Mujoco KDL Wrapper  0.2.2
MuJoCo + KDL bridge for robot kinematics and dynamics
Loading...
Searching...
No Matches
ex_table_scene.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2"""Table-scene example ported from src/examples/ex_table_scene.cpp.
3
4Arm + gripper on a table with free objects. The arm runs KDL gravity
5compensation and the gripper cycles open/closed. An Env on_reset hook re-homes
6the arm so the simulate-UI reset button restores the scene.
7"""
8
9from __future__ import annotations
10
11import argparse
12import math
13
14import mj_kdl_wrapper as mjk
15
16SURFACE_Z = 0.7
17HOME_POSE = [0.0, 0.2618, 3.1416, -2.2689, 0.0, 0.9599, 1.5708]
18
19
20def attachment_gripper(path: str) -> mjk.AttachmentSpec:
21 spec = mjk.AttachmentSpec()
22 spec.mjcf_path = path
23 spec.attach_to = mjk.AttachTarget(mjk.AttachKind.Site, "pinch_site")
24 spec.prefix = "g_"
25 return spec
26
27
28def table_object(path: str) -> mjk.SceneObject:
29 obj = mjk.SceneObject()
30 obj.name = "table"
31 obj.mjcf_path = path
32 obj.pos = [0.0, 0.0, SURFACE_Z]
33 obj.fixed = True
34 return obj
35
36
37def make_box(name, x, y, hx, hy, hz, color) -> mjk.SceneObject:
38 obj = mjk.SceneObject()
39 obj.name = name
40 obj.shape = mjk.Shape.BOX
41 obj.size = [hx, hy, hz]
42 obj.pos = [x, y, SURFACE_Z + hz]
43 obj.rgba = [color[0], color[1], color[2], 1.0]
44 obj.mass = 0.2
45 obj.friction = [1.0, 0.005, 0.0001]
46 return obj
47
48
49def make_sphere(name, x, y, radius, color) -> mjk.SceneObject:
50 obj = mjk.SceneObject()
51 obj.name = name
52 obj.shape = mjk.Shape.SPHERE
53 obj.size = [radius, 0.0, 0.0]
54 obj.pos = [x, y, SURFACE_Z + radius]
55 obj.rgba = [color[0], color[1], color[2], 1.0]
56 obj.mass = 0.1
57 obj.friction = [1.0, 0.005, 0.0001]
58 return obj
59
60
61def scene_objects(table_path):
62 return [
63 table_object(table_path),
64 make_box("red_cube", 0.35, 0.10, 0.03, 0.03, 0.03, (1.0, 0.2, 0.2)),
65 make_box("green_cube", 0.35, -0.10, 0.03, 0.03, 0.03, (0.2, 1.0, 0.2)),
66 make_box("blue_cube", 0.35, 0.30, 0.04, 0.04, 0.04, (0.2, 0.2, 1.0)),
67 make_sphere("orange_sphere", -0.20, 0.20, 0.035, (1.0, 0.55, 0.0)),
68 make_sphere("purple_sphere", -0.20, -0.20, 0.025, (0.7, 0.0, 0.9)),
69 ]
70
71
72def build_env(model_path: str, gripper_path: str, table_path: str) -> tuple[mjk.Env, mjk.Robot]:
73 spec = mjk.SceneSpec()
74 spec.timestep = 0.002
75 spec.add_floor = True
76 spec.add_skybox = True
77 spec.objects = scene_objects(table_path)
78 robot_spec = mjk.RobotSpec()
79 robot_spec.path = model_path
80 robot_spec.pos = [0.0, 0.0, SURFACE_Z]
81 robot_spec.attachments = [attachment_gripper(gripper_path)]
82 spec.robots = [robot_spec]
83 overview = mjk.CameraSpec()
84 overview.name = "overview"
85 overview.pos = [0.0, -0.6, 1.6]
86 overview.euler = [34.0, 0.0, 0.0]
87 overview.fovy = 45.0
88 side = mjk.CameraSpec()
89 side.name = "side"
90 side.pos = [-1.0, 0.0, 1.1]
91 side.euler = [0.0, -68.0, 0.0]
92 side.fovy = 45.0
93 spec.cameras = [overview, side]
94 env = mjk.Env.build(spec)
95 tool = mjk.ToolFrameSpec()
96 tool.tool_body = "g_base"
97 tool.tcp_site = "g_pinch"
98 robot = env.create_robot("base_link", "bracelet_link", tool=tool)
99 return env, robot
100
101
102def run_loop(env: mjk.Env, robot: mjk.Robot, step_fn, *, duration: float, gui: bool) -> None:
103 if gui:
104 viewer = mjk.SimulateViewer.open(robot, "ex_table_scene.py")
105 prev = env.time()
106 try:
107 while viewer.is_running():
108 if env.time() < prev - 1e-6:
109 env.reset()
110 prev = env.time()
111 step_fn()
112 if not viewer.step():
113 break
114 finally:
115 viewer.close()
116 return
117 end = env.time() + duration
118 while env.time() < end:
119 step_fn()
120 robot.step()
121
122
123def main() -> int:
124 parser = argparse.ArgumentParser()
125 parser.add_argument("--gui", action="store_true")
126 args = parser.parse_args()
127
128 env, robot = build_env(
129 mjk.menagerie.model_path("kinova_gen3", env_var="MJ_KDL_MODEL"),
130 mjk.menagerie.asset_path("robotiq_2f85/2f85.xml", env_var="MJ_KDL_GRIPPER"),
131 mjk.menagerie.asset_path("table.xml", env_var="MJ_KDL_TABLE"),
132 )
133 try:
134 robot.ctrl_mode = mjk.CtrlMode.TORQUE
135 env.on_reset = lambda ctx: robot.set_joint_pos(HOME_POSE, call_forward=False)
136 env.reset()
137
138 top = env.site_frame(mjk.scene_object_site_name(env.spec.objects[0], "table_top"))
139 print(f"table top z = {top.p.z():.3f}")
140 print(f"cameras: {' '.join(env.camera_names())}")
141
142 def step():
143 robot.update()
144 robot.jnt_trq_cmd = robot.gravity_torques(-9.81)
145 if env.has_actuator("g_fingers_actuator"):
146 env.set_actuator_ctrl(
147 "g_fingers_actuator", 255.0 if math.fmod(env.time(), 6.0) < 3.0 else 0.0
148 )
149
150 run_loop(env, robot, step, duration=1.0, gui=args.gui)
151 finally:
152 env.close()
153 return 0
154
155
156if __name__ == "__main__":
157 raise SystemExit(main())
mjk.AttachmentSpec attachment_gripper(str path)
None run_loop(mjk.Env env, mjk.Robot robot, step_fn, *, float duration, bool gui)
scene_objects(table_path)
mjk.SceneObject make_sphere(name, x, y, radius, color)
tuple[mjk.Env, mjk.Robot] build_env(str model_path, str gripper_path, str table_path)
mjk.SceneObject table_object(str path)
mjk.SceneObject make_box(name, x, y, hx, hy, hz, color)