Mujoco KDL Wrapper  0.2.2
MuJoCo + KDL bridge for robot kinematics and dynamics
Loading...
Searching...
No Matches
ex_impedance.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2"""Joint-space impedance example ported from src/examples/ex_impedance.cpp.
3
4tau = Kp*(q_home - q) - Kd*qdot + g_kdl, applied in TORQUE mode, with the
5gripper cycling open/closed. An Env on_reset hook re-homes the arm.
6"""
7
8from __future__ import annotations
9
10import argparse
11import math
12
13import mj_kdl_wrapper as mjk
14
15HOME_POSE = [0.0, 0.2618, 3.1416, -2.2689, 0.0, 0.9599, 1.5708]
16
17KP = [100, 200, 100, 200, 100, 200, 100]
18KD = [10, 20, 10, 20, 10, 20, 10]
19
20
21def attachment_gripper(path: str) -> mjk.AttachmentSpec:
22 spec = mjk.AttachmentSpec()
23 spec.mjcf_path = path
24 spec.attach_to = mjk.AttachTarget(mjk.AttachKind.Site, "pinch_site")
25 spec.prefix = "g_"
26 return spec
27
28
29def build_env(model_path: str, gripper_path: str) -> tuple[mjk.Env, mjk.Robot]:
30 spec = mjk.SceneSpec()
31 spec.timestep = 0.002
32 spec.add_floor = True
33 spec.add_skybox = True
34 robot_spec = mjk.RobotSpec()
35 robot_spec.path = model_path
36 robot_spec.attachments = [attachment_gripper(gripper_path)]
37 spec.robots = [robot_spec]
38 env = mjk.Env.build(spec)
39 tool = mjk.ToolFrameSpec()
40 tool.tool_body = "g_base"
41 tool.tcp_site = "g_pinch"
42 robot = env.create_robot("base_link", "bracelet_link", tool=tool)
43 return env, robot
44
45
46def apply_pd_gravity(robot: mjk.Robot, target: list[float]) -> None:
47 robot.update()
48 grav = robot.gravity_torques(-9.81)
49 robot.jnt_trq_cmd = [
50 KP[i] * (target[i] - robot.jnt_pos_msr[i]) - KD[i] * robot.jnt_vel_msr[i] + grav[i]
51 for i in range(robot.n_joints)
52 ]
53
54
55def run_loop(env: mjk.Env, robot: mjk.Robot, step_fn, *, duration: float, gui: bool) -> None:
56 if gui:
57 viewer = mjk.SimulateViewer.open(robot, "ex_impedance.py")
58 prev = env.time()
59 try:
60 while viewer.is_running():
61 if env.time() < prev - 1e-6:
62 env.reset()
63 prev = env.time()
64 step_fn()
65 if not viewer.step():
66 break
67 finally:
68 viewer.close()
69 return
70 end = env.time() + duration
71 while env.time() < end:
72 step_fn()
73 robot.step()
74
75
76def main() -> int:
77 parser = argparse.ArgumentParser()
78 parser.add_argument("--gui", action="store_true")
79 args = parser.parse_args()
80
81 env, robot = build_env(
82 mjk.menagerie.model_path("kinova_gen3", env_var="MJ_KDL_MODEL"),
83 mjk.menagerie.asset_path("robotiq_2f85/2f85.xml", env_var="MJ_KDL_GRIPPER"),
84 )
85 try:
86 robot.ctrl_mode = mjk.CtrlMode.TORQUE
87 env.on_reset = lambda ctx: robot.set_joint_pos(HOME_POSE, call_forward=False)
88 env.reset()
89
90 def step():
91 apply_pd_gravity(robot, HOME_POSE)
92 if env.has_actuator("g_fingers_actuator"):
93 env.set_actuator_ctrl(
94 "g_fingers_actuator", 255.0 if math.fmod(env.time(), 6.0) < 3.0 else 0.0
95 )
96
97 run_loop(env, robot, step, duration=3.0, gui=args.gui)
98 print(f"final q: {[round(x, 4) for x in robot.jnt_pos_msr]}")
99 finally:
100 env.close()
101 return 0
102
103
104if __name__ == "__main__":
105 raise SystemExit(main())
tuple[mjk.Env, mjk.Robot] build_env(str model_path, str gripper_path)
None run_loop(mjk.Env env, mjk.Robot robot, step_fn, *, float duration, bool gui)
mjk.AttachmentSpec attachment_gripper(str path)
None apply_pd_gravity(mjk.Robot robot, list[float] target)