Repository navigation
IKPy v4.3.0
What's new in v4.3.0
🎯 A new import API: base and tip
The way a chain is imported from a robot description has been redesigned. Until now, Chain.from_urdf_file took base_elements, an ordered list of link and joint names to follow, alternating links and joints, with base_element_type to say what the first name was, and the parser went on with the first child of each element once the list was exhausted, which picked a branch by file order; from_mjcf_file and from_bvh_file each had their own variant of it. All three now share one vocabulary: a robot description is a tree, and the path from a base to a tip is unique, so the two names are all it takes to select a chain, in every format:
# Before
chain = Chain.from_urdf_file("baxter.urdf", base_elements=["base", "torso_t0", "torso", "left_torso_arm_mount", "left_arm_mount", "left_s0", ...], last_link_vector=[0, 0, 0.1])
# Now
chain = Chain.from_urdf_file("baxter.urdf", base="base", tip="left_gripper", tip_offset=[0, 0, 0.1])
chain = Chain.from_mjcf_file("ur5e.xml", base="base", tip="wrist_3_link")
chain = Chain.from_bvh_file("walk.bvh", base="Hips", tip="LeftHand")baseis the element where the chain starts,tipthe element where it ends; the path in between is found automatically.basedefaults to the root of the file andtipto the only leaf belowbase; when the tree branches, the error lists the leaves to choose from, instead of silently following the first child.- In a URDF,
baseandtipname a link or a joint. When a joint and its child link share a name, the name means the link, and{"name": "left_hand", "type": "joint"}says otherwise. tip_offsetreplaceslast_link_vector, same meaning: a fixed translation at the end of the chain, typically the tool center point.- The former
base_elements,base_element_typeandlast_link_vectorkeep working exactly as before, with aDeprecationWarningthat shows the equivalent call; they will be removed in 5.0. Mixing the two forms raises. - The selection arguments are now keyword-only:
Chain.from_urdf_file(file, ["base"])raises aTypeErrorinstead of guessing. - Chain JSON files written by
to_json_fileuse a v2 format withbase,tipandtip_offset; v1 files, such as the ones shipped inresources/, still load, without a warning. ikpy.selectionholds the shared vocabulary and the tree helpers behind the three parsers.
🔀 Multi-start: several starting points, the best solution
The optimizer is local and converges to the solution closest to its starting point. initial_position now also accepts several starting points, and inverse_kinematics returns the best of the solutions reached from them:
chain.inverse_kinematics(target, initial_position=q) # unchanged: one configuration, one solution
chain.inverse_kinematics(target, initial_position=20) # 20 starts drawn in the joint limits
chain.inverse_kinematics(target, initial_position={"points": [q], "n": 9, "seed": 0, "around": q, "radius": 0.5})
chain.inverse_kinematics(target, initial_position=starts) # an array of shape (n_starts, n_links)To get every distinct solution of a target rather than the best one (elbow up and elbow down, wrist flipped...), chain._inverse_kinematics_solutions_frame(frame, initial_position=20, max_error=1e-3) returns them sorted by error; it is kept out of the main API but documented for that use. Closes #144.
🛤️ Trajectories
inverse_kinematics_trajectory_frame solves a sequence of frames, each step starting from the previous solution, so the joint motion follows one branch of solutions instead of jumping, and returns a (n_steps, n_links) array. geometry.interpolate_frames builds the frames between two poses (straight line, constant-speed rotation), and any list of frames works, such as the waypoints of a path planner. A multi-start on the first step picks the branch the trajectory then follows; regularization_parameter trades a little accuracy for a smoother joint motion. Closes #129, #158 and #133.
🤖 URDF conventions aligned on ROS
Checked against the Panda, Baxter, KUKA iiwa, xArm6, Husky, Laikago and R2D2 descriptions: a non-unit joint axis is normalized with a warning (it used to give a wrong rotation in silence), floating and planar joints are treated as fixed joints with a warning, as KDL does, and a xacro file is refused with a message saying to expand it first. The Panda description joins the resources. mimic joints are the remaining gap, tracked in #188.
🧰 Helpers
ikpy.inverse_kinematics.target_error gives the residual of a configuration as the solver sees it, Chain.sample_initial_positions draws starting points inside the joint limits, and ikpy.selection holds the tree helpers shared by the parsers.