2urdfIsOK

This commit is contained in:
zhenai 2026-09-06 12:05:13 +08:00
parent 70e8777eb2
commit 3165625897
90 changed files with 328125 additions and 0 deletions

14
2foot/CMakeLists.txt Normal file
View File

@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 2.8.3)
project(2foot)
find_package(catkin REQUIRED)
catkin_package()
find_package(roslaunch)
foreach(dir config launch meshes urdf)
install(DIRECTORY ${dir}/
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/${dir})
endforeach(dir)

View File

@ -0,0 +1 @@
controller_joint_names: ['', 'jlf0_link', 'jlf1_link', 'jlf2_link', 'jlf3_link', 'jrf0_link', 'jrf1_link', 'jrf2_link', 'jrf3_link', ]

682
2foot/export.log Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,20 @@
<launch>
<arg
name="model" />
<param
name="robot_description"
textfile="$(find 2foot)/urdf/2foot.urdf" />
<node
name="joint_state_publisher_gui"
pkg="joint_state_publisher_gui"
type="joint_state_publisher_gui" />
<node
name="robot_state_publisher"
pkg="robot_state_publisher"
type="robot_state_publisher" />
<node
name="rviz"
pkg="rviz"
type="rviz"
args="-d $(find 2foot)/urdf.rviz" />
</launch>

View File

@ -0,0 +1,20 @@
<launch>
<include
file="$(find gazebo_ros)/launch/empty_world.launch" />
<node
name="tf_footprint_base"
pkg="tf"
type="static_transform_publisher"
args="0 0 0 0 0 0 base_link base_footprint 40" />
<node
name="spawn_model"
pkg="gazebo_ros"
type="spawn_model"
args="-file $(find 2foot)/urdf/2foot.urdf -urdf -model 2foot"
output="screen" />
<node
name="fake_joint_calibration"
pkg="rostopic"
type="rostopic"
args="pub /calibrated std_msgs/Bool true" />
</launch>

BIN
2foot/meshes/head_link.STL Normal file

Binary file not shown.

BIN
2foot/meshes/lf0_link.STL Normal file

Binary file not shown.

BIN
2foot/meshes/lf1_link.STL Normal file

Binary file not shown.

BIN
2foot/meshes/lf2_link.STL Normal file

Binary file not shown.

BIN
2foot/meshes/lf3_link.STL Normal file

Binary file not shown.

BIN
2foot/meshes/rf0_link.STL Normal file

Binary file not shown.

BIN
2foot/meshes/rf1_link.STL Normal file

Binary file not shown.

BIN
2foot/meshes/rf2_link.STL Normal file

Binary file not shown.

BIN
2foot/meshes/rf3_link.STL Normal file

Binary file not shown.

21
2foot/package.xml Normal file
View File

@ -0,0 +1,21 @@
<package format="2">
<name>2foot</name>
<version>1.0.0</version>
<description>
<p>URDF Description package for 2foot</p>
<p>This package contains configuration data, 3D models and launch files
for 2foot robot</p>
</description>
<author>TODO</author>
<maintainer email="TODO@email.com" />
<license>BSD</license>
<buildtool_depend>catkin</buildtool_depend>
<depend>roslaunch</depend>
<depend>robot_state_publisher</depend>
<depend>rviz</depend>
<depend>joint_state_publisher_gui</depend>
<depend>gazebo</depend>
<export>
<architecture_independent />
</export>
</package>

10
2foot/urdf/2foot.csv Normal file
View File

@ -0,0 +1,10 @@
Link Name,Center of Mass X,Center of Mass Y,Center of Mass Z,Center of Mass Roll,Center of Mass Pitch,Center of Mass Yaw,Mass,Moment Ixx,Moment Ixy,Moment Ixz,Moment Iyy,Moment Iyz,Moment Izz,Visual X,Visual Y,Visual Z,Visual Roll,Visual Pitch,Visual Yaw,Mesh Filename,Color Red,Color Green,Color Blue,Color Alpha,Collision X,Collision Y,Collision Z,Collision Roll,Collision Pitch,Collision Yaw,Collision Mesh Filename,Material Name,SW Components,Coordinate System,Axis Name,Joint Name,Joint Type,Joint Origin X,Joint Origin Y,Joint Origin Z,Joint Origin Roll,Joint Origin Pitch,Joint Origin Yaw,Parent,Joint Axis X,Joint Axis Y,Joint Axis Z,Limit Effort,Limit Velocity,Limit Lower,Limit Upper,Calibration rising,Calibration falling,Dynamics Damping,Dynamics Friction,Safety Soft Upper,Safety Soft Lower,Safety K Position,Safety K Velocity
head_link,0.00637927718522201,8.36838553548436E-05,0.0502679117290854,0,0,0,0.104147639434427,0.000119888626287878,4.26649795023379E-08,-3.14056079328627E-06,9.2091610344693E-05,1.01375294153974E-07,3.18810914232645E-05,0,0,0,0,0,0,package://2foot/meshes/head_link.STL,1,1,1,1,0,0,0,0,0,0,package://2foot/meshes/head_link.STL,,主体-2;bateria 9v-1;Step Up-1;3D_PCB1_2026-08-10.step-1/Board~RkW7.step-1;Freenove ESP32-S3-WROOM-CAM-1;3D_PCB1_2026-08-10.step-1/H15~HDR-TH_20P-P2.54-V-F~HDR-F-2.54_1x20~VMZC.step-1/HDR-TH_20P-P2.54-V-F~HDR-F-2.54_1x20~Z7qR.step-1;3D_PCB1_2026-08-10.step-1/H1~HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~UsHF.step-1/HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~m73r.step-1;3D_PCB1_2026-08-10.step-1/H8~HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~Shzr.step-1/HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~m73r.step-1;3D_PCB1_2026-08-10.step-1/H2~HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~Ckmi.step-1/HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~m73r.step-1;3D_PCB1_2026-08-10.step-1/H4~HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~7m2w.step-1/HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~m73r.step-1;3D_PCB1_2026-08-10.step-1/H6~HDR-TH_20P-P2.54-V-F~HDR-F-2.54_1x20~FFBa.step-1/HDR-TH_20P-P2.54-V-F~HDR-F-2.54_1x20~Z7qR.step-1;3D_PCB1_2026-08-10.step-1/H3~HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~2T1y.step-1/HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~m73r.step-1;3D_PCB1_2026-08-10.step-1/H5~HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~T7xH.step-1/HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~m73r.step-1;舵机总体-5/Servo-1;舵机总体-4/Servo-1,head,,,,0,0,0,0,0,0,,0,0,0,,,,,,,,,,,,
lf0_link,2.5034674019167E-06,-0.00399152370097755,-0.0136055723537577,0,0,0,0.0155246301341258,1.99164881392775E-06,-4.82887905395487E-10,-2.07253296776602E-10,2.02900387840545E-06,2.49004321417992E-07,1.54078395860252E-06,0,0,0,0,0,0,package://2foot/meshes/lf0_link.STL,1,1,1,1,0,0,0,0,0,0,package://2foot/meshes/lf0_link.STL,,右腿胯骨-18;舵机总体-8/Servo-1,lf0,lf0_hige,jlf0_link,revolute,-0.0031441,0.025688,-0.006475,0,0,0,head_link,0,0,-1,0,0,0,0,,,,,,,,
lf1_link,2.91696425805399E-06,0.004390376864982,-0.0296712953157869,0,0,0,0.013323922418148,2.72143018103993E-06,4.82887905395412E-10,2.07253296776833E-10,2.92090153101514E-06,-3.25175555348237E-08,9.23918900070304E-07,0,0,0,0,0,0,package://2foot/meshes/lf1_link.STL,1,1,1,1,0,0,0,0,0,0,package://2foot/meshes/lf1_link.STL,,右大腿-3;舵机总体-10/Servo-1,lf1,lf1_hige,jlf1_link,revolute,9.7027E-05,0.011975,-0.012388,0,0,0,lf0_link,0,-1,0,0,0,0,0,,,,,,,,
lf2_link,2.43737372657149E-06,0.00363613025354126,-0.0425732788173739,0,0,0,0.0159456077850123,5.35424510746978E-06,4.82887905395677E-10,2.07253296776739E-10,5.71315402728463E-06,-2.13454759600996E-08,1.09035404123551E-06,0,0,0,0,0,0,package://2foot/meshes/lf2_link.STL,1,1,1,1,0,0,0,0,0,0,package://2foot/meshes/lf2_link.STL,,右小腿-2;舵机总体-12/Servo-1,lf2,lf2_hige,jlf2_link,revolute,9.7027E-05,-0.008475,-0.040938,0,0,0,lf1_link,0,1,0,0,0,0,0,,,,,,,,
lf3_link,-4.82253126321552E-16,-0.000451394188820231,-0.0198245674059442,0,0,0,0.0192906631601767,3.18209633375994E-06,3.34527248954873E-21,1.76056444695768E-21,6.55022061625284E-06,2.53604908486043E-07,7.24649308736933E-06,0,0,0,0,0,0,package://2foot/meshes/lf3_link.STL,1,1,1,1,0,0,0,0,0,0,package://2foot/meshes/lf3_link.STL,,玉足-4,lf3,lf3_hige,jlf3_link,revolute,9.7027E-05,-0.006475,-0.060937,0,0,0,lf2_link,0,-1,0,0,0,0,0,,,,,,,,
rf0_link,-2.50346740203813E-06,0.00399152370097733,-0.0136055723537577,0,0,0,0.0155246301341258,1.99164881392775E-06,-4.82887905395413E-10,2.07253296776268E-10,2.02900387840545E-06,-2.49004321417992E-07,1.54078395860252E-06,0,0,0,0,0,0,package://2foot/meshes/rf0_link.STL,1,1,1,1,0,0,0,0,0,0,package://2foot/meshes/rf0_link.STL,,右腿胯骨-16;舵机总体-9/Servo-1,rf0,rf0_hige,jrf0_link,revolute,-0.0033382,-0.025687,-0.006475,0,0,0,head_link,0,0,-1,0,0,0,0,,,,,,,,
rf1_link,-2.91696425855359E-06,-0.00439037686498245,-0.0296712953157865,0,0,0,0.0133239224181479,2.72143018103992E-06,4.82887905395081E-10,-2.07253296776895E-10,2.92090153101514E-06,3.25175555348265E-08,9.23918900070297E-07,0,0,0,0,0,0,package://2foot/meshes/rf1_link.STL,1,1,1,1,0,0,0,0,0,0,package://2foot/meshes/rf1_link.STL,,右大腿-2;舵机总体-11/Servo-1,rf1,rf1_hige,jrf1_link,revolute,-9.7027E-05,-0.011975,-0.012388,0,0,0,rf0_link,0,1,0,0,0,0,0,,,,,,,,
rf2_link,-2.43737372681782E-06,-0.00363613025354104,-0.0425732788173739,0,0,0,0.0159456077850122,5.35424510746977E-06,4.82887905394926E-10,-2.0725329677683E-10,5.71315402728462E-06,2.13454759600991E-08,1.0903540412355E-06,0,0,0,0,0,0,package://2foot/meshes/rf2_link.STL,1,1,1,1,0,0,0,0,0,0,package://2foot/meshes/rf2_link.STL,,右小腿-1;舵机总体-13/Servo-1,rf2,lf2_hige,jrf2_link,revolute,-9.7027E-05,0.008475,-0.040937,0,0,0,rf1_link,0,1,0,0,0,0,0,,,,,,,,
rf3_link,8.18789480661053E-16,0.000451394188820897,-0.0198245674059443,0,0,0,0.0192906631601768,3.18209633375994E-06,8.58350838304875E-21,2.39867798130625E-21,6.55022061625285E-06,-2.53604908486041E-07,7.24649308736931E-06,0,0,0,0,0,0,package://2foot/meshes/rf3_link.STL,1,1,1,1,0,0,0,0,0,0,package://2foot/meshes/rf3_link.STL,,玉足-3,rf3,rf3_hige,jrf3_link,revolute,-9.7027E-05,0.006475,-0.060938,0,0,0,rf2_link,0,1,0,0,0,0,0,,,,,,,,
1 Link Name Center of Mass X Center of Mass Y Center of Mass Z Center of Mass Roll Center of Mass Pitch Center of Mass Yaw Mass Moment Ixx Moment Ixy Moment Ixz Moment Iyy Moment Iyz Moment Izz Visual X Visual Y Visual Z Visual Roll Visual Pitch Visual Yaw Mesh Filename Color Red Color Green Color Blue Color Alpha Collision X Collision Y Collision Z Collision Roll Collision Pitch Collision Yaw Collision Mesh Filename Material Name SW Components Coordinate System Axis Name Joint Name Joint Type Joint Origin X Joint Origin Y Joint Origin Z Joint Origin Roll Joint Origin Pitch Joint Origin Yaw Parent Joint Axis X Joint Axis Y Joint Axis Z Limit Effort Limit Velocity Limit Lower Limit Upper Calibration rising Calibration falling Dynamics Damping Dynamics Friction Safety Soft Upper Safety Soft Lower Safety K Position Safety K Velocity
2 head_link 0.00637927718522201 8.36838553548436E-05 0.0502679117290854 0 0 0 0.104147639434427 0.000119888626287878 4.26649795023379E-08 -3.14056079328627E-06 9.2091610344693E-05 1.01375294153974E-07 3.18810914232645E-05 0 0 0 0 0 0 package://2foot/meshes/head_link.STL 1 1 1 1 0 0 0 0 0 0 package://2foot/meshes/head_link.STL 主体-2;bateria 9v-1;Step Up-1;3D_PCB1_2026-08-10.step-1/Board~RkW7.step-1;Freenove ESP32-S3-WROOM-CAM-1;3D_PCB1_2026-08-10.step-1/H15~HDR-TH_20P-P2.54-V-F~HDR-F-2.54_1x20~VMZC.step-1/HDR-TH_20P-P2.54-V-F~HDR-F-2.54_1x20~Z7qR.step-1;3D_PCB1_2026-08-10.step-1/H1~HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~UsHF.step-1/HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~m73r.step-1;3D_PCB1_2026-08-10.step-1/H8~HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~Shzr.step-1/HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~m73r.step-1;3D_PCB1_2026-08-10.step-1/H2~HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~Ckmi.step-1/HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~m73r.step-1;3D_PCB1_2026-08-10.step-1/H4~HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~7m2w.step-1/HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~m73r.step-1;3D_PCB1_2026-08-10.step-1/H6~HDR-TH_20P-P2.54-V-F~HDR-F-2.54_1x20~FFBa.step-1/HDR-TH_20P-P2.54-V-F~HDR-F-2.54_1x20~Z7qR.step-1;3D_PCB1_2026-08-10.step-1/H3~HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~2T1y.step-1/HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~m73r.step-1;3D_PCB1_2026-08-10.step-1/H5~HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~T7xH.step-1/HDR-TH_20P-P2.54-V-M-1~HDR-M-2.54_1x20~m73r.step-1;舵机总体-5/Servo-1;舵机总体-4/Servo-1 head 0 0 0 0 0 0 0 0 0
3 lf0_link 2.5034674019167E-06 -0.00399152370097755 -0.0136055723537577 0 0 0 0.0155246301341258 1.99164881392775E-06 -4.82887905395487E-10 -2.07253296776602E-10 2.02900387840545E-06 2.49004321417992E-07 1.54078395860252E-06 0 0 0 0 0 0 package://2foot/meshes/lf0_link.STL 1 1 1 1 0 0 0 0 0 0 package://2foot/meshes/lf0_link.STL 右腿胯骨-18;舵机总体-8/Servo-1 lf0 lf0_hige jlf0_link revolute -0.0031441 0.025688 -0.006475 0 0 0 head_link 0 0 -1 0 0 0 0
4 lf1_link 2.91696425805399E-06 0.004390376864982 -0.0296712953157869 0 0 0 0.013323922418148 2.72143018103993E-06 4.82887905395412E-10 2.07253296776833E-10 2.92090153101514E-06 -3.25175555348237E-08 9.23918900070304E-07 0 0 0 0 0 0 package://2foot/meshes/lf1_link.STL 1 1 1 1 0 0 0 0 0 0 package://2foot/meshes/lf1_link.STL 右大腿-3;舵机总体-10/Servo-1 lf1 lf1_hige jlf1_link revolute 9.7027E-05 0.011975 -0.012388 0 0 0 lf0_link 0 -1 0 0 0 0 0
5 lf2_link 2.43737372657149E-06 0.00363613025354126 -0.0425732788173739 0 0 0 0.0159456077850123 5.35424510746978E-06 4.82887905395677E-10 2.07253296776739E-10 5.71315402728463E-06 -2.13454759600996E-08 1.09035404123551E-06 0 0 0 0 0 0 package://2foot/meshes/lf2_link.STL 1 1 1 1 0 0 0 0 0 0 package://2foot/meshes/lf2_link.STL 右小腿-2;舵机总体-12/Servo-1 lf2 lf2_hige jlf2_link revolute 9.7027E-05 -0.008475 -0.040938 0 0 0 lf1_link 0 1 0 0 0 0 0
6 lf3_link -4.82253126321552E-16 -0.000451394188820231 -0.0198245674059442 0 0 0 0.0192906631601767 3.18209633375994E-06 3.34527248954873E-21 1.76056444695768E-21 6.55022061625284E-06 2.53604908486043E-07 7.24649308736933E-06 0 0 0 0 0 0 package://2foot/meshes/lf3_link.STL 1 1 1 1 0 0 0 0 0 0 package://2foot/meshes/lf3_link.STL 玉足-4 lf3 lf3_hige jlf3_link revolute 9.7027E-05 -0.006475 -0.060937 0 0 0 lf2_link 0 -1 0 0 0 0 0
7 rf0_link -2.50346740203813E-06 0.00399152370097733 -0.0136055723537577 0 0 0 0.0155246301341258 1.99164881392775E-06 -4.82887905395413E-10 2.07253296776268E-10 2.02900387840545E-06 -2.49004321417992E-07 1.54078395860252E-06 0 0 0 0 0 0 package://2foot/meshes/rf0_link.STL 1 1 1 1 0 0 0 0 0 0 package://2foot/meshes/rf0_link.STL 右腿胯骨-16;舵机总体-9/Servo-1 rf0 rf0_hige jrf0_link revolute -0.0033382 -0.025687 -0.006475 0 0 0 head_link 0 0 -1 0 0 0 0
8 rf1_link -2.91696425855359E-06 -0.00439037686498245 -0.0296712953157865 0 0 0 0.0133239224181479 2.72143018103992E-06 4.82887905395081E-10 -2.07253296776895E-10 2.92090153101514E-06 3.25175555348265E-08 9.23918900070297E-07 0 0 0 0 0 0 package://2foot/meshes/rf1_link.STL 1 1 1 1 0 0 0 0 0 0 package://2foot/meshes/rf1_link.STL 右大腿-2;舵机总体-11/Servo-1 rf1 rf1_hige jrf1_link revolute -9.7027E-05 -0.011975 -0.012388 0 0 0 rf0_link 0 1 0 0 0 0 0
9 rf2_link -2.43737372681782E-06 -0.00363613025354104 -0.0425732788173739 0 0 0 0.0159456077850122 5.35424510746977E-06 4.82887905394926E-10 -2.0725329677683E-10 5.71315402728462E-06 2.13454759600991E-08 1.0903540412355E-06 0 0 0 0 0 0 package://2foot/meshes/rf2_link.STL 1 1 1 1 0 0 0 0 0 0 package://2foot/meshes/rf2_link.STL 右小腿-1;舵机总体-13/Servo-1 rf2 lf2_hige jrf2_link revolute -9.7027E-05 0.008475 -0.040937 0 0 0 rf1_link 0 1 0 0 0 0 0
10 rf3_link 8.18789480661053E-16 0.000451394188820897 -0.0198245674059443 0 0 0 0.0192906631601768 3.18209633375994E-06 8.58350838304875E-21 2.39867798130625E-21 6.55022061625285E-06 -2.53604908486041E-07 7.24649308736931E-06 0 0 0 0 0 0 package://2foot/meshes/rf3_link.STL 1 1 1 1 0 0 0 0 0 0 package://2foot/meshes/rf3_link.STL 玉足-3 rf3 rf3_hige jrf3_link revolute -9.7027E-05 0.006475 -0.060938 0 0 0 rf2_link 0 1 0 0 0 0 0

511
2foot/urdf/2foot.urdf Normal file
View File

@ -0,0 +1,511 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This URDF was automatically created by SolidWorks to URDF Exporter! Originally created by Stephen Brawner (brawner@gmail.com)
Commit Version: 1.6.0-4-g7f85cfe Build Version: 1.6.7995.38578
For more information, please see http://wiki.ros.org/sw_urdf_exporter -->
<robot
name="2foot">
<link
name="head_link">
<inertial>
<origin
xyz="0.00637927718522201 8.36838553548436E-05 0.0502679117290854"
rpy="0 0 0" />
<mass
value="0.104147639434427" />
<inertia
ixx="0.000119888626287878"
ixy="4.26649795023379E-08"
ixz="-3.14056079328627E-06"
iyy="9.2091610344693E-05"
iyz="1.01375294153974E-07"
izz="3.18810914232645E-05" />
</inertial>
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://2foot/meshes/head_link.STL" />
</geometry>
<material
name="">
<color
rgba="1 1 1 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://2foot/meshes/head_link.STL" />
</geometry>
</collision>
</link>
<link
name="lf0_link">
<inertial>
<origin
xyz="2.5034674019167E-06 -0.00399152370097755 -0.0136055723537577"
rpy="0 0 0" />
<mass
value="0.0155246301341258" />
<inertia
ixx="1.99164881392775E-06"
ixy="-4.82887905395487E-10"
ixz="-2.07253296776602E-10"
iyy="2.02900387840545E-06"
iyz="2.49004321417992E-07"
izz="1.54078395860252E-06" />
</inertial>
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://2foot/meshes/lf0_link.STL" />
</geometry>
<material
name="">
<color
rgba="1 1 1 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://2foot/meshes/lf0_link.STL" />
</geometry>
</collision>
</link>
<joint
name="jlf0_link"
type="revolute">
<origin
xyz="-0.0031441 0.025688 -0.006475"
rpy="0 0 0" />
<parent
link="head_link" />
<child
link="lf0_link" />
<axis
xyz="0 0 -1" />
<limit
lower="0"
upper="0"
effort="0"
velocity="0" />
</joint>
<link
name="lf1_link">
<inertial>
<origin
xyz="2.91696425805399E-06 0.004390376864982 -0.0296712953157869"
rpy="0 0 0" />
<mass
value="0.013323922418148" />
<inertia
ixx="2.72143018103993E-06"
ixy="4.82887905395412E-10"
ixz="2.07253296776833E-10"
iyy="2.92090153101514E-06"
iyz="-3.25175555348237E-08"
izz="9.23918900070304E-07" />
</inertial>
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://2foot/meshes/lf1_link.STL" />
</geometry>
<material
name="">
<color
rgba="1 1 1 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://2foot/meshes/lf1_link.STL" />
</geometry>
</collision>
</link>
<joint
name="jlf1_link"
type="revolute">
<origin
xyz="9.7027E-05 0.011975 -0.012388"
rpy="0 0 0" />
<parent
link="lf0_link" />
<child
link="lf1_link" />
<axis
xyz="0 -1 0" />
<limit
lower="0"
upper="0"
effort="0"
velocity="0" />
</joint>
<link
name="lf2_link">
<inertial>
<origin
xyz="2.43737372657149E-06 0.00363613025354126 -0.0425732788173739"
rpy="0 0 0" />
<mass
value="0.0159456077850123" />
<inertia
ixx="5.35424510746978E-06"
ixy="4.82887905395677E-10"
ixz="2.07253296776739E-10"
iyy="5.71315402728463E-06"
iyz="-2.13454759600996E-08"
izz="1.09035404123551E-06" />
</inertial>
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://2foot/meshes/lf2_link.STL" />
</geometry>
<material
name="">
<color
rgba="1 1 1 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://2foot/meshes/lf2_link.STL" />
</geometry>
</collision>
</link>
<joint
name="jlf2_link"
type="revolute">
<origin
xyz="9.7027E-05 -0.008475 -0.040938"
rpy="0 0 0" />
<parent
link="lf1_link" />
<child
link="lf2_link" />
<axis
xyz="0 1 0" />
<limit
lower="0"
upper="0"
effort="0"
velocity="0" />
</joint>
<link
name="lf3_link">
<inertial>
<origin
xyz="-4.82253126321552E-16 -0.000451394188820231 -0.0198245674059442"
rpy="0 0 0" />
<mass
value="0.0192906631601767" />
<inertia
ixx="3.18209633375994E-06"
ixy="3.34527248954873E-21"
ixz="1.76056444695768E-21"
iyy="6.55022061625284E-06"
iyz="2.53604908486043E-07"
izz="7.24649308736933E-06" />
</inertial>
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://2foot/meshes/lf3_link.STL" />
</geometry>
<material
name="">
<color
rgba="1 1 1 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://2foot/meshes/lf3_link.STL" />
</geometry>
</collision>
</link>
<joint
name="jlf3_link"
type="revolute">
<origin
xyz="9.7027E-05 -0.006475 -0.060937"
rpy="0 0 0" />
<parent
link="lf2_link" />
<child
link="lf3_link" />
<axis
xyz="0 -1 0" />
<limit
lower="0"
upper="0"
effort="0"
velocity="0" />
</joint>
<link
name="rf0_link">
<inertial>
<origin
xyz="-2.50346740203813E-06 0.00399152370097733 -0.0136055723537577"
rpy="0 0 0" />
<mass
value="0.0155246301341258" />
<inertia
ixx="1.99164881392775E-06"
ixy="-4.82887905395413E-10"
ixz="2.07253296776268E-10"
iyy="2.02900387840545E-06"
iyz="-2.49004321417992E-07"
izz="1.54078395860252E-06" />
</inertial>
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://2foot/meshes/rf0_link.STL" />
</geometry>
<material
name="">
<color
rgba="1 1 1 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://2foot/meshes/rf0_link.STL" />
</geometry>
</collision>
</link>
<joint
name="jrf0_link"
type="revolute">
<origin
xyz="-0.0033382 -0.025687 -0.006475"
rpy="0 0 0" />
<parent
link="head_link" />
<child
link="rf0_link" />
<axis
xyz="0 0 -1" />
<limit
lower="0"
upper="0"
effort="0"
velocity="0" />
</joint>
<link
name="rf1_link">
<inertial>
<origin
xyz="-2.91696425855359E-06 -0.00439037686498245 -0.0296712953157865"
rpy="0 0 0" />
<mass
value="0.0133239224181479" />
<inertia
ixx="2.72143018103992E-06"
ixy="4.82887905395081E-10"
ixz="-2.07253296776895E-10"
iyy="2.92090153101514E-06"
iyz="3.25175555348265E-08"
izz="9.23918900070297E-07" />
</inertial>
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://2foot/meshes/rf1_link.STL" />
</geometry>
<material
name="">
<color
rgba="1 1 1 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://2foot/meshes/rf1_link.STL" />
</geometry>
</collision>
</link>
<joint
name="jrf1_link"
type="revolute">
<origin
xyz="-9.7027E-05 -0.011975 -0.012388"
rpy="0 0 0" />
<parent
link="rf0_link" />
<child
link="rf1_link" />
<axis
xyz="0 1 0" />
<limit
lower="0"
upper="0"
effort="0"
velocity="0" />
</joint>
<link
name="rf2_link">
<inertial>
<origin
xyz="-2.43737372681782E-06 -0.00363613025354104 -0.0425732788173739"
rpy="0 0 0" />
<mass
value="0.0159456077850122" />
<inertia
ixx="5.35424510746977E-06"
ixy="4.82887905394926E-10"
ixz="-2.0725329677683E-10"
iyy="5.71315402728462E-06"
iyz="2.13454759600991E-08"
izz="1.0903540412355E-06" />
</inertial>
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://2foot/meshes/rf2_link.STL" />
</geometry>
<material
name="">
<color
rgba="1 1 1 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://2foot/meshes/rf2_link.STL" />
</geometry>
</collision>
</link>
<joint
name="jrf2_link"
type="revolute">
<origin
xyz="-9.7027E-05 0.008475 -0.040937"
rpy="0 0 0" />
<parent
link="rf1_link" />
<child
link="rf2_link" />
<axis
xyz="0 1 0" />
<limit
lower="0"
upper="0"
effort="0"
velocity="0" />
</joint>
<link
name="rf3_link">
<inertial>
<origin
xyz="8.18789480661053E-16 0.000451394188820897 -0.0198245674059443"
rpy="0 0 0" />
<mass
value="0.0192906631601768" />
<inertia
ixx="3.18209633375994E-06"
ixy="8.58350838304875E-21"
ixz="2.39867798130625E-21"
iyy="6.55022061625285E-06"
iyz="-2.53604908486041E-07"
izz="7.24649308736931E-06" />
</inertial>
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://2foot/meshes/rf3_link.STL" />
</geometry>
<material
name="">
<color
rgba="1 1 1 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://2foot/meshes/rf3_link.STL" />
</geometry>
</collision>
</link>
<joint
name="jrf3_link"
type="revolute">
<origin
xyz="-9.7027E-05 0.006475 -0.060938"
rpy="0 0 0" />
<parent
link="rf2_link" />
<child
link="rf3_link" />
<axis
xyz="0 1 0" />
<limit
lower="0"
upper="0"
effort="0"
velocity="0" />
</joint>
</robot>

View File

@ -0,0 +1,52 @@
#usda 1.0
(
customLayerData = {
string creator = "URDF USD Converter v0.1.3"
}
defaultPrim = "tn__2foot_"
doc = """Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\tmpf1f0lj99\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\usdex_2foot\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\temp_2foot\\2foot.usd
Generated from Composed Stage of root layer C:\\Users\\ZhenaiWin\\Documents\\Bot3dData\\2foot\\urdf\\2foot\\payloads\\base.usd
"""
kilogramsPerUnit = 1
metersPerUnit = 1
upAxis = "Z"
)
def Xform "tn__2foot_" (
prepend references = @./payloads/base.usda@
variants = {
string Physics = "physx"
}
append variantSets = "Physics"
)
{
variantSet "Physics" = {
"mujoco" (
prepend payload = @./payloads/Physics/mujoco.usda@
) {
}
"none" {
}
"physics" (
prepend payload = @./payloads/Physics/physics.usda@
) {
}
"physx" (
prepend payload = @./payloads/Physics/physx.usda@
) {
}
}
}

View File

@ -0,0 +1,257 @@
#usda 1.0
(
customLayerData = {
string creator = "URDF USD Converter v0.1.3"
}
defaultPrim = "tn__2foot_"
doc = """Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\tmpf1f0lj99\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\usdex_2foot\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\temp_2foot\\2foot.usd
Generated from Composed Stage of root layer C:\\Users\\ZhenaiWin\\Documents\\Bot3dData\\2foot\\urdf\\2foot\\payloads\\base.usd
"""
kilogramsPerUnit = 1
metersPerUnit = 1
subLayers = [
@./physics.usda@
]
upAxis = "Z"
)
over "tn__2foot_"
{
over "Physics"
{
def MjcActuator "jlf0_link_actuator"
{
uniform double mjc:forceRange:max = inf
uniform double mjc:forceRange:min = -inf
custom rel mjc:target
prepend rel mjc:target = </tn__2foot_/Physics/jlf0_link>
}
def MjcActuator "jlf1_link_actuator"
{
uniform double mjc:forceRange:max = inf
uniform double mjc:forceRange:min = -inf
custom rel mjc:target
prepend rel mjc:target = </tn__2foot_/Physics/jlf1_link>
}
def MjcActuator "jlf2_link_actuator"
{
uniform double mjc:forceRange:max = inf
uniform double mjc:forceRange:min = -inf
custom rel mjc:target
prepend rel mjc:target = </tn__2foot_/Physics/jlf2_link>
}
def MjcActuator "jlf3_link_actuator"
{
uniform double mjc:forceRange:max = inf
uniform double mjc:forceRange:min = -inf
custom rel mjc:target
prepend rel mjc:target = </tn__2foot_/Physics/jlf3_link>
}
def MjcActuator "jrf0_link_actuator"
{
uniform double mjc:forceRange:max = inf
uniform double mjc:forceRange:min = -inf
custom rel mjc:target
prepend rel mjc:target = </tn__2foot_/Physics/jrf0_link>
}
def MjcActuator "jrf1_link_actuator"
{
uniform double mjc:forceRange:max = inf
uniform double mjc:forceRange:min = -inf
custom rel mjc:target
prepend rel mjc:target = </tn__2foot_/Physics/jrf1_link>
}
def MjcActuator "jrf2_link_actuator"
{
uniform double mjc:forceRange:max = inf
uniform double mjc:forceRange:min = -inf
custom rel mjc:target
prepend rel mjc:target = </tn__2foot_/Physics/jrf2_link>
}
def MjcActuator "jrf3_link_actuator"
{
uniform double mjc:forceRange:max = inf
uniform double mjc:forceRange:min = -inf
custom rel mjc:target
prepend rel mjc:target = </tn__2foot_/Physics/jrf3_link>
}
over "root_joint"
{
}
over "jlf0_link" (
delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
}
over "jlf1_link" (
delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
}
over "jlf2_link" (
delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
}
over "jlf3_link" (
delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
}
over "jrf0_link" (
delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
}
over "jrf1_link" (
delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
}
over "jrf2_link" (
delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
}
over "jrf3_link" (
delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
}
}
over "Geometry"
{
over "head_link"
{
over "lf0_link"
{
over "lf1_link"
{
over "lf2_link"
{
over "lf3_link"
{
over "lf3_link"
{
}
over "lf3_link_1"
{
}
}
over "lf2_link"
{
}
over "lf2_link_1"
{
}
}
over "lf1_link"
{
}
over "lf1_link_1"
{
}
}
over "lf0_link"
{
}
over "lf0_link_1"
{
}
}
over "rf0_link"
{
over "rf1_link"
{
over "rf2_link"
{
over "rf3_link"
{
over "rf3_link"
{
}
over "rf3_link_1"
{
}
}
over "rf2_link"
{
}
over "rf2_link_1"
{
}
}
over "rf1_link"
{
}
over "rf1_link_1"
{
}
}
over "rf0_link"
{
}
over "rf0_link_1"
{
}
}
over "head_link"
{
}
over "head_link_1"
{
}
}
}
over "Materials"
{
}
over "VisualMaterials"
{
}
}

View File

@ -0,0 +1,310 @@
#usda 1.0
(
customLayerData = {
string creator = "URDF USD Converter v0.1.3"
}
defaultPrim = "tn__2foot_"
doc = """Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\tmpf1f0lj99\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\usdex_2foot\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\temp_2foot\\2foot.usd
Generated from Composed Stage of root layer C:\\Users\\ZhenaiWin\\Documents\\Bot3dData\\2foot\\urdf\\2foot\\payloads\\base.usd
"""
kilogramsPerUnit = 1
metersPerUnit = 1
upAxis = "Z"
)
over "tn__2foot_"
{
over "Geometry"
{
over "head_link" (
prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsArticulationRootAPI", "NewtonArticulationRootAPI", "PhysicsMassAPI"]
)
{
bool newton:selfCollisionEnabled = 0
point3f physics:centerOfMass = (0.006379277, 0.00008368386, 0.050267912)
float3 physics:diagonalInertia = (0.00003176899, 0.00009209173, 0.00012000061)
float physics:mass = 0.10414764
quatf physics:principalAxes = (0.7195886, -0.0010949927, 0.6943998, 0.00012781573)
over "lf0_link" (
prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"]
)
{
point3f physics:centerOfMass = (0.0000025034674, -0.0039915238, -0.013605572)
float3 physics:diagonalInertia = (0.0000014361923, 0.000001991647, 0.0000021335975)
float physics:mass = 0.01552463
quatf physics:principalAxes = (0.5896363, 0.3902982, 0.39247534, 0.58818316)
over "lf1_link" (
prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"]
)
{
point3f physics:centerOfMass = (0.0000029169641, 0.004390377, -0.029671295)
float3 physics:diagonalInertia = (9.233895e-7, 0.0000027214292, 0.000002921432)
float physics:mass = 0.013323923
quatf physics:principalAxes = (0.49527994, 0.5046167, 0.5034881, 0.49654758)
over "lf2_link" (
prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"]
)
{
point3f physics:centerOfMass = (0.0000024373737, 0.0036361304, -0.04257328)
float3 physics:diagonalInertia = (0.0000010902555, 0.0000053542444, 0.0000057132534)
float physics:mass = 0.015945608
quatf physics:principalAxes = (0.4984956, 0.5014754, 0.50083035, 0.49919286)
over "lf3_link" (
prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"]
)
{
point3f physics:centerOfMass = (-4.822531e-16, -0.00045139418, -0.019824568)
float3 physics:diagonalInertia = (0.0000031820964, 0.0000064676433, 0.0000073290707)
float physics:mass = 0.019290663
quatf physics:principalAxes = (0.9876391, 0.1567448, -2.5980806e-16, 4.4737337e-16)
}
}
}
}
over "rf0_link" (
prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"]
)
{
point3f physics:centerOfMass = (-0.0000025034674, 0.0039915238, -0.013605572)
float3 physics:diagonalInertia = (0.0000014361923, 0.000001991647, 0.0000021335975)
float physics:mass = 0.01552463
quatf physics:principalAxes = (0.39247534, 0.58818316, 0.5896363, 0.3902982)
over "rf1_link" (
prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"]
)
{
point3f physics:centerOfMass = (-0.0000029169641, -0.004390377, -0.029671295)
float3 physics:diagonalInertia = (9.233895e-7, 0.0000027214292, 0.000002921432)
float physics:mass = 0.013323923
quatf physics:principalAxes = (0.5034881, 0.49654758, 0.49527994, 0.5046167)
over "rf2_link" (
prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"]
)
{
point3f physics:centerOfMass = (-0.0000024373737, -0.0036361304, -0.04257328)
float3 physics:diagonalInertia = (0.0000010902555, 0.0000053542444, 0.0000057132534)
float physics:mass = 0.015945608
quatf physics:principalAxes = (0.50083035, 0.49919286, 0.4984956, 0.5014754)
over "rf3_link" (
prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"]
)
{
point3f physics:centerOfMass = (8.187895e-16, 0.00045139418, -0.019824568)
float3 physics:diagonalInertia = (0.0000031820964, 0.0000064676433, 0.0000073290707)
float physics:mass = 0.019290663
quatf physics:principalAxes = (0.9876391, -0.1567448, -1.6753745e-16, 1.3454567e-15)
}
}
}
}
}
}
over "Physics"
{
def PhysicsRevoluteJoint "jlf0_link" (
prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
float drive:angular:physics:damping = 1
float drive:angular:physics:stiffness = 1
uniform token drive:angular:physics:type = "force"
uniform token physics:axis = "Z"
custom rel physics:body0
prepend rel physics:body0 = </tn__2foot_/Geometry/head_link>
custom rel physics:body1
prepend rel physics:body1 = </tn__2foot_/Geometry/head_link/lf0_link>
point3f physics:localPos0 = (-0.0031441, 0.025688, -0.006475)
point3f physics:localPos1 = (0, 0, 0)
quatf physics:localRot0 = (0, -1, 0, 0)
quatf physics:localRot1 = (0, -1, 0, 0)
float physics:lowerLimit = 0
float physics:upperLimit = 0
custom float urdf:limit:effort = 0
custom float urdf:limit:velocity = 0
}
def PhysicsRevoluteJoint "jlf1_link" (
prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
float drive:angular:physics:damping = 0
float drive:angular:physics:stiffness = 0
uniform token drive:angular:physics:type = "force"
uniform token physics:axis = "Y"
custom rel physics:body0
prepend rel physics:body0 = </tn__2foot_/Geometry/head_link/lf0_link>
custom rel physics:body1
prepend rel physics:body1 = </tn__2foot_/Geometry/head_link/lf0_link/lf1_link>
point3f physics:localPos0 = (0.000097027, 0.011975, -0.012388)
point3f physics:localPos1 = (0, 0, 0)
quatf physics:localRot0 = (0, -1, 0, 0)
quatf physics:localRot1 = (0, -1, 0, 0)
float physics:lowerLimit = 0
float physics:upperLimit = 0
custom float urdf:limit:effort = 0
custom float urdf:limit:velocity = 0
}
def PhysicsRevoluteJoint "jlf2_link" (
prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
float drive:angular:physics:damping = 0
float drive:angular:physics:stiffness = 0
uniform token drive:angular:physics:type = "force"
uniform token physics:axis = "Y"
custom rel physics:body0
prepend rel physics:body0 = </tn__2foot_/Geometry/head_link/lf0_link/lf1_link>
custom rel physics:body1
prepend rel physics:body1 = </tn__2foot_/Geometry/head_link/lf0_link/lf1_link/lf2_link>
point3f physics:localPos0 = (0.000097027, -0.008475, -0.040938)
point3f physics:localPos1 = (0, 0, 0)
quatf physics:localRot0 = (1, 0, 0, 0)
quatf physics:localRot1 = (1, 0, 0, 0)
float physics:lowerLimit = 0
float physics:upperLimit = 0
custom float urdf:limit:effort = 0
custom float urdf:limit:velocity = 0
}
def PhysicsRevoluteJoint "jlf3_link" (
prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
float drive:angular:physics:damping = 0
float drive:angular:physics:stiffness = 0
uniform token drive:angular:physics:type = "force"
uniform token physics:axis = "Y"
custom rel physics:body0
prepend rel physics:body0 = </tn__2foot_/Geometry/head_link/lf0_link/lf1_link/lf2_link>
custom rel physics:body1
prepend rel physics:body1 = </tn__2foot_/Geometry/head_link/lf0_link/lf1_link/lf2_link/lf3_link>
point3f physics:localPos0 = (0.000097027, -0.006475, -0.060937)
point3f physics:localPos1 = (0, 0, 0)
quatf physics:localRot0 = (0, -1, 0, 0)
quatf physics:localRot1 = (0, -1, 0, 0)
float physics:lowerLimit = 0
float physics:upperLimit = 0
custom float urdf:limit:effort = 0
custom float urdf:limit:velocity = 0
}
def PhysicsRevoluteJoint "jrf0_link" (
prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
float drive:angular:physics:damping = 0
float drive:angular:physics:stiffness = 0
uniform token drive:angular:physics:type = "force"
uniform token physics:axis = "Z"
custom rel physics:body0
prepend rel physics:body0 = </tn__2foot_/Geometry/head_link>
custom rel physics:body1
prepend rel physics:body1 = </tn__2foot_/Geometry/head_link/rf0_link>
point3f physics:localPos0 = (-0.0033382, -0.025687, -0.006475)
point3f physics:localPos1 = (0, 0, 0)
quatf physics:localRot0 = (0, -1, 0, 0)
quatf physics:localRot1 = (0, -1, 0, 0)
float physics:lowerLimit = 0
float physics:upperLimit = 0
custom float urdf:limit:effort = 0
custom float urdf:limit:velocity = 0
}
def PhysicsRevoluteJoint "jrf1_link" (
prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
float drive:angular:physics:damping = 0
float drive:angular:physics:stiffness = 0
uniform token drive:angular:physics:type = "force"
uniform token physics:axis = "Y"
custom rel physics:body0
prepend rel physics:body0 = </tn__2foot_/Geometry/head_link/rf0_link>
custom rel physics:body1
prepend rel physics:body1 = </tn__2foot_/Geometry/head_link/rf0_link/rf1_link>
point3f physics:localPos0 = (-0.000097027, -0.011975, -0.012388)
point3f physics:localPos1 = (0, 0, 0)
quatf physics:localRot0 = (1, 0, 0, 0)
quatf physics:localRot1 = (1, 0, 0, 0)
float physics:lowerLimit = 0
float physics:upperLimit = 0
custom float urdf:limit:effort = 0
custom float urdf:limit:velocity = 0
}
def PhysicsRevoluteJoint "jrf2_link" (
prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
float drive:angular:physics:damping = 0
float drive:angular:physics:stiffness = 0
uniform token drive:angular:physics:type = "force"
uniform token physics:axis = "Y"
custom rel physics:body0
prepend rel physics:body0 = </tn__2foot_/Geometry/head_link/rf0_link/rf1_link>
custom rel physics:body1
prepend rel physics:body1 = </tn__2foot_/Geometry/head_link/rf0_link/rf1_link/rf2_link>
point3f physics:localPos0 = (-0.000097027, 0.008475, -0.040937)
point3f physics:localPos1 = (0, 0, 0)
quatf physics:localRot0 = (1, 0, 0, 0)
quatf physics:localRot1 = (1, 0, 0, 0)
float physics:lowerLimit = 0
float physics:upperLimit = 0
custom float urdf:limit:effort = 0
custom float urdf:limit:velocity = 0
}
def PhysicsRevoluteJoint "jrf3_link" (
prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
float drive:angular:physics:damping = 0
float drive:angular:physics:stiffness = 0
uniform token drive:angular:physics:type = "force"
uniform token physics:axis = "Y"
custom rel physics:body0
prepend rel physics:body0 = </tn__2foot_/Geometry/head_link/rf0_link/rf1_link/rf2_link>
custom rel physics:body1
prepend rel physics:body1 = </tn__2foot_/Geometry/head_link/rf0_link/rf1_link/rf2_link/rf3_link>
point3f physics:localPos0 = (-0.000097027, 0.006475, -0.060938)
point3f physics:localPos1 = (0, 0, 0)
quatf physics:localRot0 = (1, 0, 0, 0)
quatf physics:localRot1 = (1, 0, 0, 0)
float physics:lowerLimit = 0
float physics:upperLimit = 0
custom float urdf:limit:effort = 0
custom float urdf:limit:velocity = 0
}
def PhysicsFixedJoint "root_joint"
{
custom rel physics:body0
prepend rel physics:body0 = </tn__2foot_>
custom rel physics:body1
prepend rel physics:body1 = </tn__2foot_/Geometry/head_link>
point3f physics:localPos0 = (0, 0, 0)
point3f physics:localPos1 = (0, 0, 0)
quatf physics:localRot0 = (1, 0, 0, 0)
quatf physics:localRot1 = (1, 0, 0, 0)
}
}
}

View File

@ -0,0 +1,79 @@
#usda 1.0
(
customLayerData = {
string creator = "URDF USD Converter v0.1.3"
}
defaultPrim = "tn__2foot_"
doc = """Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\tmpf1f0lj99\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\usdex_2foot\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\temp_2foot\\2foot.usd
Generated from Composed Stage of root layer C:\\Users\\ZhenaiWin\\Documents\\Bot3dData\\2foot\\urdf\\2foot\\payloads\\base.usd
"""
kilogramsPerUnit = 1
metersPerUnit = 1
subLayers = [
@./physics.usda@
]
upAxis = "Z"
)
over "tn__2foot_"
{
over "Physics"
{
over "jlf0_link" (
prepend apiSchemas = ["PhysxJointAPI"]
)
{
}
over "jlf1_link" (
prepend apiSchemas = ["PhysxJointAPI"]
)
{
}
over "jlf2_link" (
prepend apiSchemas = ["PhysxJointAPI"]
)
{
}
over "jlf3_link" (
prepend apiSchemas = ["PhysxJointAPI"]
)
{
}
over "jrf0_link" (
prepend apiSchemas = ["PhysxJointAPI"]
)
{
}
over "jrf1_link" (
prepend apiSchemas = ["PhysxJointAPI"]
)
{
}
over "jrf2_link" (
prepend apiSchemas = ["PhysxJointAPI"]
)
{
}
over "jrf3_link" (
prepend apiSchemas = ["PhysxJointAPI"]
)
{
}
}
}

View File

@ -0,0 +1,326 @@
#usda 1.0
(
customLayerData = {
string creator = "URDF USD Converter v0.1.3"
}
defaultPrim = "tn__2foot_"
doc = """Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\tmpf1f0lj99\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\usdex_2foot\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\temp_2foot\\2foot.usd
Generated from Composed Stage of root layer C:\\Users\\ZhenaiWin\\Documents\\Bot3dData\\2foot\\urdf\\2foot\\payloads\\base.usd
"""
kilogramsPerUnit = 1
metersPerUnit = 1
subLayers = [
@./robot.usda@
]
upAxis = "Z"
)
def Xform "tn__2foot_" (
prepend apiSchemas = ["GeomModelAPI"]
assetInfo = {
string name = "2foot"
}
displayName = "2foot"
kind = "component"
)
{
float3[] extentsHint = [(-0.03612928, -0.058187, -0.147238), (0.03091089, 0.058188, 0.122), (3.4028235e38, 3.4028235e38, 3.4028235e38), (-3.4028235e38, -3.4028235e38, -3.4028235e38), (3.4028235e38, 3.4028235e38, 3.4028235e38), (-3.4028235e38, -3.4028235e38, -3.4028235e38), (-0.03612928, -0.058187, -0.147238), (0.03091089, 0.058188, 0.122)]
def Scope "Materials"
{
}
def Scope "Geometry"
{
def Xform "head_link"
{
def Xform "head_link" (
instanceable = true
prepend references = @./instances.usda@</Instances/head_link>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
def Xform "lf0_link"
{
quatf xformOp:orient = (1, 0, 0, 0)
float3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (-0.0031441, 0.025688, -0.006475)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
def Xform "lf0_link" (
instanceable = true
prepend references = @./instances.usda@</Instances/lf0_link>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
def Xform "lf1_link"
{
quatf xformOp:orient = (1, 0, 0, 0)
float3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0.000097027, 0.011975, -0.012388)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
def Xform "lf1_link" (
instanceable = true
prepend references = @./instances.usda@</Instances/lf1_link>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
def Xform "lf2_link"
{
quatf xformOp:orient = (1, 0, 0, 0)
float3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0.000097027, -0.008475, -0.040938)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
def Xform "lf2_link" (
instanceable = true
prepend references = @./instances.usda@</Instances/lf2_link>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
def Xform "lf3_link"
{
quatf xformOp:orient = (1, 0, 0, 0)
float3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0.000097027, -0.006475, -0.060937)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
def Xform "lf3_link" (
instanceable = true
prepend references = @./instances.usda@</Instances/lf3_link>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
def Xform "lf3_link_1" (
displayName = "lf3_link"
instanceable = true
prepend references = @./instances.usda@</Instances/lf3_link_1>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
}
def Xform "lf2_link_1" (
displayName = "lf2_link"
instanceable = true
prepend references = @./instances.usda@</Instances/lf2_link_1>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
}
def Xform "lf1_link_1" (
displayName = "lf1_link"
instanceable = true
prepend references = @./instances.usda@</Instances/lf1_link_1>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
}
def Xform "lf0_link_1" (
displayName = "lf0_link"
instanceable = true
prepend references = @./instances.usda@</Instances/lf0_link_1>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
}
def Xform "rf0_link"
{
quatf xformOp:orient = (1, 0, 0, 0)
float3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (-0.0033382, -0.025687, -0.006475)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
def Xform "rf0_link" (
instanceable = true
prepend references = @./instances.usda@</Instances/rf0_link>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
def Xform "rf1_link"
{
quatf xformOp:orient = (1, 0, 0, 0)
float3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (-0.000097027, -0.011975, -0.012388)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
def Xform "rf1_link" (
instanceable = true
prepend references = @./instances.usda@</Instances/rf1_link>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
def Xform "rf2_link"
{
quatf xformOp:orient = (1, 0, 0, 0)
float3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (-0.000097027, 0.008475, -0.040937)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
def Xform "rf2_link" (
instanceable = true
prepend references = @./instances.usda@</Instances/rf2_link>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
def Xform "rf3_link"
{
quatf xformOp:orient = (1, 0, 0, 0)
float3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (-0.000097027, 0.006475, -0.060938)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
def Xform "rf3_link" (
instanceable = true
prepend references = @./instances.usda@</Instances/rf3_link>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
def Xform "rf3_link_1" (
displayName = "rf3_link"
instanceable = true
prepend references = @./instances.usda@</Instances/rf3_link_1>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
}
def Xform "rf2_link_1" (
displayName = "rf2_link"
instanceable = true
prepend references = @./instances.usda@</Instances/rf2_link_1>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
}
def Xform "rf1_link_1" (
displayName = "rf1_link"
instanceable = true
prepend references = @./instances.usda@</Instances/rf1_link_1>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
}
def Xform "rf0_link_1" (
displayName = "rf0_link"
instanceable = true
prepend references = @./instances.usda@</Instances/rf0_link_1>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
}
def Xform "head_link_1" (
displayName = "head_link"
instanceable = true
prepend references = @./instances.usda@</Instances/head_link_1>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
}
}
def Scope "Physics"
{
}
def Scope "VisualMaterials"
{
}
}

Binary file not shown.

View File

@ -0,0 +1,348 @@
#usda 1.0
(
customLayerData = {
string creator = "URDF USD Converter v0.1.3"
}
doc = """Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\tmpf1f0lj99\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\usdex_2foot\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\temp_2foot\\2foot.usd
Generated from Composed Stage of root layer C:\\Users\\ZhenaiWin\\Documents\\Bot3dData\\2foot\\urdf\\2foot\\payloads\\base.usd
"""
kilogramsPerUnit = 1
metersPerUnit = 1
upAxis = "Z"
)
def Scope "Instances"
{
def Xform "head_link" (
prepend references = @./geometries.usd@</Geometries/head_link>
)
{
over "head_link" (
apiSchemas = ["MaterialBindingAPI"]
)
{
custom rel material:binding
prepend rel material:binding = </Instances/head_link/VisualMaterials/material_1>
}
def Scope "VisualMaterials"
{
def Material "material_1" (
instanceable = true
prepend references = @./materials.usda@</Materials/material_1>
)
{
}
}
}
def Xform "head_link_1" (
prepend references = @./geometries.usd@</Geometries/head_link>
)
{
over "head_link" (
apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"]
)
{
token physics:approximation = "convexHull"
token purpose = "guide"
}
}
def Xform "lf0_link" (
prepend references = @./geometries.usd@</Geometries/lf0_link>
)
{
over "lf0_link" (
apiSchemas = ["MaterialBindingAPI"]
)
{
custom rel material:binding
prepend rel material:binding = </Instances/lf0_link/VisualMaterials/material_2>
}
def Scope "VisualMaterials"
{
def Material "material_2" (
instanceable = true
prepend references = @./materials.usda@</Materials/material_1>
)
{
}
}
}
def Xform "lf0_link_1" (
prepend references = @./geometries.usd@</Geometries/lf0_link>
)
{
over "lf0_link" (
apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"]
)
{
token physics:approximation = "convexHull"
token purpose = "guide"
}
}
def Xform "lf1_link" (
prepend references = @./geometries.usd@</Geometries/lf1_link>
)
{
over "lf1_link" (
apiSchemas = ["MaterialBindingAPI"]
)
{
custom rel material:binding
prepend rel material:binding = </Instances/lf1_link/VisualMaterials/material_3>
}
def Scope "VisualMaterials"
{
def Material "material_3" (
instanceable = true
prepend references = @./materials.usda@</Materials/material_1>
)
{
}
}
}
def Xform "lf1_link_1" (
prepend references = @./geometries.usd@</Geometries/lf1_link>
)
{
over "lf1_link" (
apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"]
)
{
token physics:approximation = "convexHull"
token purpose = "guide"
}
}
def Xform "lf2_link" (
prepend references = @./geometries.usd@</Geometries/lf2_link>
)
{
over "lf2_link" (
apiSchemas = ["MaterialBindingAPI"]
)
{
custom rel material:binding
prepend rel material:binding = </Instances/lf2_link/VisualMaterials/material_4>
}
def Scope "VisualMaterials"
{
def Material "material_4" (
instanceable = true
prepend references = @./materials.usda@</Materials/material_1>
)
{
}
}
}
def Xform "lf2_link_1" (
prepend references = @./geometries.usd@</Geometries/lf2_link>
)
{
over "lf2_link" (
apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"]
)
{
token physics:approximation = "convexHull"
token purpose = "guide"
}
}
def Xform "lf3_link" (
prepend references = @./geometries.usd@</Geometries/lf3_link>
)
{
over "lf3_link" (
apiSchemas = ["MaterialBindingAPI"]
)
{
custom rel material:binding
prepend rel material:binding = </Instances/lf3_link/VisualMaterials/material_5>
}
def Scope "VisualMaterials"
{
def Material "material_5" (
instanceable = true
prepend references = @./materials.usda@</Materials/material_1>
)
{
}
}
}
def Xform "lf3_link_1" (
prepend references = @./geometries.usd@</Geometries/lf3_link>
)
{
over "lf3_link" (
apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"]
)
{
token physics:approximation = "convexHull"
token purpose = "guide"
}
}
def Xform "rf0_link" (
prepend references = @./geometries.usd@</Geometries/rf0_link>
)
{
over "rf0_link" (
apiSchemas = ["MaterialBindingAPI"]
)
{
custom rel material:binding
prepend rel material:binding = </Instances/rf0_link/VisualMaterials/material_6>
}
def Scope "VisualMaterials"
{
def Material "material_6" (
instanceable = true
prepend references = @./materials.usda@</Materials/material_1>
)
{
}
}
}
def Xform "rf0_link_1" (
prepend references = @./geometries.usd@</Geometries/rf0_link>
)
{
over "rf0_link" (
apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"]
)
{
token physics:approximation = "convexHull"
token purpose = "guide"
}
}
def Xform "rf1_link" (
prepend references = @./geometries.usd@</Geometries/rf1_link>
)
{
over "rf1_link" (
apiSchemas = ["MaterialBindingAPI"]
)
{
custom rel material:binding
prepend rel material:binding = </Instances/rf1_link/VisualMaterials/material_7>
}
def Scope "VisualMaterials"
{
def Material "material_7" (
instanceable = true
prepend references = @./materials.usda@</Materials/material_1>
)
{
}
}
}
def Xform "rf1_link_1" (
prepend references = @./geometries.usd@</Geometries/rf1_link>
)
{
over "rf1_link" (
apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"]
)
{
token physics:approximation = "convexHull"
token purpose = "guide"
}
}
def Xform "rf2_link" (
prepend references = @./geometries.usd@</Geometries/rf2_link>
)
{
over "rf2_link" (
apiSchemas = ["MaterialBindingAPI"]
)
{
custom rel material:binding
prepend rel material:binding = </Instances/rf2_link/VisualMaterials/material_8>
}
def Scope "VisualMaterials"
{
def Material "material_8" (
instanceable = true
prepend references = @./materials.usda@</Materials/material_1>
)
{
}
}
}
def Xform "rf2_link_1" (
prepend references = @./geometries.usd@</Geometries/rf2_link>
)
{
over "rf2_link" (
apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"]
)
{
token physics:approximation = "convexHull"
token purpose = "guide"
}
}
def Xform "rf3_link" (
prepend references = @./geometries.usd@</Geometries/rf3_link>
)
{
over "rf3_link" (
apiSchemas = ["MaterialBindingAPI"]
)
{
custom rel material:binding
prepend rel material:binding = </Instances/rf3_link/VisualMaterials/material_9>
}
def Scope "VisualMaterials"
{
def Material "material_9" (
instanceable = true
prepend references = @./materials.usda@</Materials/material_1>
)
{
}
}
}
def Xform "rf3_link_1" (
prepend references = @./geometries.usd@</Geometries/rf3_link>
)
{
over "rf3_link" (
apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"]
)
{
token physics:approximation = "convexHull"
token purpose = "guide"
}
}
}

View File

@ -0,0 +1,57 @@
#usda 1.0
(
customLayerData = {
string creator = "URDF USD Converter v0.1.3"
}
doc = """Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\tmpf1f0lj99\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\usdex_2foot\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\temp_2foot\\2foot.usd
Generated from Composed Stage of root layer C:\\Users\\ZhenaiWin\\Documents\\Bot3dData\\2foot\\urdf\\2foot\\payloads\\base.usd
"""
kilogramsPerUnit = 1
metersPerUnit = 1
upAxis = "Z"
)
def Scope "Materials"
{
def Material "material_1"
{
color3f inputs:diffuseColor = (1, 1, 1)
float inputs:metallic = 0
float inputs:opacity = 1
float inputs:roughness = 0.5
token inputs:wrapMode = "repeat"
token outputs:displacement (
displayGroup = "Outputs"
)
prepend token outputs:displacement.connect = </Materials/material_1/PreviewSurface.outputs:displacement>
token outputs:surface (
displayGroup = "Outputs"
)
prepend token outputs:surface.connect = </Materials/material_1/PreviewSurface.outputs:surface>
token outputs:volume (
displayGroup = "Outputs"
)
def Shader "PreviewSurface" (
apiSchemas = ["NodeDefAPI"]
)
{
token info:id = "UsdPreviewSurface"
prepend color3f inputs:diffuseColor.connect = </Materials/material_1.inputs:diffuseColor>
prepend float inputs:metallic.connect = </Materials/material_1.inputs:metallic>
prepend float inputs:opacity.connect = </Materials/material_1.inputs:opacity>
prepend float inputs:roughness.connect = </Materials/material_1.inputs:roughness>
token outputs:displacement
token outputs:surface
}
}
}

View File

@ -0,0 +1,155 @@
#usda 1.0
(
customLayerData = {
string creator = "URDF USD Converter v0.1.3"
}
defaultPrim = "tn__2foot_"
doc = """Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\tmpf1f0lj99\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\usdex_2foot\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\temp_2foot\\2foot.usd
"""
kilogramsPerUnit = 1
metersPerUnit = 1
upAxis = "Z"
)
over "tn__2foot_" (
prepend apiSchemas = ["IsaacRobotAPI"]
)
{
prepend rel isaac:physics:robotJoints = [
</tn__2foot_/Physics/root_joint>,
</tn__2foot_/Physics/jlf0_link>,
</tn__2foot_/Physics/jrf0_link>,
</tn__2foot_/Physics/jlf1_link>,
</tn__2foot_/Physics/jlf2_link>,
</tn__2foot_/Physics/jlf3_link>,
</tn__2foot_/Physics/jrf1_link>,
</tn__2foot_/Physics/jrf2_link>,
</tn__2foot_/Physics/jrf3_link>,
]
prepend rel isaac:physics:robotLinks = [
</tn__2foot_/Geometry/head_link>,
</tn__2foot_/Geometry/head_link/lf0_link>,
</tn__2foot_/Geometry/head_link/lf0_link/lf1_link>,
</tn__2foot_/Geometry/head_link/lf0_link/lf1_link/lf2_link>,
</tn__2foot_/Geometry/head_link/lf0_link/lf1_link/lf2_link/lf3_link>,
</tn__2foot_/Geometry/head_link/rf0_link>,
</tn__2foot_/Geometry/head_link/rf0_link/rf1_link>,
</tn__2foot_/Geometry/head_link/rf0_link/rf1_link/rf2_link>,
</tn__2foot_/Geometry/head_link/rf0_link/rf1_link/rf2_link/rf3_link>,
]
token isaac:robotType = "Default"
over "Geometry"
{
over "head_link" (
prepend apiSchemas = ["IsaacLinkAPI"]
)
{
over "lf0_link" (
prepend apiSchemas = ["IsaacLinkAPI"]
)
{
over "lf1_link" (
prepend apiSchemas = ["IsaacLinkAPI"]
)
{
over "lf2_link" (
prepend apiSchemas = ["IsaacLinkAPI"]
)
{
over "lf3_link" (
prepend apiSchemas = ["IsaacLinkAPI"]
)
{
}
}
}
}
over "rf0_link" (
prepend apiSchemas = ["IsaacLinkAPI"]
)
{
over "rf1_link" (
prepend apiSchemas = ["IsaacLinkAPI"]
)
{
over "rf2_link" (
prepend apiSchemas = ["IsaacLinkAPI"]
)
{
over "rf3_link" (
prepend apiSchemas = ["IsaacLinkAPI"]
)
{
}
}
}
}
}
}
over "Physics"
{
over "root_joint" (
prepend apiSchemas = ["IsaacJointAPI"]
)
{
}
over "jlf0_link" (
prepend apiSchemas = ["IsaacJointAPI"]
)
{
}
over "jlf1_link" (
prepend apiSchemas = ["IsaacJointAPI"]
)
{
}
over "jlf2_link" (
prepend apiSchemas = ["IsaacJointAPI"]
)
{
}
over "jlf3_link" (
prepend apiSchemas = ["IsaacJointAPI"]
)
{
}
over "jrf0_link" (
prepend apiSchemas = ["IsaacJointAPI"]
)
{
}
over "jrf1_link" (
prepend apiSchemas = ["IsaacJointAPI"]
)
{
}
over "jrf2_link" (
prepend apiSchemas = ["IsaacJointAPI"]
)
{
}
over "jrf3_link" (
prepend apiSchemas = ["IsaacJointAPI"]
)
{
}
}
}

116
DEMO/README.en.md Normal file
View File

@ -0,0 +1,116 @@
# StackForce SimReady Isaac Lab Export
This project was generated from StackForce SimReady and is ready to train in Isaac Lab / Isaac Sim.
### Copy-Paste Training Commands
```bash
conda activate <your_isaac_lab_env_name>
cd <exported_project>
python -m pip install -e source/stackforce_simready_2foot_lab
python scripts/list_envs.py
python scripts/zero_agent.py --task Template-2foot-Direct-v0 --headless --num_envs 8
python scripts/rsl_rl/train.py --task Template-2foot-Direct-v0 --headless --num_envs 64 --max_iterations 100
```
If you want the Isaac Sim window to open, remove `--headless`.
### Recommended Isaac Lab / Isaac Sim Environment
This export is recommended with the validated stack below:
```text
Python 3.11
Isaac Sim 5.1.0
Isaac Lab v2.3.2 / pip 2.3.2.post1
Torch 2.7.0+cu128
Torchvision 0.22.0+cu128
LeggedGym-Ex 0.3.0 bundled rsl_rl
```
The export includes a one-click environment script:
```bash
chmod +x scripts/setup_stackforce_isaac_lab_sim_env.sh
./scripts/setup_stackforce_isaac_lab_sim_env.sh
```
The default environment name is `env_isaaclab`. Override it with:
```bash
ENV_NAME=my_isaaclab ./scripts/setup_stackforce_isaac_lab_sim_env.sh
```
### Training Outputs And Checkpoints
Training outputs are written under:
```text
logs/rsl_rl/<experiment_name>/<timestamp>/
```
Useful commands:
```bash
find logs -name "*.pt"
find logs -name "*.pt" | sort | tail -n 1
find logs -name "policy.onnx"
```
Training saves `model_final.pt` and also attempts to export `exported/policies/policy.onnx`.
### Resume Training
```bash
python scripts/rsl_rl/train.py --task Template-2foot-Direct-v0 --resume --load_run <run_dir_name> --checkpoint <model_x.pt>
```
### Play A Trained Policy
```bash
python scripts/rsl_rl/play.py --task Template-2foot-Direct-v0 --num_envs 1 --disable_resets
```
To load a specific checkpoint:
```bash
python scripts/rsl_rl/play.py --task Template-2foot-Direct-v0 --checkpoint logs/rsl_rl/<experiment_name>/<timestamp>/model_final.pt --num_envs 1 --disable_resets
```
Regenerate ONNX from a checkpoint:
```bash
python scripts/rsl_rl/play.py --task Template-2foot-Direct-v0 --checkpoint logs/rsl_rl/<experiment_name>/<timestamp>/model_final.pt --num_envs 1 --disable_resets --export_onnx --num_steps 1
```
### Add A Custom Reward
Edit:
```text
source/stackforce_simready_2foot_lab/stackforce_simready_2foot_lab/tasks/direct/2foot/custom_rewards.py
```
Implement your reward terms in `compute_custom_reward_terms(env)`.
Then edit:
```text
source/stackforce_simready_2foot_lab/stackforce_simready_2foot_lab/tasks/direct/2foot/2foot_env_cfg.py
```
Change:
```python
"custom_reward": 0.0
```
to a non-zero scale such as:
```python
"custom_reward": 1.0
```
Notes:
- The StackForce `trimesh` option is mapped to Isaac Lab rough terrain generation.
- Assets stay embedded in the python package under `source/stackforce_simready_2foot_lab/stackforce_simready_2foot_lab/assets`.

112
DEMO/README.zh.md Normal file
View File

@ -0,0 +1,112 @@
# StackForce SimReady Isaac Lab 导出工程
这个工程由 StackForce SimReady 导出,可直接用于 Isaac Lab / Isaac Sim 训练。
### 直接可复制的训练命令
```bash
conda activate <你自己的IsaacLab环境名称>
cd <exported_project>
python -m pip install -e source/stackforce_simready_2foot_lab
python scripts/list_envs.py
python scripts/zero_agent.py --task Template-2foot-Direct-v0 --headless --num_envs 8
python scripts/rsl_rl/train.py --task Template-2foot-Direct-v0 --headless --num_envs 64 --max_iterations 100
```
如果你想打开 Isaac Sim 窗口,把训练命令里的 `--headless` 去掉即可。
### 推荐 Isaac Lab / Isaac Sim 环境
本导出工程推荐使用下面这套已验证配置:
```text
Python 3.11
Isaac Sim 5.1.0
Isaac Lab v2.3.2 / pip 2.3.2.post1
Torch 2.7.0+cu128
Torchvision 0.22.0+cu128
LeggedGym-Ex 0.3.0 提供的 rsl_rl
```
导出包内已包含一键环境脚本:
```bash
chmod +x scripts/setup_stackforce_isaac_lab_sim_env.sh
./scripts/setup_stackforce_isaac_lab_sim_env.sh
```
脚本默认创建 `env_isaaclab`。如果你想改环境名:
```bash
ENV_NAME=my_isaaclab ./scripts/setup_stackforce_isaac_lab_sim_env.sh
```
### 训练输出和 checkpoint
训练输出在:
```text
logs/rsl_rl/<experiment_name>/<timestamp>/
```
可用下面的命令直接查找:
```bash
find logs -name "*.pt"
find logs -name "*.pt" | sort | tail -n 1
find logs -name "policy.onnx"
```
Training saves `model_final.pt` and also attempts to export `exported/policies/policy.onnx`.
### 继续训练
```bash
python scripts/rsl_rl/train.py --task Template-2foot-Direct-v0 --resume --load_run <run_dir_name> --checkpoint <model_x.pt>
```
### 播放训练后的策略
```bash
python scripts/rsl_rl/play.py --task Template-2foot-Direct-v0 --num_envs 1 --disable_resets
```
如需加载指定 checkpoint
```bash
python scripts/rsl_rl/play.py --task Template-2foot-Direct-v0 --checkpoint logs/rsl_rl/<experiment_name>/<timestamp>/model_final.pt --num_envs 1 --disable_resets
```
Regenerate ONNX from a checkpoint:
```bash
python scripts/rsl_rl/play.py --task Template-2foot-Direct-v0 --checkpoint logs/rsl_rl/<experiment_name>/<timestamp>/model_final.pt --num_envs 1 --disable_resets --export_onnx --num_steps 1
```
### 增加自定义 Reward
编辑:
```text
source/stackforce_simready_2foot_lab/stackforce_simready_2foot_lab/tasks/direct/2foot/custom_rewards.py
```
`compute_custom_reward_terms(env)` 中返回你自己的 reward term。
然后再编辑:
```text
source/stackforce_simready_2foot_lab/stackforce_simready_2foot_lab/tasks/direct/2foot/2foot_env_cfg.py
```
把:
```python
"custom_reward": 0.0
```
改成非零,比如:
```python
"custom_reward": 1.0
```

29
DEMO/scripts/list_envs.py Normal file
View File

@ -0,0 +1,29 @@
import argparse
parser = argparse.ArgumentParser(description="List StackForce Isaac Lab environments.")
parser.add_argument("--keyword", type=str, default=None, help="Keyword to filter environments.")
args_cli = parser.parse_args()
import gymnasium as gym
from prettytable import PrettyTable
import stackforce_simready_2foot_lab.tasks # noqa: F401
def main():
table = PrettyTable(["S. No.", "Task Name", "Entry Point", "Config"])
table.title = "Available StackForce Isaac Lab Environments"
table.align["Task Name"] = "l"
table.align["Entry Point"] = "l"
table.align["Config"] = "l"
index = 0
for task_spec in gym.registry.values():
if "Template-" in task_spec.id and (args_cli.keyword is None or args_cli.keyword in task_spec.id):
table.add_row([index + 1, task_spec.id, task_spec.entry_point, task_spec.kwargs["env_cfg_entry_point"]])
index += 1
print(table)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,38 @@
import argparse
from isaaclab.app import AppLauncher
parser = argparse.ArgumentParser(description="Random agent for StackForce Isaac Lab environments.")
parser.add_argument("--disable_fabric", action="store_true", default=False)
parser.add_argument("--num_envs", type=int, default=None)
parser.add_argument("--task", type=str, default=None)
AppLauncher.add_app_launcher_args(parser)
args_cli = parser.parse_args()
app_launcher = AppLauncher(args_cli)
simulation_app = app_launcher.app
import gymnasium as gym
import torch
from isaaclab_tasks.utils import parse_env_cfg
import stackforce_simready_2foot_lab.tasks # noqa: F401
def main():
env_cfg = parse_env_cfg(
args_cli.task, device=args_cli.device, num_envs=args_cli.num_envs, use_fabric=not args_cli.disable_fabric
)
env = gym.make(args_cli.task, cfg=env_cfg)
env.reset()
while simulation_app.is_running():
with torch.inference_mode():
actions = 2 * torch.rand(env.action_space.shape, device=env.unwrapped.device) - 1
env.step(actions)
env.close()
if __name__ == "__main__":
main()
simulation_app.close()

View File

@ -0,0 +1,40 @@
from __future__ import annotations
import argparse
import random
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from isaaclab_rl.rsl_rl import RslRlBaseRunnerCfg
def add_rsl_rl_args(parser: argparse.ArgumentParser):
arg_group = parser.add_argument_group("rsl_rl", description="Arguments for RSL-RL agent.")
arg_group.add_argument("--experiment_name", type=str, default=None, help="Experiment folder name.")
arg_group.add_argument("--run_name", type=str, default=None, help="Run name suffix.")
arg_group.add_argument("--resume", action="store_true", default=False, help="Resume from checkpoint.")
arg_group.add_argument("--load_run", type=str, default=None, help="Run folder to resume from.")
arg_group.add_argument("--checkpoint", type=str, default=None, help="Checkpoint file to resume from.")
arg_group.add_argument("--logger", type=str, default=None, choices={"wandb", "tensorboard", "neptune"})
arg_group.add_argument("--log_project_name", type=str, default=None, help="Logger project name.")
def update_rsl_rl_cfg(agent_cfg: "RslRlBaseRunnerCfg", args_cli: argparse.Namespace):
if hasattr(args_cli, "seed") and args_cli.seed is not None:
if args_cli.seed == -1:
args_cli.seed = random.randint(0, 10000)
agent_cfg.seed = args_cli.seed
if args_cli.resume is not None:
agent_cfg.resume = args_cli.resume
if args_cli.load_run is not None:
agent_cfg.load_run = args_cli.load_run
if args_cli.checkpoint is not None:
agent_cfg.load_checkpoint = args_cli.checkpoint
if args_cli.run_name is not None:
agent_cfg.run_name = args_cli.run_name
if args_cli.logger is not None:
agent_cfg.logger = args_cli.logger
if agent_cfg.logger in {"wandb", "neptune"} and args_cli.log_project_name:
agent_cfg.wandb_project = args_cli.log_project_name
agent_cfg.neptune_project = args_cli.log_project_name
return agent_cfg

388
DEMO/scripts/rsl_rl/play.py Normal file
View File

@ -0,0 +1,388 @@
"""Script to play a trained RSL-RL policy."""
import argparse
import os
import sys
from isaaclab.app import AppLauncher
parser = argparse.ArgumentParser(description="Play a trained RSL-RL policy.")
parser.add_argument("--num_envs", type=int, default=1, help="Number of environments to simulate.")
parser.add_argument("--task", type=str, default=None, help="Name of the task.")
parser.add_argument("--agent", type=str, default="rsl_rl_cfg_entry_point", help="Agent configuration entry point.")
parser.add_argument("--seed", type=int, default=None, help="Seed used for the environment.")
parser.add_argument("--load_run", type=str, default=".*", help="Run folder name or regex to load from.")
parser.add_argument(
"--checkpoint",
type=str,
default="model_.*.pt",
help="Checkpoint filename regex under logs, or a direct path to a .pt file.",
)
parser.add_argument("--num_steps", type=int, default=500, help="Number of inference steps to simulate.")
parser.add_argument(
"--disable_resets",
action="store_true",
default=False,
help="Disable environment reset during visual play so short or unstable policies do not instantly jump back to the start pose.",
)
parser.add_argument("--export_io_descriptors", action="store_true", default=False, help="Export IO descriptors.")
parser.add_argument("--export_onnx", action="store_true", default=False, help="Export policy.onnx from the loaded checkpoint.")
AppLauncher.add_app_launcher_args(parser)
args_cli, hydra_args = parser.parse_known_args()
sys.argv = [sys.argv[0]] + hydra_args
app_launcher = AppLauncher(args_cli)
simulation_app = app_launcher.app
import gymnasium as gym
import inspect
import os
import torch
from rsl_rl.runners import OnPolicyRunner
try:
from rsl_rl.algorithms import PPO
except ImportError:
PPO = None
try:
from tensordict import TensorDict
except ImportError:
TensorDict = None
from isaaclab.envs import DirectMARLEnv, DirectMARLEnvCfg, DirectRLEnvCfg, ManagerBasedRLEnvCfg, multi_agent_to_single_agent
from isaaclab_rl.rsl_rl import RslRlBaseRunnerCfg
from isaaclab_tasks.utils import get_checkpoint_path
from isaaclab_tasks.utils.hydra import hydra_task_config
import stackforce_simready_2foot_lab.tasks # noqa: F401
import os
import torch
class _StackForceOnnxPolicy(torch.nn.Module):
def __init__(self, policy):
super().__init__()
self.policy = policy
def forward(self, obs):
actions = self.policy(obs)
if isinstance(actions, (tuple, list)):
return actions[0]
if isinstance(actions, dict):
if "actions" in actions:
return actions["actions"]
if "action" in actions:
return actions["action"]
return next(iter(actions.values()))
return actions
def _stackforce_policy_obs_tensor(obs):
if isinstance(obs, dict):
obs = obs["policy"] if "policy" in obs else next(iter(obs.values()))
elif not isinstance(obs, torch.Tensor) and hasattr(obs, "get"):
try:
candidate = obs.get("policy")
except Exception:
candidate = None
if candidate is not None:
obs = candidate
if not isinstance(obs, torch.Tensor):
raise TypeError(f"ONNX export requires a tensor policy observation, got {type(obs)!r}")
if hasattr(obs, "detach"):
obs = obs.detach()
if obs.dim() == 1:
obs = obs.unsqueeze(0)
elif obs.shape[0] > 1:
obs = obs[:1]
return obs.contiguous()
def stackforce_export_policy_as_onnx(policy, obs, output_dir, file_name="policy.onnx", opset=17):
os.makedirs(output_dir, exist_ok=True)
output_path = os.path.join(output_dir, file_name)
sample_obs = _stackforce_policy_obs_tensor(obs)
module = _StackForceOnnxPolicy(policy).to(sample_obs.device).eval()
with torch.no_grad():
torch.onnx.export(
module,
sample_obs,
output_path,
input_names=["obs"],
output_names=["actions"],
dynamic_axes={"obs": {0: "batch"}, "actions": {0: "batch"}},
opset_version=opset,
)
print(f"Exported ONNX policy to: {output_path}")
return output_path
def _runner_uses_obs_groups():
try:
source = inspect.getsource(OnPolicyRunner)
if PPO is not None and hasattr(PPO, "construct_algorithm"):
source += "\n" + inspect.getsource(PPO.construct_algorithm)
except OSError:
return False
return "resolve_obs_groups" in source or '"obs_groups"' in source or "'obs_groups'" in source
def _runner_uses_split_actor_critic():
try:
source = inspect.getsource(OnPolicyRunner)
if PPO is not None and hasattr(PPO, "construct_algorithm"):
source += "\n" + inspect.getsource(PPO.construct_algorithm)
except OSError:
return False
return 'cfg["actor"]' in source or "cfg['actor']" in source or 'cfg["critic"]' in source or "cfg['critic']" in source
def _runner_expects_privileged_step():
try:
source = inspect.getsource(OnPolicyRunner.learn)
except OSError:
return True
return "privileged_obs" in source or "critic_obs" in source
def _format_rsl_rl_obs(obs_dict, use_obs_groups):
if not use_obs_groups:
return obs_dict["policy"]
if TensorDict is not None and not isinstance(obs_dict, TensorDict):
first_obs = next(iter(obs_dict.values()))
return TensorDict(dict(obs_dict), batch_size=[first_obs.shape[0]], device=first_obs.device)
return obs_dict
class LegacyRslRlVecEnvWrapper:
def __init__(self, env, clip_actions=None):
self.env = env
self.clip_actions = clip_actions
self.use_obs_groups = _runner_uses_obs_groups()
self.return_privileged_obs = _runner_expects_privileged_step()
self.num_envs = env.unwrapped.num_envs
self.device = env.unwrapped.device
self.max_episode_length = env.unwrapped.max_episode_length
self.cfg = env.unwrapped.cfg
self.num_actions = gym.spaces.flatdim(env.unwrapped.single_action_space)
obs_dict, extras = self.env.reset()
self.obs_buf = _format_rsl_rl_obs(obs_dict, self.use_obs_groups)
self.privileged_obs_buf = obs_dict.get("critic")
self.num_obs = obs_dict["policy"].shape[-1]
self.num_privileged_obs = self.privileged_obs_buf.shape[-1] if self.privileged_obs_buf is not None else None
self.rew_buf = torch.zeros(self.num_envs, device=self.device)
self.reset_buf = torch.zeros(self.num_envs, dtype=torch.long, device=self.device)
self.episode_length_buf = env.unwrapped.episode_length_buf
self.extras = extras
def get_observations(self):
return self.obs_buf
def get_privileged_observations(self):
return self.privileged_obs_buf
def reset(self, env_ids=None):
del env_ids
obs_dict, extras = self.env.reset()
self.obs_buf = _format_rsl_rl_obs(obs_dict, self.use_obs_groups)
self.privileged_obs_buf = obs_dict.get("critic")
self.extras = extras
if not self.return_privileged_obs:
return self.obs_buf
return self.obs_buf, self.privileged_obs_buf
def step(self, actions):
if self.clip_actions is not None:
actions = torch.clamp(actions, -self.clip_actions, self.clip_actions)
obs_dict, rewards, terminated, truncated, extras = self.env.step(actions)
dones = (terminated | truncated).to(dtype=torch.long)
if not self.env.unwrapped.cfg.is_finite_horizon:
extras["time_outs"] = truncated
episode_log = dict(extras.get("episode", {}))
if torch.any(dones.bool()) and "log" in extras:
episode_log.update(extras["log"])
episode_log["Step_Reward/mean"] = torch.mean(rewards.detach())
episode_log["Step_Reward/abs_mean"] = torch.mean(torch.abs(rewards.detach()))
extras["episode"] = episode_log
self.obs_buf = _format_rsl_rl_obs(obs_dict, self.use_obs_groups)
self.privileged_obs_buf = obs_dict.get("critic")
self.rew_buf = rewards
self.reset_buf = dones
self.extras = extras
if not self.return_privileged_obs:
return self.obs_buf, rewards, dones, extras
return self.obs_buf, self.privileged_obs_buf, rewards, dones, extras
def close(self):
return self.env.close()
def _runner_expects_nested_runner():
try:
source = inspect.getsource(OnPolicyRunner)
except OSError:
return True
return 'train_cfg["runner"]' in source or "train_cfg['runner']" in source
def _runner_uses_nested_class_name():
try:
source = inspect.getsource(OnPolicyRunner)
except OSError:
return False
return (
'algorithm"]["class_name' in source
or "algorithm']['class_name" in source
or 'policy_cfg.pop("class_name")' in source
or "policy_cfg.pop('class_name')" in source
or 'self.policy_cfg.pop("class_name")' in source
or "self.policy_cfg.pop('class_name')" in source
or "resolve_callable" in source
)
def _runner_uses_split_actor_critic():
try:
source = inspect.getsource(OnPolicyRunner)
if PPO is not None and hasattr(PPO, "construct_algorithm"):
source += "\n" + inspect.getsource(PPO.construct_algorithm)
except OSError:
return False
return 'cfg["actor"]' in source or "cfg['actor']" in source or 'cfg["critic"]' in source or "cfg['critic']" in source
def to_compatible_rsl_rl_cfg(agent_cfg):
data = agent_cfg.to_dict() if hasattr(agent_cfg, "to_dict") else dict(agent_cfg)
allowed_policy_keys = {
"actor_hidden_dims",
"critic_hidden_dims",
"activation",
"init_noise_std",
"clip_actions",
"actor_obs_normalization",
"critic_obs_normalization",
}
allowed_algorithm_keys = {
"num_learning_epochs",
"num_mini_batches",
"clip_param",
"gamma",
"lam",
"value_loss_coef",
"entropy_coef",
"learning_rate",
"max_grad_norm",
"use_clipped_value_loss",
"schedule",
"desired_kl",
"use_spo",
}
if "runner" in data and "policy" in data and "algorithm" in data:
runner_cfg = dict(data["runner"])
policy_cfg = {key: value for key, value in dict(data["policy"]).items() if key in allowed_policy_keys or key == "class_name"}
algorithm_cfg = {key: value for key, value in dict(data["algorithm"]).items() if key in allowed_algorithm_keys or key == "class_name"}
else:
policy_cfg = {key: value for key, value in dict(data["policy"]).items() if key in allowed_policy_keys}
algorithm_cfg = {key: value for key, value in dict(data["algorithm"]).items() if key in allowed_algorithm_keys}
runner_cfg = {key: value for key, value in data.items() if key not in {"policy", "algorithm", "class_name"}}
runner_cfg.setdefault("num_steps_per_env", getattr(agent_cfg, "num_steps_per_env", 24))
runner_cfg.setdefault("max_iterations", getattr(agent_cfg, "max_iterations", 1500))
runner_cfg.setdefault("save_interval", getattr(agent_cfg, "save_interval", 50))
runner_cfg.setdefault("obs_groups", {"policy": ["policy"], "critic": ["policy"]})
runner_cfg.setdefault("experiment_name", getattr(agent_cfg, "experiment_name", "stackforce"))
runner_cfg.setdefault("run_name", getattr(agent_cfg, "run_name", ""))
runner_cfg.setdefault("resume", getattr(agent_cfg, "resume", False))
runner_cfg.setdefault("load_run", getattr(agent_cfg, "load_run", ".*"))
runner_cfg.setdefault("checkpoint", getattr(agent_cfg, "load_checkpoint", "model_.*.pt"))
if _runner_uses_nested_class_name():
policy_cfg.setdefault("class_name", "ActorCritic")
algorithm_cfg.setdefault("class_name", "PPO")
else:
runner_cfg.setdefault("policy_class_name", "ActorCritic")
runner_cfg.setdefault("algorithm_class_name", "PPO")
if _runner_expects_nested_runner():
return {"runner": runner_cfg, "policy": policy_cfg, "algorithm": algorithm_cfg}
if _runner_uses_split_actor_critic():
algorithm_cfg.setdefault("class_name", "PPO")
algorithm_cfg.pop("use_spo", None)
actor_cfg = {
"class_name": "MLPModel",
"hidden_dims": policy_cfg.get("actor_hidden_dims", [256, 256, 128]),
"activation": policy_cfg.get("activation", "elu"),
"obs_normalization": policy_cfg.get("actor_obs_normalization", False),
"distribution_cfg": {
"class_name": "GaussianDistribution",
"init_std": policy_cfg.get("init_noise_std", 1.0),
},
}
critic_cfg = {
"class_name": "MLPModel",
"hidden_dims": policy_cfg.get("critic_hidden_dims", [256, 256, 128]),
"activation": policy_cfg.get("activation", "elu"),
"obs_normalization": policy_cfg.get("critic_obs_normalization", False),
}
runner_cfg.pop("policy_class_name", None)
runner_cfg.pop("algorithm_class_name", None)
runner_cfg["obs_groups"] = {"actor": ["policy"], "critic": ["policy"], "policy": ["policy"]}
runner_cfg.setdefault("multi_gpu", None)
return {**runner_cfg, "actor": actor_cfg, "critic": critic_cfg, "algorithm": algorithm_cfg}
return {**runner_cfg, "policy": policy_cfg, "algorithm": algorithm_cfg}
@hydra_task_config(args_cli.task, args_cli.agent)
def main(env_cfg: ManagerBasedRLEnvCfg | DirectRLEnvCfg | DirectMARLEnvCfg, agent_cfg: RslRlBaseRunnerCfg):
env_cfg.scene.num_envs = args_cli.num_envs if args_cli.num_envs is not None else env_cfg.scene.num_envs
env_cfg.seed = args_cli.seed if args_cli.seed is not None else agent_cfg.seed
env_cfg.sim.device = args_cli.device if args_cli.device is not None else env_cfg.sim.device
if isinstance(env_cfg, ManagerBasedRLEnvCfg):
env_cfg.export_io_descriptors = args_cli.export_io_descriptors
elif args_cli.disable_resets and hasattr(env_cfg, "visual_disable_resets"):
env_cfg.visual_disable_resets = True
log_root_path = os.path.abspath(os.path.join("logs", "rsl_rl", agent_cfg.experiment_name))
checkpoint_arg = args_cli.checkpoint
if os.path.isfile(checkpoint_arg):
resume_path = os.path.abspath(checkpoint_arg)
else:
resume_path = get_checkpoint_path(log_root_path, args_cli.load_run, checkpoint_arg)
print(f"[INFO]: Loading model checkpoint from: {resume_path}")
env = gym.make(args_cli.task, cfg=env_cfg)
if isinstance(env.unwrapped, DirectMARLEnv):
env = multi_agent_to_single_agent(env)
legacy_agent_cfg = to_compatible_rsl_rl_cfg(agent_cfg)
wrapped_env = LegacyRslRlVecEnvWrapper(env, clip_actions=getattr(agent_cfg, "clip_actions", None))
runner = OnPolicyRunner(wrapped_env, legacy_agent_cfg, log_dir=None, device=env.unwrapped.device)
runner.load(resume_path, load_optimizer=False)
policy = runner.get_inference_policy(device=env.unwrapped.device)
obs = wrapped_env.get_observations()
if args_cli.export_onnx:
stackforce_export_policy_as_onnx(
policy,
obs,
os.path.join(os.path.dirname(resume_path), "exported", "policies"),
)
steps = 0
with torch.inference_mode():
while simulation_app.is_running():
actions = policy(obs)
step_result = wrapped_env.step(actions)
obs = step_result[0]
steps += 1
if args_cli.num_steps > 0 and steps >= args_cli.num_steps:
break
wrapped_env.close()
if __name__ == "__main__":
main()
simulation_app.close()

View File

@ -0,0 +1,466 @@
"""Script to train RL agent with RSL-RL."""
"""Launch Isaac Sim Simulator first."""
import argparse
import sys
from isaaclab.app import AppLauncher
import cli_args # isort: skip
parser = argparse.ArgumentParser(description="Train an RL agent with RSL-RL.")
parser.add_argument("--video", action="store_true", default=False, help="Record videos during training.")
parser.add_argument("--video_length", type=int, default=200, help="Length of the recorded video (in steps).")
parser.add_argument("--video_interval", type=int, default=2000, help="Interval between video recordings (in steps).")
parser.add_argument("--num_envs", type=int, default=None, help="Number of environments to simulate.")
parser.add_argument("--task", type=str, default=None, help="Name of the task.")
parser.add_argument("--agent", type=str, default="rsl_rl_cfg_entry_point", help="Agent configuration entry point.")
parser.add_argument("--seed", type=int, default=None, help="Seed used for the environment.")
parser.add_argument("--max_iterations", type=int, default=None, help="RL policy training iterations.")
parser.add_argument("--distributed", action="store_true", default=False, help="Run distributed training.")
parser.add_argument("--export_io_descriptors", action="store_true", default=False, help="Export IO descriptors.")
parser.add_argument("--ray-proc-id", "-rid", type=int, default=None)
cli_args.add_rsl_rl_args(parser)
AppLauncher.add_app_launcher_args(parser)
args_cli, hydra_args = parser.parse_known_args()
if args_cli.video:
args_cli.enable_cameras = True
sys.argv = [sys.argv[0]] + hydra_args
app_launcher = AppLauncher(args_cli)
simulation_app = app_launcher.app
import importlib.metadata as metadata
import inspect
import logging
import os
import platform
import time
from datetime import datetime
import gymnasium as gym
import torch
from packaging import version
from rsl_rl.env import VecEnv
from rsl_rl.runners import OnPolicyRunner
try:
from rsl_rl.algorithms import PPO
except ImportError:
PPO = None
try:
from tensordict import TensorDict
except ImportError:
TensorDict = None
from isaaclab.envs import DirectMARLEnv, DirectMARLEnvCfg, DirectRLEnvCfg, ManagerBasedRLEnvCfg, multi_agent_to_single_agent
from isaaclab.utils.dict import print_dict
from isaaclab.utils.io import dump_yaml
from isaaclab_rl.rsl_rl import RslRlBaseRunnerCfg
import isaaclab_tasks # noqa: F401
from isaaclab_tasks.utils import get_checkpoint_path
from isaaclab_tasks.utils.hydra import hydra_task_config
import stackforce_simready_2foot_lab.tasks # noqa: F401
logger = logging.getLogger(__name__)
import os
import torch
class _StackForceOnnxPolicy(torch.nn.Module):
def __init__(self, policy):
super().__init__()
self.policy = policy
def forward(self, obs):
actions = self.policy(obs)
if isinstance(actions, (tuple, list)):
return actions[0]
if isinstance(actions, dict):
if "actions" in actions:
return actions["actions"]
if "action" in actions:
return actions["action"]
return next(iter(actions.values()))
return actions
def _stackforce_policy_obs_tensor(obs):
if isinstance(obs, dict):
obs = obs["policy"] if "policy" in obs else next(iter(obs.values()))
elif not isinstance(obs, torch.Tensor) and hasattr(obs, "get"):
try:
candidate = obs.get("policy")
except Exception:
candidate = None
if candidate is not None:
obs = candidate
if not isinstance(obs, torch.Tensor):
raise TypeError(f"ONNX export requires a tensor policy observation, got {type(obs)!r}")
if hasattr(obs, "detach"):
obs = obs.detach()
if obs.dim() == 1:
obs = obs.unsqueeze(0)
elif obs.shape[0] > 1:
obs = obs[:1]
return obs.contiguous()
def stackforce_export_policy_as_onnx(policy, obs, output_dir, file_name="policy.onnx", opset=17):
os.makedirs(output_dir, exist_ok=True)
output_path = os.path.join(output_dir, file_name)
sample_obs = _stackforce_policy_obs_tensor(obs)
module = _StackForceOnnxPolicy(policy).to(sample_obs.device).eval()
with torch.no_grad():
torch.onnx.export(
module,
sample_obs,
output_path,
input_names=["obs"],
output_names=["actions"],
dynamic_axes={"obs": {0: "batch"}, "actions": {0: "batch"}},
opset_version=opset,
)
print(f"Exported ONNX policy to: {output_path}")
return output_path
try:
from rsl_rl.runners import DistillationRunner
except ImportError:
DistillationRunner = None
RSL_RL_VERSION = "3.0.1"
try:
installed_version = metadata.version("rsl-rl-lib")
except metadata.PackageNotFoundError:
installed_version = None
if installed_version is not None and version.parse(installed_version) < version.parse(RSL_RL_VERSION):
if platform.system() == "Windows":
cmd = [r".\isaaclab.bat", "-p", "-m", "pip", "install", f"rsl-rl-lib=={RSL_RL_VERSION}"]
else:
cmd = ["./isaaclab.sh", "-p", "-m", "pip", "install", f"rsl-rl-lib=={RSL_RL_VERSION}"]
print(
f"Please install the correct version of RSL-RL. Existing version is: '{installed_version}' and required version is: '{RSL_RL_VERSION}'.\n"
f"To install the correct version, run:\n\n\t{' '.join(cmd)}\n"
)
raise SystemExit(1)
torch.backends.cuda.matmul.allow_tf32 = True
torch.backends.cudnn.allow_tf32 = True
torch.backends.cudnn.deterministic = False
torch.backends.cudnn.benchmark = False
def _runner_uses_obs_groups():
try:
source = inspect.getsource(OnPolicyRunner)
if PPO is not None and hasattr(PPO, "construct_algorithm"):
source += "\n" + inspect.getsource(PPO.construct_algorithm)
except OSError:
return False
return "resolve_obs_groups" in source or '"obs_groups"' in source or "'obs_groups'" in source
def _runner_uses_split_actor_critic():
try:
source = inspect.getsource(OnPolicyRunner)
if PPO is not None and hasattr(PPO, "construct_algorithm"):
source += "\n" + inspect.getsource(PPO.construct_algorithm)
except OSError:
return False
return 'cfg["actor"]' in source or "cfg['actor']" in source or 'cfg["critic"]' in source or "cfg['critic']" in source
def _runner_expects_privileged_step():
try:
source = inspect.getsource(OnPolicyRunner.learn)
except OSError:
return True
return "privileged_obs" in source or "critic_obs" in source
def _format_rsl_rl_obs(obs_dict, use_obs_groups):
if not use_obs_groups:
return obs_dict["policy"]
if TensorDict is not None and not isinstance(obs_dict, TensorDict):
first_obs = next(iter(obs_dict.values()))
return TensorDict(dict(obs_dict), batch_size=[first_obs.shape[0]], device=first_obs.device)
return obs_dict
class LegacyRslRlVecEnvWrapper(VecEnv):
def __init__(self, env, clip_actions=None):
self.env = env
self.clip_actions = clip_actions
self.use_obs_groups = _runner_uses_obs_groups()
self.return_privileged_obs = _runner_expects_privileged_step()
self.num_envs = env.unwrapped.num_envs
self.device = env.unwrapped.device
self.max_episode_length = env.unwrapped.max_episode_length
self.cfg = env.unwrapped.cfg
self.num_actions = gym.spaces.flatdim(env.unwrapped.single_action_space)
obs_dict, extras = self.env.reset()
self.obs_buf = _format_rsl_rl_obs(obs_dict, self.use_obs_groups)
self.privileged_obs_buf = obs_dict.get("critic")
self.num_obs = obs_dict["policy"].shape[-1]
self.num_privileged_obs = self.privileged_obs_buf.shape[-1] if self.privileged_obs_buf is not None else None
self.rew_buf = torch.zeros(self.num_envs, device=self.device)
self.reset_buf = torch.zeros(self.num_envs, dtype=torch.long, device=self.device)
self.episode_length_buf = env.unwrapped.episode_length_buf
self.extras = extras
def get_observations(self):
return self.obs_buf
def get_privileged_observations(self):
return self.privileged_obs_buf
def reset(self, env_ids=None):
del env_ids
obs_dict, extras = self.env.reset()
self.obs_buf = _format_rsl_rl_obs(obs_dict, self.use_obs_groups)
self.privileged_obs_buf = obs_dict.get("critic")
self.extras = extras
if not self.return_privileged_obs:
return self.obs_buf
return self.obs_buf, self.privileged_obs_buf
def step(self, actions):
if self.clip_actions is not None:
actions = torch.clamp(actions, -self.clip_actions, self.clip_actions)
obs_dict, rewards, terminated, truncated, extras = self.env.step(actions)
dones = (terminated | truncated).to(dtype=torch.long)
if not self.env.unwrapped.cfg.is_finite_horizon:
extras["time_outs"] = truncated
episode_log = dict(extras.get("episode", {}))
if torch.any(dones.bool()) and "log" in extras:
episode_log.update(extras["log"])
episode_log["Step_Reward/mean"] = torch.mean(rewards.detach())
episode_log["Step_Reward/abs_mean"] = torch.mean(torch.abs(rewards.detach()))
extras["episode"] = episode_log
self.obs_buf = _format_rsl_rl_obs(obs_dict, self.use_obs_groups)
self.privileged_obs_buf = obs_dict.get("critic")
self.rew_buf = rewards
self.reset_buf = dones
self.extras = extras
if not self.return_privileged_obs:
return self.obs_buf, rewards, dones, extras
return self.obs_buf, self.privileged_obs_buf, rewards, dones, extras
def close(self):
return self.env.close()
def _runner_expects_nested_runner():
try:
source = inspect.getsource(OnPolicyRunner)
except OSError:
return True
return 'train_cfg["runner"]' in source or "train_cfg['runner']" in source
def _runner_uses_nested_class_name():
try:
source = inspect.getsource(OnPolicyRunner)
except OSError:
return False
return (
'algorithm"]["class_name' in source
or "algorithm']['class_name" in source
or 'policy_cfg.pop("class_name")' in source
or "policy_cfg.pop('class_name')" in source
or 'self.policy_cfg.pop("class_name")' in source
or "self.policy_cfg.pop('class_name')" in source
or "resolve_callable" in source
)
def _runner_uses_split_actor_critic():
try:
source = inspect.getsource(OnPolicyRunner)
if PPO is not None and hasattr(PPO, "construct_algorithm"):
source += "\n" + inspect.getsource(PPO.construct_algorithm)
except OSError:
return False
return 'cfg["actor"]' in source or "cfg['actor']" in source or 'cfg["critic"]' in source or "cfg['critic']" in source
def to_compatible_rsl_rl_cfg(agent_cfg):
data = agent_cfg.to_dict() if hasattr(agent_cfg, "to_dict") else dict(agent_cfg)
allowed_policy_keys = {
"actor_hidden_dims",
"critic_hidden_dims",
"activation",
"init_noise_std",
"clip_actions",
"actor_obs_normalization",
"critic_obs_normalization",
}
allowed_algorithm_keys = {
"num_learning_epochs",
"num_mini_batches",
"clip_param",
"gamma",
"lam",
"value_loss_coef",
"entropy_coef",
"learning_rate",
"max_grad_norm",
"use_clipped_value_loss",
"schedule",
"desired_kl",
"use_spo",
}
if "runner" in data and "policy" in data and "algorithm" in data:
runner_cfg = dict(data["runner"])
policy_cfg = {key: value for key, value in dict(data["policy"]).items() if key in allowed_policy_keys or key == "class_name"}
algorithm_cfg = {key: value for key, value in dict(data["algorithm"]).items() if key in allowed_algorithm_keys or key == "class_name"}
else:
policy_cfg = {key: value for key, value in dict(data["policy"]).items() if key in allowed_policy_keys}
algorithm_cfg = {key: value for key, value in dict(data["algorithm"]).items() if key in allowed_algorithm_keys}
runner_cfg = {key: value for key, value in data.items() if key not in {"policy", "algorithm", "class_name"}}
runner_cfg.setdefault("num_steps_per_env", getattr(agent_cfg, "num_steps_per_env", 24))
runner_cfg.setdefault("max_iterations", getattr(agent_cfg, "max_iterations", 1500))
runner_cfg.setdefault("save_interval", getattr(agent_cfg, "save_interval", 50))
runner_cfg.setdefault("obs_groups", {"policy": ["policy"], "critic": ["policy"]})
runner_cfg.setdefault("experiment_name", getattr(agent_cfg, "experiment_name", "stackforce"))
runner_cfg.setdefault("run_name", getattr(agent_cfg, "run_name", ""))
runner_cfg.setdefault("resume", getattr(agent_cfg, "resume", False))
runner_cfg.setdefault("load_run", getattr(agent_cfg, "load_run", ".*"))
runner_cfg.setdefault("checkpoint", getattr(agent_cfg, "load_checkpoint", "model_.*.pt"))
if _runner_uses_nested_class_name():
policy_cfg.setdefault("class_name", "ActorCritic")
algorithm_cfg.setdefault("class_name", "PPO")
else:
runner_cfg.setdefault("policy_class_name", "ActorCritic")
runner_cfg.setdefault("algorithm_class_name", "PPO")
if _runner_expects_nested_runner():
return {"runner": runner_cfg, "policy": policy_cfg, "algorithm": algorithm_cfg}
if _runner_uses_split_actor_critic():
algorithm_cfg.setdefault("class_name", "PPO")
algorithm_cfg.pop("use_spo", None)
actor_cfg = {
"class_name": "MLPModel",
"hidden_dims": policy_cfg.get("actor_hidden_dims", [256, 256, 128]),
"activation": policy_cfg.get("activation", "elu"),
"obs_normalization": policy_cfg.get("actor_obs_normalization", False),
"distribution_cfg": {
"class_name": "GaussianDistribution",
"init_std": policy_cfg.get("init_noise_std", 1.0),
},
}
critic_cfg = {
"class_name": "MLPModel",
"hidden_dims": policy_cfg.get("critic_hidden_dims", [256, 256, 128]),
"activation": policy_cfg.get("activation", "elu"),
"obs_normalization": policy_cfg.get("critic_obs_normalization", False),
}
runner_cfg.pop("policy_class_name", None)
runner_cfg.pop("algorithm_class_name", None)
runner_cfg["obs_groups"] = {"actor": ["policy"], "critic": ["policy"], "policy": ["policy"]}
runner_cfg.setdefault("multi_gpu", None)
return {**runner_cfg, "actor": actor_cfg, "critic": critic_cfg, "algorithm": algorithm_cfg}
return {**runner_cfg, "policy": policy_cfg, "algorithm": algorithm_cfg}
@hydra_task_config(args_cli.task, args_cli.agent)
def main(env_cfg: ManagerBasedRLEnvCfg | DirectRLEnvCfg | DirectMARLEnvCfg, agent_cfg: RslRlBaseRunnerCfg):
agent_cfg = cli_args.update_rsl_rl_cfg(agent_cfg, args_cli)
env_cfg.scene.num_envs = args_cli.num_envs if args_cli.num_envs is not None else env_cfg.scene.num_envs
agent_cfg.max_iterations = args_cli.max_iterations if args_cli.max_iterations is not None else agent_cfg.max_iterations
env_cfg.seed = agent_cfg.seed
env_cfg.sim.device = args_cli.device if args_cli.device is not None else env_cfg.sim.device
if args_cli.distributed and args_cli.device is not None and "cpu" in args_cli.device:
raise ValueError("Distributed training is not supported on CPU.")
if args_cli.distributed:
env_cfg.sim.device = f"cuda:{app_launcher.local_rank}"
agent_cfg.device = f"cuda:{app_launcher.local_rank}"
seed = agent_cfg.seed + app_launcher.local_rank
env_cfg.seed = seed
agent_cfg.seed = seed
log_root_path = os.path.abspath(os.path.join("logs", "rsl_rl", agent_cfg.experiment_name))
print(f"[INFO] Logging experiment in directory: {log_root_path}")
log_dir = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
print(f"Exact experiment name requested from command line: {log_dir}")
if agent_cfg.run_name:
log_dir += f"_{agent_cfg.run_name}"
log_dir = os.path.join(log_root_path, log_dir)
if isinstance(env_cfg, ManagerBasedRLEnvCfg):
env_cfg.export_io_descriptors = args_cli.export_io_descriptors
else:
logger.warning("IO descriptors are only supported for manager based RL environments.")
env_cfg.log_dir = log_dir
env = gym.make(args_cli.task, cfg=env_cfg, render_mode="rgb_array" if args_cli.video else None)
if isinstance(env.unwrapped, DirectMARLEnv):
env = multi_agent_to_single_agent(env)
if agent_cfg.resume or agent_cfg.algorithm.class_name == "Distillation":
resume_path = get_checkpoint_path(log_root_path, agent_cfg.load_run, agent_cfg.load_checkpoint)
if args_cli.video:
video_kwargs = {
"video_folder": os.path.join(log_dir, "videos", "train"),
"step_trigger": lambda step: step % args_cli.video_interval == 0,
"video_length": args_cli.video_length,
"disable_logger": True,
}
print("[INFO] Recording videos during training.")
print_dict(video_kwargs, nesting=4)
env = gym.wrappers.RecordVideo(env, **video_kwargs)
start_time = time.time()
env = LegacyRslRlVecEnvWrapper(env, clip_actions=agent_cfg.clip_actions)
legacy_agent_cfg = to_compatible_rsl_rl_cfg(agent_cfg)
if agent_cfg.class_name == "OnPolicyRunner":
runner = OnPolicyRunner(env, legacy_agent_cfg, log_dir=log_dir, device=agent_cfg.device)
elif agent_cfg.class_name == "DistillationRunner" and DistillationRunner is not None:
runner = DistillationRunner(env, legacy_agent_cfg, log_dir=log_dir, device=agent_cfg.device)
else:
raise ValueError(f"Unsupported runner class: {agent_cfg.class_name}")
if hasattr(runner, "add_git_repo_to_log"):
runner.add_git_repo_to_log(__file__)
if agent_cfg.resume or agent_cfg.algorithm.class_name == "Distillation":
print(f"[INFO]: Loading model checkpoint from: {resume_path}")
runner.load(resume_path)
dump_yaml(os.path.join(log_dir, "params", "env.yaml"), env_cfg)
dump_yaml(os.path.join(log_dir, "params", "agent.yaml"), agent_cfg)
runner.learn(num_learning_iterations=agent_cfg.max_iterations, init_at_random_ep_len=True)
final_path = os.path.join(log_dir, "model_final.pt")
runner.save(final_path)
print(f"Saved final checkpoint to: {final_path}")
try:
stackforce_export_policy_as_onnx(
runner.get_inference_policy(device=env.device),
env.get_observations(),
os.path.join(log_dir, "exported", "policies"),
)
except Exception as exc:
print(f"ONNX export skipped: {exc}")
print(f"Training time: {round(time.time() - start_time, 2)} seconds")
env.close()
if __name__ == "__main__":
main()
simulation_app.close()

View File

@ -0,0 +1,79 @@
#!/usr/bin/env bash
set -euo pipefail
# StackForce SimReady Isaac Lab / Isaac Sim environment bootstrap.
# Tested target: Isaac Sim 5.1.0, Isaac Lab v2.3.2, Python 3.11, Torch 2.7.0 cu128.
# Override defaults with: ENV_NAME=env_isaaclab INSTALL_ROOT=$HOME ./setup_stackforce_isaac_lab_sim_env.sh
ENV_NAME="${ENV_NAME:-env_isaaclab}"
INSTALL_ROOT="${INSTALL_ROOT:-$HOME}"
ISAACLAB_DIR="${ISAACLAB_DIR:-$INSTALL_ROOT/IsaacLab}"
LEGGED_GYM_EX_DIR="${LEGGED_GYM_EX_DIR:-$HOME/leggedgymex/LeggedGym-Ex}"
ISAACLAB_TAG="${ISAACLAB_TAG:-v2.3.2}"
if ! command -v conda >/dev/null 2>&1; then
echo "conda was not found. Install Miniconda/Anaconda first, then rerun this script." >&2
exit 1
fi
if ! command -v git >/dev/null 2>&1; then
echo "git was not found. Install git first, then rerun this script." >&2
exit 1
fi
CONDA_BASE="$(conda info --base)"
source "$CONDA_BASE/etc/profile.d/conda.sh"
if ! conda env list | awk '{print $1}' | grep -qx "$ENV_NAME"; then
conda create -n "$ENV_NAME" python=3.11 -y
fi
conda activate "$ENV_NAME"
python -m pip install --upgrade pip setuptools wheel
python -m pip install "isaacsim[all,extscache]==5.1.0" --extra-index-url https://pypi.nvidia.com
python -m pip install -U torch==2.7.0 torchvision==0.22.0 --index-url https://download.pytorch.org/whl/cu128
if [ ! -d "$ISAACLAB_DIR/.git" ]; then
mkdir -p "$(dirname "$ISAACLAB_DIR")"
git clone https://github.com/isaac-sim/IsaacLab.git "$ISAACLAB_DIR"
fi
cd "$ISAACLAB_DIR"
git fetch --tags
git checkout "$ISAACLAB_TAG"
./isaaclab.sh --install
./isaaclab.sh --install rsl_rl || true
# SimReady has been validated with the rsl_rl package bundled by LeggedGym-Ex.
if [ ! -d "$LEGGED_GYM_EX_DIR/.git" ]; then
mkdir -p "$(dirname "$LEGGED_GYM_EX_DIR")"
git clone https://github.com/lupinjia/LeggedGym-Ex.git "$LEGGED_GYM_EX_DIR"
fi
python -m pip uninstall -y rsl-rl rsl-rl-lib >/dev/null 2>&1 || true
python -m pip install -e "$LEGGED_GYM_EX_DIR" --no-deps
python - <<'PY'
import importlib.metadata as md
import sys
import torch
import rsl_rl
print("StackForce Isaac Lab / Isaac Sim environment is ready.")
print("python:", sys.version.split()[0])
print("torch:", torch.__version__)
for name in ("isaacsim", "isaaclab", "isaaclab_rl", "isaaclab_tasks"):
try:
print(f"{name}:", md.version(name))
except Exception as exc:
print(f"{name}: not found ({exc})")
print("rsl_rl path:", rsl_rl.__file__)
PY
echo ""
echo "Next step for a SimReady export:"
echo " conda activate $ENV_NAME"
echo " cd <exported_project>"
echo " python -m pip install -e source/<package_name>"
echo " python scripts/list_envs.py"
echo " python scripts/rsl_rl/train.py --task <TaskName> --headless --num_envs 64 --max_iterations 100"

View File

@ -0,0 +1,38 @@
import argparse
from isaaclab.app import AppLauncher
parser = argparse.ArgumentParser(description="Zero agent for StackForce Isaac Lab environments.")
parser.add_argument("--disable_fabric", action="store_true", default=False)
parser.add_argument("--num_envs", type=int, default=None)
parser.add_argument("--task", type=str, default=None)
AppLauncher.add_app_launcher_args(parser)
args_cli = parser.parse_args()
app_launcher = AppLauncher(args_cli)
simulation_app = app_launcher.app
import gymnasium as gym
import torch
from isaaclab_tasks.utils import parse_env_cfg
import stackforce_simready_2foot_lab.tasks # noqa: F401
def main():
env_cfg = parse_env_cfg(
args_cli.task, device=args_cli.device, num_envs=args_cli.num_envs, use_fabric=not args_cli.disable_fabric
)
env = gym.make(args_cli.task, cfg=env_cfg)
env.reset()
while simulation_app.is_running():
with torch.inference_mode():
actions = torch.zeros(env.action_space.shape, device=env.unwrapped.device)
env.step(actions)
env.close()
if __name__ == "__main__":
main()
simulation_app.close()

View File

@ -0,0 +1,3 @@
[build-system]
requires = ["setuptools>=61", "wheel"]
build-backend = "setuptools.build_meta"

View File

@ -0,0 +1,12 @@
from setuptools import find_packages, setup
setup(
name="stackforce_simready_2foot_lab",
version="0.1.0",
description="StackForce SimReady Isaac Lab export for Template-2foot-Direct-v0",
packages=find_packages(),
include_package_data=True,
install_requires=["psutil"],
python_requires=">=3.10",
)

View File

@ -0,0 +1,9 @@
Metadata-Version: 2.4
Name: stackforce_simready_2foot_lab
Version: 0.1.0
Summary: StackForce SimReady Isaac Lab export for Template-2foot-Direct-v0
Requires-Python: >=3.10
Requires-Dist: psutil
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

View File

@ -0,0 +1,16 @@
pyproject.toml
setup.py
stackforce_simready_2foot_lab/__init__.py
stackforce_simready_2foot_lab.egg-info/PKG-INFO
stackforce_simready_2foot_lab.egg-info/SOURCES.txt
stackforce_simready_2foot_lab.egg-info/dependency_links.txt
stackforce_simready_2foot_lab.egg-info/requires.txt
stackforce_simready_2foot_lab.egg-info/top_level.txt
stackforce_simready_2foot_lab/tasks/__init__.py
stackforce_simready_2foot_lab/tasks/direct/__init__.py
stackforce_simready_2foot_lab/tasks/direct/2foot/2foot_env.py
stackforce_simready_2foot_lab/tasks/direct/2foot/2foot_env_cfg.py
stackforce_simready_2foot_lab/tasks/direct/2foot/__init__.py
stackforce_simready_2foot_lab/tasks/direct/2foot/custom_rewards.py
stackforce_simready_2foot_lab/tasks/direct/2foot/agents/__init__.py
stackforce_simready_2foot_lab/tasks/direct/2foot/agents/rsl_rl_ppo_cfg.py

View File

@ -0,0 +1 @@
stackforce_simready_2foot_lab

View File

@ -0,0 +1 @@
from . import tasks

View File

@ -0,0 +1,52 @@
#usda 1.0
(
customLayerData = {
string creator = "URDF USD Converter v0.1.3"
}
defaultPrim = "tn__2foot_"
doc = """Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\tmpf1f0lj99\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\usdex_2foot\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\temp_2foot\\2foot.usd
Generated from Composed Stage of root layer C:\\Users\\ZhenaiWin\\Documents\\Bot3dData\\2foot\\urdf\\2foot\\payloads\\base.usd
"""
kilogramsPerUnit = 1
metersPerUnit = 1
upAxis = "Z"
)
def Xform "tn__2foot_" (
prepend references = @./payloads/base.usda@
variants = {
string Physics = "physx"
}
append variantSets = "Physics"
)
{
variantSet "Physics" = {
"mujoco" (
prepend payload = @./payloads/Physics/mujoco.usda@
) {
}
"none" {
}
"physics" (
prepend payload = @./payloads/Physics/physics.usda@
) {
}
"physx" (
prepend payload = @./payloads/Physics/physx.usda@
) {
}
}
}

View File

@ -0,0 +1,257 @@
#usda 1.0
(
customLayerData = {
string creator = "URDF USD Converter v0.1.3"
}
defaultPrim = "tn__2foot_"
doc = """Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\tmpf1f0lj99\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\usdex_2foot\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\temp_2foot\\2foot.usd
Generated from Composed Stage of root layer C:\\Users\\ZhenaiWin\\Documents\\Bot3dData\\2foot\\urdf\\2foot\\payloads\\base.usd
"""
kilogramsPerUnit = 1
metersPerUnit = 1
subLayers = [
@./physics.usda@
]
upAxis = "Z"
)
over "tn__2foot_"
{
over "Physics"
{
def MjcActuator "jlf0_link_actuator"
{
uniform double mjc:forceRange:max = inf
uniform double mjc:forceRange:min = -inf
custom rel mjc:target
prepend rel mjc:target = </tn__2foot_/Physics/jlf0_link>
}
def MjcActuator "jlf1_link_actuator"
{
uniform double mjc:forceRange:max = inf
uniform double mjc:forceRange:min = -inf
custom rel mjc:target
prepend rel mjc:target = </tn__2foot_/Physics/jlf1_link>
}
def MjcActuator "jlf2_link_actuator"
{
uniform double mjc:forceRange:max = inf
uniform double mjc:forceRange:min = -inf
custom rel mjc:target
prepend rel mjc:target = </tn__2foot_/Physics/jlf2_link>
}
def MjcActuator "jlf3_link_actuator"
{
uniform double mjc:forceRange:max = inf
uniform double mjc:forceRange:min = -inf
custom rel mjc:target
prepend rel mjc:target = </tn__2foot_/Physics/jlf3_link>
}
def MjcActuator "jrf0_link_actuator"
{
uniform double mjc:forceRange:max = inf
uniform double mjc:forceRange:min = -inf
custom rel mjc:target
prepend rel mjc:target = </tn__2foot_/Physics/jrf0_link>
}
def MjcActuator "jrf1_link_actuator"
{
uniform double mjc:forceRange:max = inf
uniform double mjc:forceRange:min = -inf
custom rel mjc:target
prepend rel mjc:target = </tn__2foot_/Physics/jrf1_link>
}
def MjcActuator "jrf2_link_actuator"
{
uniform double mjc:forceRange:max = inf
uniform double mjc:forceRange:min = -inf
custom rel mjc:target
prepend rel mjc:target = </tn__2foot_/Physics/jrf2_link>
}
def MjcActuator "jrf3_link_actuator"
{
uniform double mjc:forceRange:max = inf
uniform double mjc:forceRange:min = -inf
custom rel mjc:target
prepend rel mjc:target = </tn__2foot_/Physics/jrf3_link>
}
over "root_joint"
{
}
over "jlf0_link" (
delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
}
over "jlf1_link" (
delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
}
over "jlf2_link" (
delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
}
over "jlf3_link" (
delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
}
over "jrf0_link" (
delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
}
over "jrf1_link" (
delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
}
over "jrf2_link" (
delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
}
over "jrf3_link" (
delete apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
}
}
over "Geometry"
{
over "head_link"
{
over "lf0_link"
{
over "lf1_link"
{
over "lf2_link"
{
over "lf3_link"
{
over "lf3_link"
{
}
over "lf3_link_1"
{
}
}
over "lf2_link"
{
}
over "lf2_link_1"
{
}
}
over "lf1_link"
{
}
over "lf1_link_1"
{
}
}
over "lf0_link"
{
}
over "lf0_link_1"
{
}
}
over "rf0_link"
{
over "rf1_link"
{
over "rf2_link"
{
over "rf3_link"
{
over "rf3_link"
{
}
over "rf3_link_1"
{
}
}
over "rf2_link"
{
}
over "rf2_link_1"
{
}
}
over "rf1_link"
{
}
over "rf1_link_1"
{
}
}
over "rf0_link"
{
}
over "rf0_link_1"
{
}
}
over "head_link"
{
}
over "head_link_1"
{
}
}
}
over "Materials"
{
}
over "VisualMaterials"
{
}
}

View File

@ -0,0 +1,310 @@
#usda 1.0
(
customLayerData = {
string creator = "URDF USD Converter v0.1.3"
}
defaultPrim = "tn__2foot_"
doc = """Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\tmpf1f0lj99\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\usdex_2foot\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\temp_2foot\\2foot.usd
Generated from Composed Stage of root layer C:\\Users\\ZhenaiWin\\Documents\\Bot3dData\\2foot\\urdf\\2foot\\payloads\\base.usd
"""
kilogramsPerUnit = 1
metersPerUnit = 1
upAxis = "Z"
)
over "tn__2foot_"
{
over "Geometry"
{
over "head_link" (
prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsArticulationRootAPI", "NewtonArticulationRootAPI", "PhysicsMassAPI"]
)
{
bool newton:selfCollisionEnabled = 0
point3f physics:centerOfMass = (0.006379277, 0.00008368386, 0.050267912)
float3 physics:diagonalInertia = (0.00003176899, 0.00009209173, 0.00012000061)
float physics:mass = 0.10414764
quatf physics:principalAxes = (0.7195886, -0.0010949927, 0.6943998, 0.00012781573)
over "lf0_link" (
prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"]
)
{
point3f physics:centerOfMass = (0.0000025034674, -0.0039915238, -0.013605572)
float3 physics:diagonalInertia = (0.0000014361923, 0.000001991647, 0.0000021335975)
float physics:mass = 0.01552463
quatf physics:principalAxes = (0.5896363, 0.3902982, 0.39247534, 0.58818316)
over "lf1_link" (
prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"]
)
{
point3f physics:centerOfMass = (0.0000029169641, 0.004390377, -0.029671295)
float3 physics:diagonalInertia = (9.233895e-7, 0.0000027214292, 0.000002921432)
float physics:mass = 0.013323923
quatf physics:principalAxes = (0.49527994, 0.5046167, 0.5034881, 0.49654758)
over "lf2_link" (
prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"]
)
{
point3f physics:centerOfMass = (0.0000024373737, 0.0036361304, -0.04257328)
float3 physics:diagonalInertia = (0.0000010902555, 0.0000053542444, 0.0000057132534)
float physics:mass = 0.015945608
quatf physics:principalAxes = (0.4984956, 0.5014754, 0.50083035, 0.49919286)
over "lf3_link" (
prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"]
)
{
point3f physics:centerOfMass = (-4.822531e-16, -0.00045139418, -0.019824568)
float3 physics:diagonalInertia = (0.0000031820964, 0.0000064676433, 0.0000073290707)
float physics:mass = 0.019290663
quatf physics:principalAxes = (0.9876391, 0.1567448, -2.5980806e-16, 4.4737337e-16)
}
}
}
}
over "rf0_link" (
prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"]
)
{
point3f physics:centerOfMass = (-0.0000025034674, 0.0039915238, -0.013605572)
float3 physics:diagonalInertia = (0.0000014361923, 0.000001991647, 0.0000021335975)
float physics:mass = 0.01552463
quatf physics:principalAxes = (0.39247534, 0.58818316, 0.5896363, 0.3902982)
over "rf1_link" (
prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"]
)
{
point3f physics:centerOfMass = (-0.0000029169641, -0.004390377, -0.029671295)
float3 physics:diagonalInertia = (9.233895e-7, 0.0000027214292, 0.000002921432)
float physics:mass = 0.013323923
quatf physics:principalAxes = (0.5034881, 0.49654758, 0.49527994, 0.5046167)
over "rf2_link" (
prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"]
)
{
point3f physics:centerOfMass = (-0.0000024373737, -0.0036361304, -0.04257328)
float3 physics:diagonalInertia = (0.0000010902555, 0.0000053542444, 0.0000057132534)
float physics:mass = 0.015945608
quatf physics:principalAxes = (0.50083035, 0.49919286, 0.4984956, 0.5014754)
over "rf3_link" (
prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysicsMassAPI"]
)
{
point3f physics:centerOfMass = (8.187895e-16, 0.00045139418, -0.019824568)
float3 physics:diagonalInertia = (0.0000031820964, 0.0000064676433, 0.0000073290707)
float physics:mass = 0.019290663
quatf physics:principalAxes = (0.9876391, -0.1567448, -1.6753745e-16, 1.3454567e-15)
}
}
}
}
}
}
over "Physics"
{
def PhysicsRevoluteJoint "jlf0_link" (
prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
float drive:angular:physics:damping = 1
float drive:angular:physics:stiffness = 1
uniform token drive:angular:physics:type = "force"
uniform token physics:axis = "Z"
custom rel physics:body0
prepend rel physics:body0 = </tn__2foot_/Geometry/head_link>
custom rel physics:body1
prepend rel physics:body1 = </tn__2foot_/Geometry/head_link/lf0_link>
point3f physics:localPos0 = (-0.0031441, 0.025688, -0.006475)
point3f physics:localPos1 = (0, 0, 0)
quatf physics:localRot0 = (0, -1, 0, 0)
quatf physics:localRot1 = (0, -1, 0, 0)
float physics:lowerLimit = 0
float physics:upperLimit = 0
custom float urdf:limit:effort = 0
custom float urdf:limit:velocity = 0
}
def PhysicsRevoluteJoint "jlf1_link" (
prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
float drive:angular:physics:damping = 0
float drive:angular:physics:stiffness = 0
uniform token drive:angular:physics:type = "force"
uniform token physics:axis = "Y"
custom rel physics:body0
prepend rel physics:body0 = </tn__2foot_/Geometry/head_link/lf0_link>
custom rel physics:body1
prepend rel physics:body1 = </tn__2foot_/Geometry/head_link/lf0_link/lf1_link>
point3f physics:localPos0 = (0.000097027, 0.011975, -0.012388)
point3f physics:localPos1 = (0, 0, 0)
quatf physics:localRot0 = (0, -1, 0, 0)
quatf physics:localRot1 = (0, -1, 0, 0)
float physics:lowerLimit = 0
float physics:upperLimit = 0
custom float urdf:limit:effort = 0
custom float urdf:limit:velocity = 0
}
def PhysicsRevoluteJoint "jlf2_link" (
prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
float drive:angular:physics:damping = 0
float drive:angular:physics:stiffness = 0
uniform token drive:angular:physics:type = "force"
uniform token physics:axis = "Y"
custom rel physics:body0
prepend rel physics:body0 = </tn__2foot_/Geometry/head_link/lf0_link/lf1_link>
custom rel physics:body1
prepend rel physics:body1 = </tn__2foot_/Geometry/head_link/lf0_link/lf1_link/lf2_link>
point3f physics:localPos0 = (0.000097027, -0.008475, -0.040938)
point3f physics:localPos1 = (0, 0, 0)
quatf physics:localRot0 = (1, 0, 0, 0)
quatf physics:localRot1 = (1, 0, 0, 0)
float physics:lowerLimit = 0
float physics:upperLimit = 0
custom float urdf:limit:effort = 0
custom float urdf:limit:velocity = 0
}
def PhysicsRevoluteJoint "jlf3_link" (
prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
float drive:angular:physics:damping = 0
float drive:angular:physics:stiffness = 0
uniform token drive:angular:physics:type = "force"
uniform token physics:axis = "Y"
custom rel physics:body0
prepend rel physics:body0 = </tn__2foot_/Geometry/head_link/lf0_link/lf1_link/lf2_link>
custom rel physics:body1
prepend rel physics:body1 = </tn__2foot_/Geometry/head_link/lf0_link/lf1_link/lf2_link/lf3_link>
point3f physics:localPos0 = (0.000097027, -0.006475, -0.060937)
point3f physics:localPos1 = (0, 0, 0)
quatf physics:localRot0 = (0, -1, 0, 0)
quatf physics:localRot1 = (0, -1, 0, 0)
float physics:lowerLimit = 0
float physics:upperLimit = 0
custom float urdf:limit:effort = 0
custom float urdf:limit:velocity = 0
}
def PhysicsRevoluteJoint "jrf0_link" (
prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
float drive:angular:physics:damping = 0
float drive:angular:physics:stiffness = 0
uniform token drive:angular:physics:type = "force"
uniform token physics:axis = "Z"
custom rel physics:body0
prepend rel physics:body0 = </tn__2foot_/Geometry/head_link>
custom rel physics:body1
prepend rel physics:body1 = </tn__2foot_/Geometry/head_link/rf0_link>
point3f physics:localPos0 = (-0.0033382, -0.025687, -0.006475)
point3f physics:localPos1 = (0, 0, 0)
quatf physics:localRot0 = (0, -1, 0, 0)
quatf physics:localRot1 = (0, -1, 0, 0)
float physics:lowerLimit = 0
float physics:upperLimit = 0
custom float urdf:limit:effort = 0
custom float urdf:limit:velocity = 0
}
def PhysicsRevoluteJoint "jrf1_link" (
prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
float drive:angular:physics:damping = 0
float drive:angular:physics:stiffness = 0
uniform token drive:angular:physics:type = "force"
uniform token physics:axis = "Y"
custom rel physics:body0
prepend rel physics:body0 = </tn__2foot_/Geometry/head_link/rf0_link>
custom rel physics:body1
prepend rel physics:body1 = </tn__2foot_/Geometry/head_link/rf0_link/rf1_link>
point3f physics:localPos0 = (-0.000097027, -0.011975, -0.012388)
point3f physics:localPos1 = (0, 0, 0)
quatf physics:localRot0 = (1, 0, 0, 0)
quatf physics:localRot1 = (1, 0, 0, 0)
float physics:lowerLimit = 0
float physics:upperLimit = 0
custom float urdf:limit:effort = 0
custom float urdf:limit:velocity = 0
}
def PhysicsRevoluteJoint "jrf2_link" (
prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
float drive:angular:physics:damping = 0
float drive:angular:physics:stiffness = 0
uniform token drive:angular:physics:type = "force"
uniform token physics:axis = "Y"
custom rel physics:body0
prepend rel physics:body0 = </tn__2foot_/Geometry/head_link/rf0_link/rf1_link>
custom rel physics:body1
prepend rel physics:body1 = </tn__2foot_/Geometry/head_link/rf0_link/rf1_link/rf2_link>
point3f physics:localPos0 = (-0.000097027, 0.008475, -0.040937)
point3f physics:localPos1 = (0, 0, 0)
quatf physics:localRot0 = (1, 0, 0, 0)
quatf physics:localRot1 = (1, 0, 0, 0)
float physics:lowerLimit = 0
float physics:upperLimit = 0
custom float urdf:limit:effort = 0
custom float urdf:limit:velocity = 0
}
def PhysicsRevoluteJoint "jrf3_link" (
prepend apiSchemas = ["PhysicsDriveAPI:angular", "PhysicsJointStateAPI:angular"]
)
{
float drive:angular:physics:damping = 0
float drive:angular:physics:stiffness = 0
uniform token drive:angular:physics:type = "force"
uniform token physics:axis = "Y"
custom rel physics:body0
prepend rel physics:body0 = </tn__2foot_/Geometry/head_link/rf0_link/rf1_link/rf2_link>
custom rel physics:body1
prepend rel physics:body1 = </tn__2foot_/Geometry/head_link/rf0_link/rf1_link/rf2_link/rf3_link>
point3f physics:localPos0 = (-0.000097027, 0.006475, -0.060938)
point3f physics:localPos1 = (0, 0, 0)
quatf physics:localRot0 = (1, 0, 0, 0)
quatf physics:localRot1 = (1, 0, 0, 0)
float physics:lowerLimit = 0
float physics:upperLimit = 0
custom float urdf:limit:effort = 0
custom float urdf:limit:velocity = 0
}
def PhysicsFixedJoint "root_joint"
{
custom rel physics:body0
prepend rel physics:body0 = </tn__2foot_>
custom rel physics:body1
prepend rel physics:body1 = </tn__2foot_/Geometry/head_link>
point3f physics:localPos0 = (0, 0, 0)
point3f physics:localPos1 = (0, 0, 0)
quatf physics:localRot0 = (1, 0, 0, 0)
quatf physics:localRot1 = (1, 0, 0, 0)
}
}
}

View File

@ -0,0 +1,79 @@
#usda 1.0
(
customLayerData = {
string creator = "URDF USD Converter v0.1.3"
}
defaultPrim = "tn__2foot_"
doc = """Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\tmpf1f0lj99\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\usdex_2foot\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\temp_2foot\\2foot.usd
Generated from Composed Stage of root layer C:\\Users\\ZhenaiWin\\Documents\\Bot3dData\\2foot\\urdf\\2foot\\payloads\\base.usd
"""
kilogramsPerUnit = 1
metersPerUnit = 1
subLayers = [
@./physics.usda@
]
upAxis = "Z"
)
over "tn__2foot_"
{
over "Physics"
{
over "jlf0_link" (
prepend apiSchemas = ["PhysxJointAPI"]
)
{
}
over "jlf1_link" (
prepend apiSchemas = ["PhysxJointAPI"]
)
{
}
over "jlf2_link" (
prepend apiSchemas = ["PhysxJointAPI"]
)
{
}
over "jlf3_link" (
prepend apiSchemas = ["PhysxJointAPI"]
)
{
}
over "jrf0_link" (
prepend apiSchemas = ["PhysxJointAPI"]
)
{
}
over "jrf1_link" (
prepend apiSchemas = ["PhysxJointAPI"]
)
{
}
over "jrf2_link" (
prepend apiSchemas = ["PhysxJointAPI"]
)
{
}
over "jrf3_link" (
prepend apiSchemas = ["PhysxJointAPI"]
)
{
}
}
}

View File

@ -0,0 +1,326 @@
#usda 1.0
(
customLayerData = {
string creator = "URDF USD Converter v0.1.3"
}
defaultPrim = "tn__2foot_"
doc = """Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\tmpf1f0lj99\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\usdex_2foot\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\temp_2foot\\2foot.usd
Generated from Composed Stage of root layer C:\\Users\\ZhenaiWin\\Documents\\Bot3dData\\2foot\\urdf\\2foot\\payloads\\base.usd
"""
kilogramsPerUnit = 1
metersPerUnit = 1
subLayers = [
@./robot.usda@
]
upAxis = "Z"
)
def Xform "tn__2foot_" (
prepend apiSchemas = ["GeomModelAPI"]
assetInfo = {
string name = "2foot"
}
displayName = "2foot"
kind = "component"
)
{
float3[] extentsHint = [(-0.03612928, -0.058187, -0.147238), (0.03091089, 0.058188, 0.122), (3.4028235e38, 3.4028235e38, 3.4028235e38), (-3.4028235e38, -3.4028235e38, -3.4028235e38), (3.4028235e38, 3.4028235e38, 3.4028235e38), (-3.4028235e38, -3.4028235e38, -3.4028235e38), (-0.03612928, -0.058187, -0.147238), (0.03091089, 0.058188, 0.122)]
def Scope "Materials"
{
}
def Scope "Geometry"
{
def Xform "head_link"
{
def Xform "head_link" (
instanceable = true
prepend references = @./instances.usda@</Instances/head_link>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
def Xform "lf0_link"
{
quatf xformOp:orient = (1, 0, 0, 0)
float3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (-0.0031441, 0.025688, -0.006475)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
def Xform "lf0_link" (
instanceable = true
prepend references = @./instances.usda@</Instances/lf0_link>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
def Xform "lf1_link"
{
quatf xformOp:orient = (1, 0, 0, 0)
float3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0.000097027, 0.011975, -0.012388)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
def Xform "lf1_link" (
instanceable = true
prepend references = @./instances.usda@</Instances/lf1_link>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
def Xform "lf2_link"
{
quatf xformOp:orient = (1, 0, 0, 0)
float3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0.000097027, -0.008475, -0.040938)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
def Xform "lf2_link" (
instanceable = true
prepend references = @./instances.usda@</Instances/lf2_link>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
def Xform "lf3_link"
{
quatf xformOp:orient = (1, 0, 0, 0)
float3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0.000097027, -0.006475, -0.060937)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
def Xform "lf3_link" (
instanceable = true
prepend references = @./instances.usda@</Instances/lf3_link>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
def Xform "lf3_link_1" (
displayName = "lf3_link"
instanceable = true
prepend references = @./instances.usda@</Instances/lf3_link_1>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
}
def Xform "lf2_link_1" (
displayName = "lf2_link"
instanceable = true
prepend references = @./instances.usda@</Instances/lf2_link_1>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
}
def Xform "lf1_link_1" (
displayName = "lf1_link"
instanceable = true
prepend references = @./instances.usda@</Instances/lf1_link_1>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
}
def Xform "lf0_link_1" (
displayName = "lf0_link"
instanceable = true
prepend references = @./instances.usda@</Instances/lf0_link_1>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
}
def Xform "rf0_link"
{
quatf xformOp:orient = (1, 0, 0, 0)
float3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (-0.0033382, -0.025687, -0.006475)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
def Xform "rf0_link" (
instanceable = true
prepend references = @./instances.usda@</Instances/rf0_link>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
def Xform "rf1_link"
{
quatf xformOp:orient = (1, 0, 0, 0)
float3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (-0.000097027, -0.011975, -0.012388)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
def Xform "rf1_link" (
instanceable = true
prepend references = @./instances.usda@</Instances/rf1_link>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
def Xform "rf2_link"
{
quatf xformOp:orient = (1, 0, 0, 0)
float3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (-0.000097027, 0.008475, -0.040937)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
def Xform "rf2_link" (
instanceable = true
prepend references = @./instances.usda@</Instances/rf2_link>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
def Xform "rf3_link"
{
quatf xformOp:orient = (1, 0, 0, 0)
float3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (-0.000097027, 0.006475, -0.060938)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
def Xform "rf3_link" (
instanceable = true
prepend references = @./instances.usda@</Instances/rf3_link>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
def Xform "rf3_link_1" (
displayName = "rf3_link"
instanceable = true
prepend references = @./instances.usda@</Instances/rf3_link_1>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
}
def Xform "rf2_link_1" (
displayName = "rf2_link"
instanceable = true
prepend references = @./instances.usda@</Instances/rf2_link_1>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
}
def Xform "rf1_link_1" (
displayName = "rf1_link"
instanceable = true
prepend references = @./instances.usda@</Instances/rf1_link_1>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
}
def Xform "rf0_link_1" (
displayName = "rf0_link"
instanceable = true
prepend references = @./instances.usda@</Instances/rf0_link_1>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
}
def Xform "head_link_1" (
displayName = "head_link"
instanceable = true
prepend references = @./instances.usda@</Instances/head_link_1>
)
{
quatd xformOp:orient = (1, 0, 0, 0)
double3 xformOp:scale = (1, 1, 1)
double3 xformOp:translate = (0, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
}
}
}
def Scope "Physics"
{
}
def Scope "VisualMaterials"
{
}
}

View File

@ -0,0 +1,348 @@
#usda 1.0
(
customLayerData = {
string creator = "URDF USD Converter v0.1.3"
}
doc = """Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\tmpf1f0lj99\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\usdex_2foot\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\temp_2foot\\2foot.usd
Generated from Composed Stage of root layer C:\\Users\\ZhenaiWin\\Documents\\Bot3dData\\2foot\\urdf\\2foot\\payloads\\base.usd
"""
kilogramsPerUnit = 1
metersPerUnit = 1
upAxis = "Z"
)
def Scope "Instances"
{
def Xform "head_link" (
prepend references = @./geometries.usd@</Geometries/head_link>
)
{
over "head_link" (
apiSchemas = ["MaterialBindingAPI"]
)
{
custom rel material:binding
prepend rel material:binding = </Instances/head_link/VisualMaterials/material_1>
}
def Scope "VisualMaterials"
{
def Material "material_1" (
instanceable = true
prepend references = @./materials.usda@</Materials/material_1>
)
{
}
}
}
def Xform "head_link_1" (
prepend references = @./geometries.usd@</Geometries/head_link>
)
{
over "head_link" (
apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"]
)
{
token physics:approximation = "convexHull"
token purpose = "guide"
}
}
def Xform "lf0_link" (
prepend references = @./geometries.usd@</Geometries/lf0_link>
)
{
over "lf0_link" (
apiSchemas = ["MaterialBindingAPI"]
)
{
custom rel material:binding
prepend rel material:binding = </Instances/lf0_link/VisualMaterials/material_2>
}
def Scope "VisualMaterials"
{
def Material "material_2" (
instanceable = true
prepend references = @./materials.usda@</Materials/material_1>
)
{
}
}
}
def Xform "lf0_link_1" (
prepend references = @./geometries.usd@</Geometries/lf0_link>
)
{
over "lf0_link" (
apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"]
)
{
token physics:approximation = "convexHull"
token purpose = "guide"
}
}
def Xform "lf1_link" (
prepend references = @./geometries.usd@</Geometries/lf1_link>
)
{
over "lf1_link" (
apiSchemas = ["MaterialBindingAPI"]
)
{
custom rel material:binding
prepend rel material:binding = </Instances/lf1_link/VisualMaterials/material_3>
}
def Scope "VisualMaterials"
{
def Material "material_3" (
instanceable = true
prepend references = @./materials.usda@</Materials/material_1>
)
{
}
}
}
def Xform "lf1_link_1" (
prepend references = @./geometries.usd@</Geometries/lf1_link>
)
{
over "lf1_link" (
apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"]
)
{
token physics:approximation = "convexHull"
token purpose = "guide"
}
}
def Xform "lf2_link" (
prepend references = @./geometries.usd@</Geometries/lf2_link>
)
{
over "lf2_link" (
apiSchemas = ["MaterialBindingAPI"]
)
{
custom rel material:binding
prepend rel material:binding = </Instances/lf2_link/VisualMaterials/material_4>
}
def Scope "VisualMaterials"
{
def Material "material_4" (
instanceable = true
prepend references = @./materials.usda@</Materials/material_1>
)
{
}
}
}
def Xform "lf2_link_1" (
prepend references = @./geometries.usd@</Geometries/lf2_link>
)
{
over "lf2_link" (
apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"]
)
{
token physics:approximation = "convexHull"
token purpose = "guide"
}
}
def Xform "lf3_link" (
prepend references = @./geometries.usd@</Geometries/lf3_link>
)
{
over "lf3_link" (
apiSchemas = ["MaterialBindingAPI"]
)
{
custom rel material:binding
prepend rel material:binding = </Instances/lf3_link/VisualMaterials/material_5>
}
def Scope "VisualMaterials"
{
def Material "material_5" (
instanceable = true
prepend references = @./materials.usda@</Materials/material_1>
)
{
}
}
}
def Xform "lf3_link_1" (
prepend references = @./geometries.usd@</Geometries/lf3_link>
)
{
over "lf3_link" (
apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"]
)
{
token physics:approximation = "convexHull"
token purpose = "guide"
}
}
def Xform "rf0_link" (
prepend references = @./geometries.usd@</Geometries/rf0_link>
)
{
over "rf0_link" (
apiSchemas = ["MaterialBindingAPI"]
)
{
custom rel material:binding
prepend rel material:binding = </Instances/rf0_link/VisualMaterials/material_6>
}
def Scope "VisualMaterials"
{
def Material "material_6" (
instanceable = true
prepend references = @./materials.usda@</Materials/material_1>
)
{
}
}
}
def Xform "rf0_link_1" (
prepend references = @./geometries.usd@</Geometries/rf0_link>
)
{
over "rf0_link" (
apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"]
)
{
token physics:approximation = "convexHull"
token purpose = "guide"
}
}
def Xform "rf1_link" (
prepend references = @./geometries.usd@</Geometries/rf1_link>
)
{
over "rf1_link" (
apiSchemas = ["MaterialBindingAPI"]
)
{
custom rel material:binding
prepend rel material:binding = </Instances/rf1_link/VisualMaterials/material_7>
}
def Scope "VisualMaterials"
{
def Material "material_7" (
instanceable = true
prepend references = @./materials.usda@</Materials/material_1>
)
{
}
}
}
def Xform "rf1_link_1" (
prepend references = @./geometries.usd@</Geometries/rf1_link>
)
{
over "rf1_link" (
apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"]
)
{
token physics:approximation = "convexHull"
token purpose = "guide"
}
}
def Xform "rf2_link" (
prepend references = @./geometries.usd@</Geometries/rf2_link>
)
{
over "rf2_link" (
apiSchemas = ["MaterialBindingAPI"]
)
{
custom rel material:binding
prepend rel material:binding = </Instances/rf2_link/VisualMaterials/material_8>
}
def Scope "VisualMaterials"
{
def Material "material_8" (
instanceable = true
prepend references = @./materials.usda@</Materials/material_1>
)
{
}
}
}
def Xform "rf2_link_1" (
prepend references = @./geometries.usd@</Geometries/rf2_link>
)
{
over "rf2_link" (
apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"]
)
{
token physics:approximation = "convexHull"
token purpose = "guide"
}
}
def Xform "rf3_link" (
prepend references = @./geometries.usd@</Geometries/rf3_link>
)
{
over "rf3_link" (
apiSchemas = ["MaterialBindingAPI"]
)
{
custom rel material:binding
prepend rel material:binding = </Instances/rf3_link/VisualMaterials/material_9>
}
def Scope "VisualMaterials"
{
def Material "material_9" (
instanceable = true
prepend references = @./materials.usda@</Materials/material_1>
)
{
}
}
}
def Xform "rf3_link_1" (
prepend references = @./geometries.usd@</Geometries/rf3_link>
)
{
over "rf3_link" (
apiSchemas = ["PhysicsCollisionAPI", "NewtonCollisionAPI", "PhysicsMeshCollisionAPI", "NewtonMeshCollisionAPI"]
)
{
token physics:approximation = "convexHull"
token purpose = "guide"
}
}
}

View File

@ -0,0 +1,57 @@
#usda 1.0
(
customLayerData = {
string creator = "URDF USD Converter v0.1.3"
}
doc = """Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\tmpf1f0lj99\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\usdex_2foot\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\temp_2foot\\2foot.usd
Generated from Composed Stage of root layer C:\\Users\\ZhenaiWin\\Documents\\Bot3dData\\2foot\\urdf\\2foot\\payloads\\base.usd
"""
kilogramsPerUnit = 1
metersPerUnit = 1
upAxis = "Z"
)
def Scope "Materials"
{
def Material "material_1"
{
color3f inputs:diffuseColor = (1, 1, 1)
float inputs:metallic = 0
float inputs:opacity = 1
float inputs:roughness = 0.5
token inputs:wrapMode = "repeat"
token outputs:displacement (
displayGroup = "Outputs"
)
prepend token outputs:displacement.connect = </Materials/material_1/PreviewSurface.outputs:displacement>
token outputs:surface (
displayGroup = "Outputs"
)
prepend token outputs:surface.connect = </Materials/material_1/PreviewSurface.outputs:surface>
token outputs:volume (
displayGroup = "Outputs"
)
def Shader "PreviewSurface" (
apiSchemas = ["NodeDefAPI"]
)
{
token info:id = "UsdPreviewSurface"
prepend color3f inputs:diffuseColor.connect = </Materials/material_1.inputs:diffuseColor>
prepend float inputs:metallic.connect = </Materials/material_1.inputs:metallic>
prepend float inputs:opacity.connect = </Materials/material_1.inputs:opacity>
prepend float inputs:roughness.connect = </Materials/material_1.inputs:roughness>
token outputs:displacement
token outputs:surface
}
}
}

View File

@ -0,0 +1,155 @@
#usda 1.0
(
customLayerData = {
string creator = "URDF USD Converter v0.1.3"
}
defaultPrim = "tn__2foot_"
doc = """Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\tmpf1f0lj99\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\usdex_2foot\\2foot.usdc
Generated from Composed Stage of root layer C:\\Users\\ZHENAI~1\\AppData\\Local\\Temp\\urdf_import_2foot_b4o7puoa\\temp_2foot\\2foot.usd
"""
kilogramsPerUnit = 1
metersPerUnit = 1
upAxis = "Z"
)
over "tn__2foot_" (
prepend apiSchemas = ["IsaacRobotAPI"]
)
{
prepend rel isaac:physics:robotJoints = [
</tn__2foot_/Physics/root_joint>,
</tn__2foot_/Physics/jlf0_link>,
</tn__2foot_/Physics/jrf0_link>,
</tn__2foot_/Physics/jlf1_link>,
</tn__2foot_/Physics/jlf2_link>,
</tn__2foot_/Physics/jlf3_link>,
</tn__2foot_/Physics/jrf1_link>,
</tn__2foot_/Physics/jrf2_link>,
</tn__2foot_/Physics/jrf3_link>,
]
prepend rel isaac:physics:robotLinks = [
</tn__2foot_/Geometry/head_link>,
</tn__2foot_/Geometry/head_link/lf0_link>,
</tn__2foot_/Geometry/head_link/lf0_link/lf1_link>,
</tn__2foot_/Geometry/head_link/lf0_link/lf1_link/lf2_link>,
</tn__2foot_/Geometry/head_link/lf0_link/lf1_link/lf2_link/lf3_link>,
</tn__2foot_/Geometry/head_link/rf0_link>,
</tn__2foot_/Geometry/head_link/rf0_link/rf1_link>,
</tn__2foot_/Geometry/head_link/rf0_link/rf1_link/rf2_link>,
</tn__2foot_/Geometry/head_link/rf0_link/rf1_link/rf2_link/rf3_link>,
]
token isaac:robotType = "Default"
over "Geometry"
{
over "head_link" (
prepend apiSchemas = ["IsaacLinkAPI"]
)
{
over "lf0_link" (
prepend apiSchemas = ["IsaacLinkAPI"]
)
{
over "lf1_link" (
prepend apiSchemas = ["IsaacLinkAPI"]
)
{
over "lf2_link" (
prepend apiSchemas = ["IsaacLinkAPI"]
)
{
over "lf3_link" (
prepend apiSchemas = ["IsaacLinkAPI"]
)
{
}
}
}
}
over "rf0_link" (
prepend apiSchemas = ["IsaacLinkAPI"]
)
{
over "rf1_link" (
prepend apiSchemas = ["IsaacLinkAPI"]
)
{
over "rf2_link" (
prepend apiSchemas = ["IsaacLinkAPI"]
)
{
over "rf3_link" (
prepend apiSchemas = ["IsaacLinkAPI"]
)
{
}
}
}
}
}
}
over "Physics"
{
over "root_joint" (
prepend apiSchemas = ["IsaacJointAPI"]
)
{
}
over "jlf0_link" (
prepend apiSchemas = ["IsaacJointAPI"]
)
{
}
over "jlf1_link" (
prepend apiSchemas = ["IsaacJointAPI"]
)
{
}
over "jlf2_link" (
prepend apiSchemas = ["IsaacJointAPI"]
)
{
}
over "jlf3_link" (
prepend apiSchemas = ["IsaacJointAPI"]
)
{
}
over "jrf0_link" (
prepend apiSchemas = ["IsaacJointAPI"]
)
{
}
over "jrf1_link" (
prepend apiSchemas = ["IsaacJointAPI"]
)
{
}
over "jrf2_link" (
prepend apiSchemas = ["IsaacJointAPI"]
)
{
}
over "jrf3_link" (
prepend apiSchemas = ["IsaacJointAPI"]
)
{
}
}
}

View File

@ -0,0 +1,511 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This URDF was automatically created by SolidWorks to URDF Exporter! Originally created by Stephen Brawner (brawner@gmail.com)
Commit Version: 1.6.0-4-g7f85cfe Build Version: 1.6.7995.38578
For more information, please see http://wiki.ros.org/sw_urdf_exporter -->
<robot
name="2foot">
<link
name="head_link">
<inertial>
<origin
xyz="0.00637927718522201 8.36838553548436E-05 0.0502679117290854"
rpy="0 0 0" />
<mass
value="0.104147639434427" />
<inertia
ixx="0.000119888626287878"
ixy="4.26649795023379E-08"
ixz="-3.14056079328627E-06"
iyy="9.2091610344693E-05"
iyz="1.01375294153974E-07"
izz="3.18810914232645E-05" />
</inertial>
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="../meshes/head_link.STL" />
</geometry>
<material
name="">
<color
rgba="1 1 1 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="../meshes/head_link.STL" />
</geometry>
</collision>
</link>
<link
name="lf0_link">
<inertial>
<origin
xyz="2.5034674019167E-06 -0.00399152370097755 -0.0136055723537577"
rpy="0 0 0" />
<mass
value="0.0155246301341258" />
<inertia
ixx="1.99164881392775E-06"
ixy="-4.82887905395487E-10"
ixz="-2.07253296776602E-10"
iyy="2.02900387840545E-06"
iyz="2.49004321417992E-07"
izz="1.54078395860252E-06" />
</inertial>
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="../meshes/lf0_link.STL" />
</geometry>
<material
name="">
<color
rgba="1 1 1 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="../meshes/lf0_link.STL" />
</geometry>
</collision>
</link>
<joint
name="jlf0_link"
type="revolute">
<origin
xyz="-0.0031441 0.025688 -0.006475"
rpy="0 0 0" />
<parent
link="head_link" />
<child
link="lf0_link" />
<axis
xyz="0 0 -1" />
<limit
lower="0"
upper="0"
effort="0"
velocity="0" />
</joint>
<link
name="lf1_link">
<inertial>
<origin
xyz="2.91696425805399E-06 0.004390376864982 -0.0296712953157869"
rpy="0 0 0" />
<mass
value="0.013323922418148" />
<inertia
ixx="2.72143018103993E-06"
ixy="4.82887905395412E-10"
ixz="2.07253296776833E-10"
iyy="2.92090153101514E-06"
iyz="-3.25175555348237E-08"
izz="9.23918900070304E-07" />
</inertial>
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="../meshes/lf1_link.STL" />
</geometry>
<material
name="">
<color
rgba="1 1 1 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="../meshes/lf1_link.STL" />
</geometry>
</collision>
</link>
<joint
name="jlf1_link"
type="revolute">
<origin
xyz="9.7027E-05 0.011975 -0.012388"
rpy="0 0 0" />
<parent
link="lf0_link" />
<child
link="lf1_link" />
<axis
xyz="0 -1 0" />
<limit
lower="0"
upper="0"
effort="0"
velocity="0" />
</joint>
<link
name="lf2_link">
<inertial>
<origin
xyz="2.43737372657149E-06 0.00363613025354126 -0.0425732788173739"
rpy="0 0 0" />
<mass
value="0.0159456077850123" />
<inertia
ixx="5.35424510746978E-06"
ixy="4.82887905395677E-10"
ixz="2.07253296776739E-10"
iyy="5.71315402728463E-06"
iyz="-2.13454759600996E-08"
izz="1.09035404123551E-06" />
</inertial>
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="../meshes/lf2_link.STL" />
</geometry>
<material
name="">
<color
rgba="1 1 1 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="../meshes/lf2_link.STL" />
</geometry>
</collision>
</link>
<joint
name="jlf2_link"
type="revolute">
<origin
xyz="9.7027E-05 -0.008475 -0.040938"
rpy="0 0 0" />
<parent
link="lf1_link" />
<child
link="lf2_link" />
<axis
xyz="0 1 0" />
<limit
lower="0"
upper="0"
effort="0"
velocity="0" />
</joint>
<link
name="lf3_link">
<inertial>
<origin
xyz="-4.82253126321552E-16 -0.000451394188820231 -0.0198245674059442"
rpy="0 0 0" />
<mass
value="0.0192906631601767" />
<inertia
ixx="3.18209633375994E-06"
ixy="3.34527248954873E-21"
ixz="1.76056444695768E-21"
iyy="6.55022061625284E-06"
iyz="2.53604908486043E-07"
izz="7.24649308736933E-06" />
</inertial>
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="../meshes/lf3_link.STL" />
</geometry>
<material
name="">
<color
rgba="1 1 1 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="../meshes/lf3_link.STL" />
</geometry>
</collision>
</link>
<joint
name="jlf3_link"
type="revolute">
<origin
xyz="9.7027E-05 -0.006475 -0.060937"
rpy="0 0 0" />
<parent
link="lf2_link" />
<child
link="lf3_link" />
<axis
xyz="0 -1 0" />
<limit
lower="0"
upper="0"
effort="0"
velocity="0" />
</joint>
<link
name="rf0_link">
<inertial>
<origin
xyz="-2.50346740203813E-06 0.00399152370097733 -0.0136055723537577"
rpy="0 0 0" />
<mass
value="0.0155246301341258" />
<inertia
ixx="1.99164881392775E-06"
ixy="-4.82887905395413E-10"
ixz="2.07253296776268E-10"
iyy="2.02900387840545E-06"
iyz="-2.49004321417992E-07"
izz="1.54078395860252E-06" />
</inertial>
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="../meshes/rf0_link.STL" />
</geometry>
<material
name="">
<color
rgba="1 1 1 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="../meshes/rf0_link.STL" />
</geometry>
</collision>
</link>
<joint
name="jrf0_link"
type="revolute">
<origin
xyz="-0.0033382 -0.025687 -0.006475"
rpy="0 0 0" />
<parent
link="head_link" />
<child
link="rf0_link" />
<axis
xyz="0 0 -1" />
<limit
lower="0"
upper="0"
effort="0"
velocity="0" />
</joint>
<link
name="rf1_link">
<inertial>
<origin
xyz="-2.91696425855359E-06 -0.00439037686498245 -0.0296712953157865"
rpy="0 0 0" />
<mass
value="0.0133239224181479" />
<inertia
ixx="2.72143018103992E-06"
ixy="4.82887905395081E-10"
ixz="-2.07253296776895E-10"
iyy="2.92090153101514E-06"
iyz="3.25175555348265E-08"
izz="9.23918900070297E-07" />
</inertial>
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="../meshes/rf1_link.STL" />
</geometry>
<material
name="">
<color
rgba="1 1 1 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="../meshes/rf1_link.STL" />
</geometry>
</collision>
</link>
<joint
name="jrf1_link"
type="revolute">
<origin
xyz="-9.7027E-05 -0.011975 -0.012388"
rpy="0 0 0" />
<parent
link="rf0_link" />
<child
link="rf1_link" />
<axis
xyz="0 1 0" />
<limit
lower="0"
upper="0"
effort="0"
velocity="0" />
</joint>
<link
name="rf2_link">
<inertial>
<origin
xyz="-2.43737372681782E-06 -0.00363613025354104 -0.0425732788173739"
rpy="0 0 0" />
<mass
value="0.0159456077850122" />
<inertia
ixx="5.35424510746977E-06"
ixy="4.82887905394926E-10"
ixz="-2.0725329677683E-10"
iyy="5.71315402728462E-06"
iyz="2.13454759600991E-08"
izz="1.0903540412355E-06" />
</inertial>
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="../meshes/rf2_link.STL" />
</geometry>
<material
name="">
<color
rgba="1 1 1 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="../meshes/rf2_link.STL" />
</geometry>
</collision>
</link>
<joint
name="jrf2_link"
type="revolute">
<origin
xyz="-9.7027E-05 0.008475 -0.040937"
rpy="0 0 0" />
<parent
link="rf1_link" />
<child
link="rf2_link" />
<axis
xyz="0 1 0" />
<limit
lower="0"
upper="0"
effort="0"
velocity="0" />
</joint>
<link
name="rf3_link">
<inertial>
<origin
xyz="8.18789480661053E-16 0.000451394188820897 -0.0198245674059443"
rpy="0 0 0" />
<mass
value="0.0192906631601768" />
<inertia
ixx="3.18209633375994E-06"
ixy="8.58350838304875E-21"
ixz="2.39867798130625E-21"
iyy="6.55022061625285E-06"
iyz="-2.53604908486041E-07"
izz="7.24649308736931E-06" />
</inertial>
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="../meshes/rf3_link.STL" />
</geometry>
<material
name="">
<color
rgba="1 1 1 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="../meshes/rf3_link.STL" />
</geometry>
</collision>
</link>
<joint
name="jrf3_link"
type="revolute">
<origin
xyz="-9.7027E-05 0.006475 -0.060938"
rpy="0 0 0" />
<parent
link="rf2_link" />
<child
link="rf3_link" />
<axis
xyz="0 1 0" />
<limit
lower="0"
upper="0"
effort="0"
velocity="0" />
</joint>
</robot>

View File

@ -0,0 +1 @@
from . import direct

View File

@ -0,0 +1,192 @@
from __future__ import annotations
import gymnasium as gym
import torch
import isaaclab.sim as sim_utils
from isaaclab.assets import Articulation
from isaaclab.envs import DirectRLEnv
from isaaclab.sensors import ContactSensor
from .custom_rewards import compute_custom_reward_terms
from .2foot_env_cfg import 2footEnvCfg
class 2footEnv(DirectRLEnv):
cfg: 2footEnvCfg
def __init__(self, cfg: 2footEnvCfg, render_mode: str | None = None, **kwargs):
super().__init__(cfg, render_mode, **kwargs)
self._actions = torch.zeros(self.num_envs, gym.spaces.flatdim(self.single_action_space), device=self.device)
self._previous_actions = torch.zeros_like(self._actions)
self._commands = torch.zeros(self.num_envs, 3, device=self.device)
self._episode_sums = {
key: torch.zeros(self.num_envs, dtype=torch.float, device=self.device)
for key in self.cfg.reward_scales.keys()
}
self._actuated_joint_ids, _ = self._robot.find_joints(self.cfg.actuated_joint_names, preserve_order=True)
self._foot_ids, _ = self._contact_sensor.find_bodies(self.cfg.foot_link_names, preserve_order=True)
self._termination_body_ids, _ = self._contact_sensor.find_bodies([self.cfg.base_link_name], preserve_order=True)
self._undesired_contact_body_ids, _ = self._contact_sensor.find_bodies([], preserve_order=True)
self._termination_grace_steps = max(0, int(self.cfg.termination_grace_time_s / self.step_dt))
self._fallen_termination_steps = max(1, int(self.cfg.fallen_termination_time_s / self.step_dt))
self._fallen_fail_buf = torch.zeros(self.num_envs, dtype=torch.float, device=self.device)
self._pre_step_root_height = torch.full(
(self.num_envs,), self.cfg.base_height_target, dtype=torch.float, device=self.device
)
def _setup_scene(self):
self._robot = Articulation(self.cfg.robot)
self.scene.articulations["robot"] = self._robot
self._contact_sensor = ContactSensor(self.cfg.contact_sensor)
self.scene.sensors["contact_sensor"] = self._contact_sensor
self.cfg.terrain.num_envs = self.scene.cfg.num_envs
self.cfg.terrain.env_spacing = self.scene.cfg.env_spacing
self._terrain = self.cfg.terrain.class_type(self.cfg.terrain)
self.scene.clone_environments(copy_from_source=False)
if self.device == "cpu":
self.scene.filter_collisions(global_prim_paths=[self.cfg.terrain.prim_path])
light_cfg = sim_utils.DomeLightCfg(intensity=2000.0, color=(0.75, 0.75, 0.75))
light_cfg.func("/World/Light", light_cfg)
def _pre_physics_step(self, actions: torch.Tensor):
self._actions = torch.clamp(actions.clone(), -self.cfg.action_clip, self.cfg.action_clip)
self._pre_step_root_height = self._robot.data.root_pos_w[:, 2] - self._terrain.env_origins[:, 2]
default_pos = self._robot.data.default_joint_pos[:, self._actuated_joint_ids]
self._processed_actions = self.cfg.action_scale * self._actions + default_pos
def _apply_action(self):
self._robot.set_joint_position_target(self._processed_actions, joint_ids=self._actuated_joint_ids)
def _get_observations(self) -> dict:
obs = torch.cat(
[
self._robot.data.root_lin_vel_b,
self._robot.data.root_ang_vel_b,
self._robot.data.projected_gravity_b,
self._commands,
self._robot.data.joint_pos[:, self._actuated_joint_ids]
- self._robot.data.default_joint_pos[:, self._actuated_joint_ids],
self._robot.data.joint_vel[:, self._actuated_joint_ids],
self._actions,
],
dim=-1,
)
self._previous_actions = self._actions.clone()
return {"policy": obs}
def _get_rewards(self) -> torch.Tensor:
reward_scales = self.cfg.reward_scales
joint_pos_error = self._robot.data.joint_pos[:, self._actuated_joint_ids] - self._robot.data.default_joint_pos[:, self._actuated_joint_ids]
lin_vel_error = torch.sum(torch.square(self._commands[:, :2] - self._robot.data.root_lin_vel_b[:, :2]), dim=1)
ang_vel_error = torch.square(self._commands[:, 2] - self._robot.data.root_ang_vel_b[:, 2])
z_vel_error = torch.square(self._robot.data.root_lin_vel_b[:, 2])
ang_vel_xy_error = torch.sum(torch.square(self._robot.data.root_ang_vel_b[:, :2]), dim=1)
orientation_error = torch.sum(torch.square(self._robot.data.projected_gravity_b[:, :2]), dim=1)
joint_torques = torch.sum(torch.square(self._robot.data.applied_torque[:, self._actuated_joint_ids]), dim=1)
joint_vel = torch.sum(torch.square(self._robot.data.joint_vel[:, self._actuated_joint_ids]), dim=1)
joint_accel = torch.sum(torch.square(self._robot.data.joint_acc[:, self._actuated_joint_ids]), dim=1)
action_rate = torch.sum(torch.square(self._actions - self._previous_actions), dim=1)
root_height = self._robot.data.root_pos_w[:, 2] - self._terrain.env_origins[:, 2]
base_height_error = torch.square(root_height - self.cfg.base_height_target)
first_contact = self._contact_sensor.compute_first_contact(self.step_dt)[:, self._foot_ids]
last_air_time = self._contact_sensor.data.last_air_time[:, self._foot_ids]
feet_air_time = torch.sum((last_air_time - 0.5) * first_contact, dim=1) * (
torch.norm(self._commands[:, :2], dim=1) > 0.1
)
if self._undesired_contact_body_ids:
net_contact_forces = self._contact_sensor.data.net_forces_w_history
is_contact = (
torch.max(torch.norm(net_contact_forces[:, :, self._undesired_contact_body_ids], dim=-1), dim=1)[0] > 1.0
)
collision = torch.sum(is_contact, dim=1)
else:
collision = torch.zeros(self.num_envs, device=self.device)
stand_still = torch.sum(torch.abs(joint_pos_error), dim=1) * (torch.norm(self._commands, dim=1) < 0.1)
termination = self.reset_terminated.float()
rewards = {
"termination": termination * reward_scales.get("termination", 0.0),
"tracking_lin_vel": torch.exp(-lin_vel_error / 0.25) * reward_scales.get("tracking_lin_vel", 0.0),
"tracking_ang_vel": torch.exp(-ang_vel_error / 0.25) * reward_scales.get("tracking_ang_vel", 0.0),
"lin_vel_z": z_vel_error * reward_scales.get("lin_vel_z", 0.0),
"ang_vel_xy": ang_vel_xy_error * reward_scales.get("ang_vel_xy", 0.0),
"orientation": orientation_error * reward_scales.get("orientation", 0.0),
"torques": joint_torques * reward_scales.get("torques", 0.0),
"dof_vel": joint_vel * reward_scales.get("dof_vel", 0.0),
"dof_acc": joint_accel * reward_scales.get("dof_acc", 0.0),
"base_height": base_height_error * reward_scales.get("base_height", 0.0),
"feet_air_time": feet_air_time * reward_scales.get("feet_air_time", 0.0),
"collision": collision * reward_scales.get("collision", 0.0),
"feet_stumble": torch.zeros_like(collision),
"action_rate": action_rate * reward_scales.get("action_rate", 0.0),
"stand_still": stand_still * reward_scales.get("stand_still", 0.0),
}
custom_rewards = compute_custom_reward_terms(self)
for key, value in custom_rewards.items():
rewards[key] = rewards.get(key, torch.zeros_like(value)) + value * reward_scales.get(key, 0.0)
reward = torch.sum(torch.stack(list(rewards.values())), dim=0) * self.step_dt
for key, value in rewards.items():
self._episode_sums[key] += value * self.step_dt
return reward
def _get_dones(self) -> tuple[torch.Tensor, torch.Tensor]:
time_out = self.episode_length_buf >= self.max_episode_length - 1
if getattr(self.cfg, "visual_disable_resets", False):
no_reset = torch.zeros_like(time_out)
return no_reset, no_reset
after_grace = self.episode_length_buf > self._termination_grace_steps
if self._termination_body_ids:
net_contact_forces = self._contact_sensor.data.net_forces_w_history
termination_contacts = torch.max(torch.norm(net_contact_forces[:, :, self._termination_body_ids], dim=-1), dim=1)[0]
contact_died = torch.any(termination_contacts > self.cfg.termination_contact_force_threshold, dim=1)
else:
contact_died = torch.zeros_like(time_out)
root_height = torch.minimum(
self._robot.data.root_pos_w[:, 2] - self._terrain.env_origins[:, 2],
self._pre_step_root_height,
)
height_died = root_height < self.cfg.min_base_height
fallen = self._robot.data.projected_gravity_b[:, 2] > self.cfg.fallen_projected_gravity_z
fallen &= after_grace
self._fallen_fail_buf *= fallen.float()
self._fallen_fail_buf += fallen.float()
fallen_died = self._fallen_fail_buf > self._fallen_termination_steps
died = ((contact_died | height_died) & after_grace) | fallen_died
return died, time_out
def _reset_idx(self, env_ids: torch.Tensor | None):
if env_ids is None or len(env_ids) == self.num_envs:
env_ids = self._robot._ALL_INDICES
self._robot.reset(env_ids)
super()._reset_idx(env_ids)
if len(env_ids) == self.num_envs and getattr(self.cfg, "randomize_initial_episode_length", False):
self.episode_length_buf[:] = torch.randint_like(self.episode_length_buf, high=int(self.max_episode_length))
self._actions[env_ids] = 0.0
self._previous_actions[env_ids] = 0.0
self._fallen_fail_buf[env_ids] = 0.0
self._pre_step_root_height[env_ids] = self.cfg.base_height_target
self._commands[env_ids, 0].uniform_(*self.cfg.command_ranges["lin_vel_x"])
self._commands[env_ids, 1].uniform_(*self.cfg.command_ranges["lin_vel_y"])
self._commands[env_ids, 2].uniform_(*self.cfg.command_ranges["ang_vel_yaw"])
joint_pos = self._robot.data.default_joint_pos[env_ids]
joint_vel = self._robot.data.default_joint_vel[env_ids]
default_root_state = self._robot.data.default_root_state[env_ids]
default_root_state[:, :3] += self._terrain.env_origins[env_ids]
self._robot.write_root_pose_to_sim(default_root_state[:, :7], env_ids)
self._robot.write_root_velocity_to_sim(default_root_state[:, 7:], env_ids)
self._robot.write_joint_state_to_sim(joint_pos, joint_vel, None, env_ids)
extras = {}
for key in self._episode_sums.keys():
extras["Episode_Reward/" + key] = torch.mean(self._episode_sums[key][env_ids]) / self.max_episode_length_s
self._episode_sums[key][env_ids] = 0.0
self.extras["log"] = extras

View File

@ -0,0 +1,199 @@
from pathlib import Path
import isaaclab.sim as sim_utils
from isaaclab.actuators import ImplicitActuatorCfg
from isaaclab.assets import ArticulationCfg
from isaaclab.envs import DirectRLEnvCfg
from isaaclab.scene import InteractiveSceneCfg
from isaaclab.sensors import ContactSensorCfg
from isaaclab.sim import SimulationCfg
from isaaclab.terrains import TerrainImporterCfg
from isaaclab.terrains.config.rough import ROUGH_TERRAINS_CFG
from isaaclab.utils import configclass
ASSET_DIR = Path(__file__).resolve().parents[3] / "assets" / "robots" / "2foot"
URDF_PATH = ASSET_DIR / "urdf" / "2foot.urdf"
@configclass
class 2footEnvCfg(DirectRLEnvCfg):
episode_length_s = 20.0
decimation = 4
action_scale = 0.5
action_space = 8
observation_space = 36
state_space = 0
sim: SimulationCfg = SimulationCfg(
dt=1 / 200,
render_interval=decimation,
physics_material=sim_utils.RigidBodyMaterialCfg(
friction_combine_mode="multiply",
restitution_combine_mode="multiply",
static_friction=1.0,
dynamic_friction=1.0,
restitution=0.0,
),
)
terrain = TerrainImporterCfg(
prim_path="/World/ground",
terrain_type="plane",
collision_group=-1,
physics_material=sim_utils.RigidBodyMaterialCfg(
friction_combine_mode="multiply",
restitution_combine_mode="multiply",
static_friction=1.0,
dynamic_friction=1.0,
restitution=0.0,
),
debug_vis=False,
)
scene: InteractiveSceneCfg = InteractiveSceneCfg(num_envs=1024, env_spacing=4.0, replicate_physics=True)
robot: ArticulationCfg = ArticulationCfg(
prim_path="/World/envs/env_.*/Robot",
spawn=sim_utils.UrdfFileCfg(
asset_path=str(URDF_PATH),
fix_base=False,
merge_fixed_joints=True,
self_collision=False,
replace_cylinders_with_capsules=True,
activate_contact_sensors=True,
rigid_props=sim_utils.RigidBodyPropertiesCfg(
disable_gravity=False,
retain_accelerations=False,
linear_damping=0.0,
angular_damping=0.0,
max_linear_velocity=1000.0,
max_angular_velocity=1000.0,
max_depenetration_velocity=5.0,
),
articulation_props=sim_utils.ArticulationRootPropertiesCfg(
enabled_self_collisions=False,
solver_position_iteration_count=8,
solver_velocity_iteration_count=1,
),
joint_drive=sim_utils.UrdfConverterCfg.JointDriveCfg(
gains=sim_utils.UrdfConverterCfg.JointDriveCfg.PDGainsCfg(stiffness=0.0, damping=0.0)
),
),
init_state=ArticulationCfg.InitialStateCfg(
pos=(0.0, 0.0, 1),
joint_pos={
"jlf0_link": 0.0,
"jlf1_link": 0.0,
"jlf2_link": 0.0,
"jlf3_link": 0.0,
"jrf0_link": 0.0,
"jrf1_link": 0.0,
"jrf2_link": 0.0,
"jrf3_link": 0.0,
},
),
actuators={
"joints": ImplicitActuatorCfg(
joint_names_expr=["jlf0_link", "jlf1_link", "jlf2_link", "jlf3_link", "jrf0_link", "jrf1_link", "jrf2_link", "jrf3_link"],
stiffness={
"jlf0_link": 20.0,
"jlf1_link": 20.0,
"jlf2_link": 20.0,
"jlf3_link": 20.0,
"jrf0_link": 20.0,
"jrf1_link": 20.0,
"jrf2_link": 20.0,
"jrf3_link": 20.0,
},
damping={
"jlf0_link": 0.5,
"jlf1_link": 0.5,
"jlf2_link": 0.5,
"jlf3_link": 0.5,
"jrf0_link": 0.5,
"jrf1_link": 0.5,
"jrf2_link": 0.5,
"jrf3_link": 0.5,
},
effort_limit_sim={
"jlf0_link": 0.0,
"jlf1_link": 0.0,
"jlf2_link": 0.0,
"jlf3_link": 0.0,
"jrf0_link": 0.0,
"jrf1_link": 0.0,
"jrf2_link": 0.0,
"jrf3_link": 0.0,
},
velocity_limit_sim={
"jlf0_link": 0.0,
"jlf1_link": 0.0,
"jlf2_link": 0.0,
"jlf3_link": 0.0,
"jrf0_link": 0.0,
"jrf1_link": 0.0,
"jrf2_link": 0.0,
"jrf3_link": 0.0,
},
),
},
soft_joint_pos_limit_factor=0.95,
)
contact_sensor: ContactSensorCfg = ContactSensorCfg(
prim_path="/World/envs/env_.*/Robot/.*",
history_length=3,
update_period=0.02,
track_air_time=True,
)
command_ranges = {
"lin_vel_x": (-0.5, 0.5),
"lin_vel_y": (-0.25, 0.25),
"ang_vel_yaw": (-0.5, 0.5),
}
reward_scales = {
"termination": 0.0,
"tracking_lin_vel": 1.0,
"tracking_ang_vel": 0.5,
"lin_vel_z": -2.0,
"ang_vel_xy": -0.05,
"orientation": -1.0,
"torques": -0.00001,
"dof_vel": 0.0,
"dof_acc": -2.5e-7,
"base_height": -1.0,
"feet_air_time": 1.0,
"collision": -1.0,
"feet_stumble": 0.0,
"action_rate": -0.01,
"stand_still": 0.0,
"custom_reward": 0.0,
}
default_joint_angles = {
"jlf0_link": 0.0,
"jlf1_link": 0.0,
"jlf2_link": 0.0,
"jlf3_link": 0.0,
"jrf0_link": 0.0,
"jrf1_link": 0.0,
"jrf2_link": 0.0,
"jrf3_link": 0.0,
}
actuated_joint_names = ["jlf0_link", "jlf1_link", "jlf2_link", "jlf3_link", "jrf0_link", "jrf1_link", "jrf2_link", "jrf3_link"]
foot_link_names = ["lf3_link", "rf3_link"]
base_link_name = "head_link"
auto_ground_spawn_height = 1
auto_ground_clearance = 0.02
auto_ground_complete = False
base_height_target = 0.98
action_clip = 1.0
visual_disable_resets = False
termination_grace_time_s = 2.0
termination_contact_force_threshold = 20.0
fallen_projected_gravity_z = -0.35
fallen_termination_time_s = 0.5
min_base_height = 0.441
randomize_initial_episode_length = False

View File

@ -0,0 +1,14 @@
import gymnasium as gym
from . import agents
gym.register(
id="Template-2foot-Direct-v0",
entry_point=f"{__name__}.2foot_env:2footEnv",
disable_env_checker=True,
kwargs={
"env_cfg_entry_point": f"{__name__}.2foot_env_cfg:2footEnvCfg",
"rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:2footPPORunnerCfg",
},
)

View File

@ -0,0 +1,32 @@
from isaaclab.utils import configclass
from isaaclab_rl.rsl_rl import RslRlOnPolicyRunnerCfg, RslRlPpoActorCriticCfg, RslRlPpoAlgorithmCfg
@configclass
class 2footPPORunnerCfg(RslRlOnPolicyRunnerCfg):
num_steps_per_env = 24
max_iterations = 1500
save_interval = 50
experiment_name = "2foot"
policy = RslRlPpoActorCriticCfg(
init_noise_std=1.0,
actor_obs_normalization=False,
critic_obs_normalization=False,
actor_hidden_dims=[256, 256, 128],
critic_hidden_dims=[256, 256, 128],
activation="elu",
)
algorithm = RslRlPpoAlgorithmCfg(
value_loss_coef=1.0,
use_clipped_value_loss=True,
clip_param=0.2,
entropy_coef=0.005,
num_learning_epochs=5,
num_mini_batches=4,
learning_rate=1.0e-3,
schedule="adaptive",
gamma=0.99,
lam=0.95,
desired_kl=0.01,
max_grad_norm=1.0,
)

View File

@ -0,0 +1,20 @@
from __future__ import annotations
import torch
def compute_custom_reward_terms(env) -> dict[str, torch.Tensor]:
"""Return additional unscaled reward terms.
Edit this file after export to add task-specific reward terms.
Each tensor must have shape [num_envs].
To activate a term, also set a non-zero scale for the same key
inside reward_scales in the generated *_env_cfg.py file.
"""
# Example:
# root_height = env._robot.data.root_pos_w[:, 2] - env._terrain.env_origins[:, 2]
# return {"custom_reward": torch.clamp(root_height - 0.25, min=0.0)}
return {"custom_reward": torch.zeros(env.num_envs, dtype=torch.float, device=env.device)}

79
git-force-push.bat Normal file
View File

@ -0,0 +1,79 @@
@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion
echo ============================================================
echo 脚本: git-force-push.bat
echo 功能: 将本地分支强制推送到远程,让远程与本地完全一致
echo ============================================================
REM ---------- 检查是否在 Git 仓库 ----------
git rev-parse --is-inside-work-tree >nul 2>&1
if errorlevel 1 (
echo [错误] 当前目录不是 Git 仓库
exit /b 1
)
REM ---------- 获取当前分支 ----------
for /f %%i in ('git branch --show-current') do set CURRENT_BRANCH=%%i
if "%CURRENT_BRANCH%"=="" (
echo [错误] 当前处于 HEAD 分离状态,请先切换到具体分支。
exit /b 1
)
echo [信息] 当前分支:%CURRENT_BRANCH%
REM ---------- 拉取远程最新信息 ----------
echo [信息] 正在获取远程最新引用...
git fetch origin
REM ---------- 检查本地是否有未提交更改 ----------
git diff --quiet >nul 2>&1
if errorlevel 1 (
echo [警告] 检测到本地有未提交的更改(已暂存或未暂存)。
echo [警告] 这些更改不会被推送,但会保留在工作区。
set /p CONTINUE="是否继续强制推送?(y/N): "
if /i not "!CONTINUE!"=="y" (
echo [信息] 操作已取消。
exit /b 0
)
)
REM ---------- 检查本地是否落后于远程 ----------
for /f %%i in ('git rev-list --count @..@{u} 2^>nul') do set AHEAD=%%i
if not defined AHEAD set AHEAD=0
if %AHEAD% gtr 0 (
echo [警告] 远程有 %AHEAD% 个新提交,本地落后于远程。
echo [警告] 强制推送会覆盖这些提交,请确认这不是他人刚提交的代码!
)
REM ---------- 选择推送模式 ----------
echo 请选择推送模式:
echo 1) --force-with-lease (推荐,安全覆盖)
echo 2) --force (强制覆盖,极度危险)
set /p MODE="请输入数字 (1 或 2默认 1): "
if "%MODE%"=="" set MODE=1
if "%MODE%"=="2" (
set FORCE_FLAG=--force
echo [警告] 您选择了 --force这将无条件覆盖远程分支
) else (
set FORCE_FLAG=--force-with-lease
echo [信息] 您选择了 --force-with-lease安全模式。
)
REM ---------- 最终确认 ----------
set /p CONFIRM="确认将本地分支 %CURRENT_BRANCH% 强制推送到远程?请输入 'yes' 继续: "
if /i not "%CONFIRM%"=="yes" (
echo [信息] 操作已取消。
exit /b 0
)
REM ---------- 执行推送 ----------
echo [信息] 正在执行: git push %FORCE_FLAG% origin %CURRENT_BRANCH%
git push %FORCE_FLAG% origin %CURRENT_BRANCH%
if errorlevel 1 (
echo [错误] 推送失败,请检查网络或权限。
exit /b %errorlevel%
)
echo [成功] 推送完成!远程 origin/%CURRENT_BRANCH% 已与本地保持一致。
endlocal

Binary file not shown.

BIN
大腿.SLDASM Normal file

Binary file not shown.

BIN
小腿.SLDASM Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

321279
带电的/pcb.step Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
总装体 - 副本.SLDASM Normal file

Binary file not shown.

Binary file not shown.

BIN
生体.SLDASM Normal file

Binary file not shown.

BIN
胯骨.SLDASM Normal file

Binary file not shown.