Mujoco KDL Wrapper  0.5.1
MuJoCo + KDL bridge for robot kinematics and dynamics
Loading...
Searching...
No Matches
ex_gravity_comp.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2"""KDL gravity compensation on the Gen3; Python counterpart of src/examples/ex_gravity_comp.cpp."""
3
4from __future__ import annotations
5
6import argparse
7
8import PyKDL as kdl
9
10import mj_kdl_wrapper as mjk
11
12HOME_POSE = [0.0, 0.2618, 3.1416, -2.2689, 0.0, 0.9599, 1.5708]
13STEPS = 7500 # 15 s
14MAX_DRIFT = 0.0001 # [m]
15
16
17def joints(values) -> kdl.JntArray:
18 q = kdl.JntArray(len(values))
19 for i, value in enumerate(values):
20 q[i] = value
21 return q
22
23
24def gravity(dyn: kdl.ChainDynParam, q_values) -> list[float]:
25 g = kdl.JntArray(len(q_values))
26 dyn.JntToGravity(joints(q_values), g)
27 return [g[i] for i in range(g.rows())]
28
29
30def main() -> int:
31 parser = argparse.ArgumentParser()
32 parser.add_argument("--gui", action="store_true")
33 args = parser.parse_args()
34
35 spec = mjk.SceneSpec()
36 spec.timestep = 0.002
37 spec.add_floor = True
38 spec.add_skybox = True
39 robot_spec = mjk.RobotSpec()
40 robot_spec.path = str(mjk.ASSETS_DIR / "kinova_gen3/gen3.xml")
41 spec.robots = [robot_spec]
42
43 env = mjk.Env.build(spec)
44 try:
45 robot = env.create_robot("base_link", "bracelet_link")
46 robot.set_control_mode(mjk.CtrlMode.TORQUE)
47 chain = robot.kdl_chain()
48 fk = kdl.ChainFkSolverPos_recursive(chain)
49 dyn = kdl.ChainDynParam(chain, kdl.Vector(0.0, 0.0, spec.gravity_z))
50
51 def on_reset(ctx):
52 robot.set_joint_pos(HOME_POSE)
53 robot.jnt_trq_cmd = gravity(dyn, HOME_POSE)
54
55 env.on_reset = on_reset
56 env.reset()
57 if args.gui:
58 env.open_viewer("ex_gravity_comp.py")
59
60 start = kdl.Frame()
61 fk.JntToCart(joints(HOME_POSE), start)
62 for _ in range(STEPS):
63 env.update()
64 robot.jnt_trq_cmd = gravity(dyn, robot.jnt_pos_msr)
65 if not env.step():
66 break
67 env.pace()
68 env.update()
69
70 end = kdl.Frame()
71 fk.JntToCart(joints(robot.jnt_pos_msr), end)
72 drift = (end.p - start.p).Norm()
73 print(f"EE drift after {STEPS} steps: {drift * 1000:.4f} mm (limit {MAX_DRIFT * 1000} mm)")
74 finally:
75 env.close()
76 if args.gui:
77 return 0
78 ok = drift <= MAX_DRIFT
79 print(f"{'PASS' if ok else 'FAIL'}: the arm holds its pose")
80 return 0 if ok else 1
81
82
83if __name__ == "__main__":
84 raise SystemExit(main())
list[float] gravity(kdl.ChainDynParam dyn, q_values)
kdl.JntArray joints(values)