Skip to content

Commit 5a689ab

Browse files
committed
[update] update submodule version and improve setup.py build files
1 parent c6ade50 commit 5a689ab

File tree

6 files changed

+109
-119
lines changed

6 files changed

+109
-119
lines changed

example/sapien/README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ meshcat-server
2222

2323
```bash
2424
# Install the dependencies for ManiSkill2 if you have not
25-
pip install setuptools==50.0 mani-skill2
25+
pip install mani-skill2 # or pip install ."[sapien]" in the project root
2626
cd example/sapien
2727

2828
# You may need to download the ManiSkill2 assets before running
@@ -31,3 +31,7 @@ python run_sapien_viz.py
3131
```
3232

3333
This will start the simulation, and you should be able to visualize it in your web browser via the provided link.
34+
35+
## Limitations
36+
37+
Currently, the rendering of soft body simulation is not support for SAPIEN ManiSkill.

pyproject.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[build-system]
2+
requires = ["setuptools>=62.0.0"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[tool.isort]
6+
profile = "black"
7+
skip_gitignore = true
8+
single_line_exclusions = ["typing"]
9+
10+
[tool.black]
11+
line_length = 88 # default

setup.py

Lines changed: 89 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,22 @@
55
"""Setup script """
66

77
import os
8+
import re
9+
from pathlib import Path
810

911
from setuptools import setup, find_packages
1012

13+
_here = Path(__file__).resolve().parent
14+
name = "sim_web_visualizer"
15+
16+
# Reference: https://github.com/kevinzakka/mjc_viewer/blob/main/setup.py
17+
with open(_here / name / "__init__.py") as f:
18+
meta_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", f.read(), re.M)
19+
if meta_match:
20+
version = meta_match.group(1)
21+
else:
22+
raise RuntimeError("Unable to find __version__ string.")
23+
1124

1225
def collect_files(target_dir):
1326
file_list = []
@@ -17,38 +30,87 @@ def collect_files(target_dir):
1730
return file_list
1831

1932

33+
core_requirements = [
34+
"numpy<=1.23.0",
35+
"numpy-quaternion",
36+
"transforms3d",
37+
"dm_control>=1.0.0",
38+
"anytree",
39+
"trimesh",
40+
"pycollada",
41+
f"meshcat @ file://localhost{str(_here.absolute())}/3rd_party/meshcat-python", "mujoco>=2.2.0",
42+
]
43+
44+
isaac_requirements = [
45+
"hydra-core",
46+
"gym==0.23.1",
47+
"rl-games",
48+
"torch",
49+
"pyvirtualdisplay",
50+
"omegaconf",
51+
"jinja2",
52+
]
53+
54+
sapien_requirements = [
55+
"mani-skill2",
56+
]
57+
58+
classifiers = [
59+
"Development Status :: 3 - Alpha",
60+
"Intended Audience :: Developers",
61+
"Intended Audience :: Science/Research",
62+
"License :: OSI Approved :: MIT License",
63+
"Natural Language :: English",
64+
"Programming Language :: Python :: 3",
65+
"Programming Language :: Python :: 3.6",
66+
"Programming Language :: Python :: 3.7",
67+
"Programming Language :: Python :: 3.8",
68+
"Programming Language :: Python :: 3.9",
69+
"Programming Language :: Python :: 3.10",
70+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
71+
]
72+
73+
2074
def setup_package():
21-
root_dir = os.path.dirname(os.path.realpath(__file__))
75+
# Meta information of the project
76+
author = "Yuzhe Qin"
77+
author_email = "y1qin@ucsd.edu"
78+
description = "Web based visualizer for simulators"
79+
url = "https://github.com/NVlabs/sim-web-visualizer"
80+
with open(_here / "README.md", "r") as file:
81+
readme = file.read()
2282

83+
# Package data
2384
packages = find_packages(".")
24-
print(packages)
25-
85+
print(f"Packages: {packages}")
2686
package_files = ["assets/axis_geom/*"]
2787

28-
setup(name='sim_web_visualizer',
29-
version='0.4.0',
30-
description='Web based visualizer for simulators',
31-
author='Yuzhe Qin',
32-
author_email='',
33-
url='',
34-
license='MIT',
35-
packages=packages,
36-
package_data={
37-
"sim_web_visualizer": package_files
38-
},
39-
python_requires='>=3.6,<3.11',
40-
install_requires=[
41-
# General dependencies
42-
"numpy<=1.23.0",
43-
"numpy-quaternion",
44-
"transforms3d",
45-
"dm_control>=1.0.0",
46-
"anytree",
47-
"trimesh",
48-
"pycollada",
49-
f"meshcat @ file://localhost{root_dir}/3rd_party/meshcat-python",
50-
],
51-
)
88+
setup(
89+
name=name,
90+
version=version,
91+
author=author,
92+
author_email=author_email,
93+
maintainer=author,
94+
maintainer_email=author_email,
95+
description=description,
96+
long_description=readme,
97+
long_description_content_type="text/markdown",
98+
url=url,
99+
license='MIT',
100+
license_files=("LICENSE",),
101+
packages=packages,
102+
package_data={
103+
"sim_web_visualizer": package_files
104+
},
105+
python_requires='>=3.6,<3.11',
106+
zip_safe=True,
107+
install_requires=core_requirements,
108+
extras_require={
109+
"isaacgym": isaac_requirements,
110+
"sapien": sapien_requirements,
111+
},
112+
classifiers=classifiers,
113+
)
52114

53115

54116
setup_package()

sim_web_visualizer/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
from .base_visualizer_client import MeshCatVisualizerBase
88

9+
__version__ = "0.4.0"
10+
911
try:
1012
import sapien.core as sapien
1113
from .sapien_visualizer_client import create_sapien_visualizer, bind_visualizer_to_sapien_scene

sim_web_visualizer/parser/urdf.py

Lines changed: 0 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@
33
# Licensed under the MIT License [see LICENSE for details].
44

55
# Utils for load URDF for meshcat server
6-
from typing import List
76

87
import meshcat.geometry as g
98
import numpy as np
109
import transforms3d
1110
import trimesh
12-
from meshcat.visualizer import Visualizer
1311

1412
import sim_web_visualizer.parser.yourdfpy as urdf
1513
from sim_web_visualizer.parser.mesh_parser import load_mesh, get_trimesh_geometry_material, rgb_to_hex, AssetResource
@@ -163,91 +161,3 @@ def load_urdf_with_yourdfpy(urdf_path: str, collapse_fixed_joints: bool,
163161
pose_data=offline_pose_dict,
164162
)
165163
return resource
166-
167-
168-
def load_urdf_into_viewer_pin(filename: str, viewer: Visualizer, collapsed_link_names: List[str]):
169-
import collada
170-
import pinocchio as pin
171-
# First parse the urdf with yourdfpy since it can better handle ROS pacakge format
172-
my_urdf = urdf.URDF.load(filename)
173-
urdf_string = my_urdf.write_xml_string()
174-
175-
# Then store the internal data structure inside pinocchio
176-
robot: pin.pinocchio_pywrap.Model = pin.buildModelFromXML(urdf_string)
177-
frame_id_map = {i: frame.name for i, frame in enumerate(robot.frames)}
178-
179-
# TODO: use collision model
180-
visual_model = pin.buildGeomFromUrdfString(robot, my_urdf.write_xml_string(), pin.VISUAL)
181-
# collision_model = pin.buildGeomFromUrdfString(robot, my_urdf.write_xml_string(), pin.COLLISION)
182-
# data, collision_data, visual_data = pin.createDatas(robot, collision_model, visual_model)
183-
# joint_pos = pin.neutral(robot)
184-
# pin.forwardKinematics(robot, data, joint_pos)
185-
# pin.updateGeometryPlacements(robot, data, visual_model, visual_data)
186-
187-
collapse_fixed_joints = len(collapsed_link_names) > 0
188-
if collapse_fixed_joints:
189-
parent_frame_map = {}
190-
# The first two frames in pinocchio are 'universe' and 'root_joint', which are not presented in URDF
191-
for frame_id, link_info in enumerate(robot.frames): # type: int, pin.pinocchio_pywrap.Frame
192-
if link_info.type != pin.pinocchio_pywrap.FrameType.BODY:
193-
continue
194-
name = link_info.name
195-
if name in collapsed_link_names:
196-
parent_frame_map[link_info.parent] = frame_id
197-
198-
# Load mesh based on geometry data
199-
link_mesh_count = {}
200-
for geom in visual_model.geometryObjects: # type: pin.GeometryObject
201-
color = geom.meshColor[:3]
202-
opacity = geom.meshColor[3]
203-
mat = None
204-
if geom.meshPath == 'BOX':
205-
geometry = g.Box(2 * geom.geometry.halfSide)
206-
elif geom.meshPath == 'SPHERE':
207-
geometry = g.Sphere(geom.geometry.radius)
208-
elif geom.meshPath == 'CYLINDER':
209-
radius, length = geom.geometry.radius, 2 * geom.geometry.halfLength
210-
geometry = g.Cylinder(radius=radius, height=length)
211-
else:
212-
path = geom.meshPath
213-
if path.endswith("dae"):
214-
geometry = g.DaeMeshGeometry.from_file(path)
215-
temp_mesh = collada.Collada(geom.meshPath)
216-
img_info = [(im.path, im.data) for im in temp_mesh.images if im.path is not None]
217-
if len(img_info) > 0:
218-
texture = g.ImageTexture(g.PngImage(data=img_info[0][1]))
219-
mat = g.MeshLambertMaterial(map=texture, opacity=opacity)
220-
221-
else:
222-
exp_mesh = load_mesh(geom.meshPath, geom.meshScale)
223-
geometry = g.ObjMeshGeometry.from_stream(trimesh.util.wrap_as_stream(exp_mesh))
224-
texture_file = geom.meshTexturePath if geom.meshTexturePath else None
225-
texture = g.ImageTexture(g.PngImage.from_file(texture_file)) if isinstance(texture_file,
226-
str) else None # Create material
227-
if texture is not None:
228-
mat = g.MeshLambertMaterial(map=texture, opacity=opacity)
229-
230-
# Only create color texture if the color is not the default value for better performance
231-
if not np.allclose(geom.meshColor, np.array([0.9, 0.9, 0.9, 1])):
232-
if not (np.any(color > 1) and color.dtype == np.int):
233-
color *= 255
234-
color = np.clip(color, 0, 255).astype(np.uint8)
235-
mat = g.MeshLambertMaterial(color=rgb_to_hex(color), opacity=opacity)
236-
237-
# Compute relative pose
238-
geom_frame_id = geom.parentFrame
239-
frame_id = frame_id_map[geom_frame_id] if not collapse_fixed_joints else parent_frame_map[geom.parentJoint]
240-
link_name = frame_id_map[frame_id]
241-
link_pose = robot.frames[frame_id].placement
242-
243-
# Count geom name for each link
244-
if link_name not in link_mesh_count:
245-
link_mesh_count[link_name] = 0
246-
else:
247-
link_mesh_count[link_name] += 1
248-
geom_id = link_mesh_count[link_name]
249-
250-
# Set mesh and pose
251-
relative_pose = (link_pose.inverse() * geom.placement).homogeneous
252-
viewer[f"{link_name}/{geom_id}"].set_object(geometry, material=mat)
253-
viewer[f"{link_name}/{geom_id}"].set_transform(relative_pose)

sim_web_visualizer/sapien_visualizer_client.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ def __setattr__(self, key, value):
5757
super().__setattr__(key, value)
5858

5959

60-
def visual2geom_mat(visual: sapien.VisualRecord, pose: np.ndarray) -> Tuple[List[g.Geometry], List[g.Material], List[np.ndarray]]:
60+
def visual2geom_mat(visual: sapien.VisualRecord, pose: np.ndarray) -> Tuple[
61+
List[g.Geometry], List[g.Material], List[np.ndarray]]:
6162
scale = visual.scale.astype(float)
6263
material = visual.material
6364
if visual.type == "Box":

0 commit comments

Comments
 (0)