16HOME = [0.0, 0.2618, 3.1416, -2.2689, 0.0, 0.9599, 1.5708]
29 table = mjk.SceneObject()
31 table.mjcf_path = mjk.menagerie.asset_path(
"table.xml", env_var=
"MJ_KDL_TABLE")
32 table.pos = [0.0, 0.0, SURFACE_Z]
35 cube = mjk.SceneObject()
37 cube.shape = mjk.Shape.BOX
38 cube.size = [0.02, 0.02, 0.02]
39 cube.pos = CUBE_START[:]
40 cube.rgba = [0.1, 0.35, 1.0, 1.0]
42 cube.condim = mjk.Condim.Torsional
43 cube.friction = [0.8, 0.02, 0.001]
45 attach = mjk.AttachmentSpec()
46 attach.mjcf_path = mjk.menagerie.asset_path(
"robotiq_2f85/2f85.xml", env_var=
"MJ_KDL_GRIPPER")
47 attach.attach_to = mjk.AttachTarget(mjk.AttachKind.Site,
"pinch_site")
50 spec = mjk.SceneSpec()
53 spec.add_skybox =
True
54 spec.objects = [table, cube]
55 robot_spec = mjk.RobotSpec()
56 robot_spec.path = mjk.menagerie.model_path(
"kinova_gen3", env_var=
"MJ_KDL_MODEL")
57 robot_spec.pos = [0.0, 0.0, SURFACE_Z]
58 robot_spec.attachments = [attach]
59 spec.robots = [robot_spec]
61 env = mjk.Env.build(spec)
62 tool = mjk.ToolFrameSpec()
63 tool.tool_body =
"g_base"
64 tool.tcp_site =
"g_pinch"
65 robot = env.create_robot(
"base_link",
"bracelet_link", tool=tool)
92def achd_step(robot, chain, fk, achd, rnea, alpha, target, err_prev, first_pid) -> None:
95 q =
jnt(robot.jnt_pos_msr)
96 qd =
jnt(robot.jnt_vel_msr)
99 fk.JntToCart(q, current)
100 err = kdl.diff(current, target)
102 e = [err.vel.x(), err.vel.y(), err.vel.z(), err.rot.x(), err.rot.y(), err.rot.z()]
106 de = [(e[i] - err_prev[i]) / dt
for i
in range(6)]
109 beta = kdl.JntArray(6)
110 beta[0] =
clamp_abs(KP_LIN * e[0] + KD_LIN * de[0], BETA_LIN_MAX)
111 beta[1] =
clamp_abs(KP_LIN * e[1] + KD_LIN * de[1], BETA_LIN_MAX)
112 beta[2] =
clamp_abs(KP_LIN * e[2] + KD_LIN * de[2], BETA_LIN_MAX)
113 beta[3] =
clamp_abs(KP_ROT * e[3] + KD_ROT * de[3], BETA_ROT_MAX)
114 beta[4] =
clamp_abs(KP_ROT * e[4] + KD_ROT * de[4], BETA_ROT_MAX)
115 beta[5] =
clamp_abs(KP_ROT * e[5] + KD_ROT * de[5], BETA_ROT_MAX)
117 qdd = kdl.JntArray(n)
119 constraint_tau = kdl.JntArray(n)
120 f_ext = [kdl.Wrench.Zero()
for _
in range(chain.getNrOfSegments())]
121 if achd.CartToJnt(q, qd, qdd, alpha, beta, f_ext, ff, constraint_tau) < 0:
122 raise RuntimeError(
"PyKDL ACHD failed")
124 tau = kdl.JntArray(n)
125 if rnea.CartToJnt(q, qd, qdd, f_ext, tau) < 0:
126 raise RuntimeError(
"PyKDL RNEA failed")
127 robot.jnt_trq_cmd = [
clamp_abs(tau[i], TAU_MAX)
for i
in range(n)]
142def run_phase(env, robot, chain, fk, achd, rnea, alpha, phase, viewer, state) -> bool:
143 print(f
"State: {phase['name']}")
144 start = robot.fk_frame()
148 while env.time() - t0 < phase[
"duration"]:
149 t =
smoothstep((env.time() - t0) / phase[
"duration"])
150 target = kdl.addDelta(start, kdl.diff(start, phase[
"target"]), t)
151 achd_step(robot, chain, fk, achd, rnea, alpha, target, err_prev, first_pid)
152 if env.has_actuator(
"g_fingers_actuator"):
153 env.set_actuator_ctrl(
"g_fingers_actuator", phase[
"gripper"])
154 if viewer
is not None and not viewer.is_running():
156 if not step_once(env, robot, viewer, state):
162 parser = argparse.ArgumentParser()
163 parser.add_argument(
"--gui", action=
"store_true")
164 args = parser.parse_args()
168 chain = robot.kdl_chain()
169 fk = kdl.ChainFkSolverPos_recursive(chain)
170 achd = kdl.ChainHdSolver_Vereshchagin_Fixed_Joint(
171 chain, kdl.Twist(kdl.Vector(0.0, 0.0, 9.81), kdl.Vector.Zero()), 6
173 rnea = kdl.ChainIdSolver_RNE(chain, kdl.Vector(0.0, 0.0, -9.81))
176 robot.ctrl_mode = mjk.CtrlMode.TORQUE
179 robot.set_joint_pos(HOME, call_forward=
False)
180 env.set_body_pose(
"cube", CUBE_START)
181 if env.has_actuator(
"g_fingers_actuator"):
182 env.set_actuator_ctrl(
"g_fingers_actuator", 0.0)
184 env.on_reset = on_reset
188 grasp_rot = robot.fk_frame().M
190 def target(x: float, y: float, z: float) -> kdl.Frame:
191 return kdl.Frame(grasp_rot, kdl.Vector(x, y, z))
194 {
"name":
"HOME",
"target": robot.fk_frame(),
"duration": 0.8,
"gripper": 0.0},
195 {
"name":
"PICK_ABOVE",
"target": target(0.40, 0.0, 0.24),
"duration": 2.0,
"gripper": 0.0},
196 {
"name":
"PICK",
"target": target(0.40, 0.0, 0.04),
"duration": 1.8,
"gripper": 0.0},
197 {
"name":
"CLOSE",
"target": target(0.40, 0.0, 0.04),
"duration": 1.0,
"gripper": 255.0},
198 {
"name":
"LIFT",
"target": target(0.40, 0.0, 0.34),
"duration": 1.6,
"gripper": 255.0},
199 {
"name":
"PLACE_ABOVE",
"target": target(0.40, 0.24, 0.24),
"duration": 1.8,
"gripper": 255.0},
200 {
"name":
"PLACE",
"target": target(0.40, 0.24, 0.04),
"duration": 1.8,
"gripper": 255.0},
201 {
"name":
"OPEN",
"target": target(0.40, 0.24, 0.04),
"duration": 0.8,
"gripper": 0.0},
202 {
"name":
"RETREAT",
"target": target(0.40, 0.24, 0.24),
"duration": 1.2,
"gripper": 0.0},
205 state = {
"prev": env.time()}
207 viewer = mjk.SimulateViewer.open(robot,
"ex_achd_pick_place.py")
209 while viewer.is_running():
212 if not run_phase(env, robot, chain, fk, achd, rnea, alpha, phase, viewer, state):
215 except ResetRequested:
217 except StopIteration:
223 if not run_phase(env, robot, chain, fk, achd, rnea, alpha, phase,
None, state):
225 cube = env.body_frame(
"cube")
226 print(f
"cube final position: {[round(v, 3) for v in [cube.p.x(), cube.p.y(), cube.p.z()]]}")