Would it be possible to use the IK tutorials and get the joint states for a point without having to move the base? When I run the IK, the base moves as well. I tried setting the velocity and the axis of the joint_base_translation to 0. But that did not work. Removing the joint leads to an error due to mismatch in size. How would I solve this? Thank you.
Hey @Shashank_Shiva, glad to hear you’re using the code from the IK Tutorial. The way to fix the base is to remove the joint_base_translation joint. It sounds like you’ve already tried this? Would you share the error you’re seeing? Could you link to your code?
Hey @bshah,
This is the error I get when I comment out the joint_base_translation part of the code.
Traceback (most recent call last):
File "final_inv.py", line 121, in <module>
q_mid = chain.inverse_kinematics(target_point, pretarget_orientation, orientation_mode='all', initial_position=q_init)
File "/home/hello-robot/anaconda3/envs/myenv/lib/python3.8/site-packages/ikpy/chain.py", line 151, in inverse_kinematics
return self.inverse_kinematics_frame(target=frame_target, orientation_mode=orientation_mode, no_position=no_position, **kwargs)
File "/home/hello-robot/anaconda3/envs/myenv/lib/python3.8/site-packages/ikpy/chain.py", line 177, in inverse_kinematics_frame
return ik.inverse_kinematic_optimization(self, target, starting_nodes_angles=initial_position, **kwargs)
File "/home/hello-robot/anaconda3/envs/myenv/lib/python3.8/site-packages/ikpy/inverse_kinematics.py", line 149, in inverse_kinematic_optimization
res = scipy.optimize.least_squares(optimize_total, chain.active_from_full(starting_nodes_angles), bounds=real_bounds)
File "/home/hello-robot/anaconda3/envs/myenv/lib/python3.8/site-packages/scipy/optimize/_lsq/least_squares.py", line 820, in least_squares
f0 = fun_wrapped(x0)
File "/home/hello-robot/anaconda3/envs/myenv/lib/python3.8/site-packages/scipy/optimize/_lsq/least_squares.py", line 815, in fun_wrapped
return np.atleast_1d(fun(x, *args, **kwargs))
File "/home/hello-robot/anaconda3/envs/myenv/lib/python3.8/site-packages/ikpy/inverse_kinematics.py", line 102, in optimize_function
fk = optimize_basis(x)
File "/home/hello-robot/anaconda3/envs/myenv/lib/python3.8/site-packages/ikpy/inverse_kinematics.py", line 49, in optimize_basis
y = chain.active_to_full(x, starting_nodes_angles)
File "/home/hello-robot/anaconda3/envs/myenv/lib/python3.8/site-packages/ikpy/chain.py", line 337, in active_to_full
np.place(full_joints, self.active_links_mask, active_joints)
File "<__array_function__ internals>", line 180, in place
File "/home/hello-robot/anaconda3/envs/myenv/lib/python3.8/site-packages/numpy/lib/function_base.py", line 1953, in place
return _insert(arr, mask, vals)
ValueError: place: mask and data must be the same size
I did not add any link name or joint time to the removal list.
Link to the current code: inversekinematics/final_inv.py at main · shashankshiva8/inversekinematics · GitHub
Thank you
Thanks @Shashank_Shiva. So the ValueError
exception alone isn’t clearly communicating what went wrong, but paired with the traceback, we can understand. Inside the IKPy library, there’s a call to Numpy’s np.place()
method, where the the data is full_joints
and the mask if self.active_links_mask
. The exception says ValueError: mask and data must be the same size
, or in other words, there’s a mismatch in array length between these two variables. The self.active_links_mask
is actually available to us, and if we printed it out, we would see something like: [False, True, False, True, True, ...]
, where each entry corresponds to a joint in the URDF, and the boolean tells IKPy whether it needs to solve for that joint or not (i.e. active or not). By default, all fixed joints are inactive and all prismatic/revolute joints are active. The data variable full_joints
is not known to us, but looking at the traceback again, it’s a good guess that it might be starting_nodes_angles
which would come from the initial guess that we give IKPy’s optimizer.
On the line where we call inverse_kinematics()
, we pass in an initial guess for the optimizer to begin solving from, called q_init
.
q_init
comes from the get_current_configuration()
method and is actually an array where each entry corresponds to a joint we expect is in the URDF, and the float value is the position of the joint in its range.
Since get_current_configuration()
was written for a URDF that contained the “joint_base_translation” joint, the array returned looks like [0.0, q_base, 0.0, q_lift, 0.0, q_arml, q_arml, q_arml, q_arml, q_yaw, 0.0, 0.0]
, where q_base
is 0.0 because we want the optimizer to start solving from no base motion being required. By commenting out the code that adds “joint_base_translation”, we’ve introduced a mismatch in array sizes, which is why we saw that ValueError
exception. Since we don’t need q_base
, the solution is to return the configuration array without “joint_base_translation”: [0.0, 0.0, q_lift, 0.0, q_arml, q_arml, q_arml, q_arml, q_yaw, 0.0, 0.0]
.
@bshah That makes sense on why I am having the mismatch in arrays. I will work on the changing the get_configuration part and get back to you. Thank you.