Skip to content

Commit

Permalink
Add the IK by optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
buschbapti committed Apr 25, 2017
1 parent de74c56 commit 3f52e1a
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 12 deletions.
16 changes: 8 additions & 8 deletions launch/human_ik.launch
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version="1.0"?>
<launch>
<arg name="human_prefix" default="human" />
<arg name="use_tracik" default="True" />
<arg name="use_optim_ik" default="False" />
<arg name="use_tracik" default="False" />
<arg name="use_optimik" default="True" />

<group if="$(arg use_tracik)">
<!-- <node name="ik_shoulder_center" pkg="human_moveit_config" type="tracik_server" args="$(arg human_prefix)/base $(arg human_prefix)/shoulder_center /ik/tracik/$(arg human_prefix)/shoulder_center" output="screen"/> -->
Expand All @@ -11,17 +11,17 @@
<node name="ik_head_tracik" pkg="human_moveit_config" type="tracik_server" args="$(arg human_prefix)/base $(arg human_prefix)/head /ik/tracik/$(arg human_prefix)/head" output="screen"/>
<node name="ik_left_hand_tracik" pkg="human_moveit_config" type="tracik_server" args="$(arg human_prefix)/shoulder_center $(arg human_prefix)/left_hand /ik/tracik/$(arg human_prefix)/left_hand" output="screen"/>
<node name="ik_right_hand_tracik" pkg="human_moveit_config" type="tracik_server" args="$(arg human_prefix)/shoulder_center $(arg human_prefix)/right_hand /ik/tracik/$(arg human_prefix)/right_hand" output="screen"/>
<node name="ik_server" pkg="human_moveit_config" type="ik_server" args="tracik" output="screen"/>
</group>

<group if="$(arg use_optim_ik)">
<group if="$(arg use_optimik)">
<!-- <node name="ik_shoulder_center" pkg="human_moveit_config" type="optim_ik_server" args="$(arg human_prefix)/base $(arg human_prefix)/shoulder_center /ik/optim/$(arg human_prefix)/shoulder_center" output="screen"/>
<node name="ik_left_elbow" pkg="human_moveit_config" type="optim_ik_server" args="$(arg human_prefix)/shoulder_center $(arg human_prefix)/left_elbow /ik/optim/$(arg human_prefix)/left_elbow" output="screen"/>
<node name="ik_right_elbow" pkg="human_moveit_config" type="optim_ik_server" args="$(arg human_prefix)/shoulder_center $(arg human_prefix)/right_elbow /ik/optim/$(arg human_prefix)/right_elbow" output="screen"/> -->
<node name="ik_head_optim" pkg="human_moveit_config" type="optim_ik_server" args="$(arg human_prefix)/base $(arg human_prefix)/head /ik/optim/$(arg human_prefix)/head" output="screen"/>
<node name="ik_left_hand_optim" pkg="human_moveit_config" type="optim_ik_server" args="$(arg human_prefix)/shoulder_center $(arg human_prefix)/left_hand /ik/optim/$(arg human_prefix)/left_hand" output="screen"/>
<node name="ik_right_hand_optim" pkg="human_moveit_config" type="optim_ik_server" args="$(arg human_prefix)/shoulder_center $(arg human_prefix)/right_hand /ik/optim/$(arg human_prefix)/right_hand" output="screen"/>
<node name="ik_head_optimik" pkg="human_moveit_config" type="optimik_server" args="$(arg human_prefix)/base $(arg human_prefix)/head /ik/optimik/$(arg human_prefix)/head" output="screen"/>
<node name="ik_left_hand_optimik" pkg="human_moveit_config" type="optimik_server" args="$(arg human_prefix)/shoulder_center $(arg human_prefix)/left_hand /ik/optimik/$(arg human_prefix)/left_hand" output="screen"/>
<node name="ik_right_hand_optimik" pkg="human_moveit_config" type="optimik_server" args="$(arg human_prefix)/shoulder_center $(arg human_prefix)/right_hand /ik/optimik/$(arg human_prefix)/right_hand" output="screen"/>
<node name="ik_server" pkg="human_moveit_config" type="ik_server" args="optimik" output="screen"/>
</group>

<node name="ik_server" pkg="human_moveit_config" type="ik_server" output="screen"/>

</launch>
3 changes: 2 additions & 1 deletion script/ik_server
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
from human_moveit_config.optimize_ik import IKOptimizer
from human_moveit_config.srv import GetHumanIK
import rospy
import sys


def main():
rospy.init_node('human_ik_srv')
rospy.sleep(5)
opti = IKOptimizer()
opti = IKOptimizer(type_ik=sys.argv[1])
rospy.Service('compute_human_ik', GetHumanIK, opti.handle_compute_ik_divided)
print "Ready to compute IK"
rospy.spin()
Expand Down
69 changes: 69 additions & 0 deletions script/optimik_server
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/env python
from human_moveit_config.human_model import HumanModel
import rospy
import numpy as np
from tf.transformations import quaternion_inverse
from tf.transformations import quaternion_multiply
from human_moveit_config.srv import GetHumanIKResponse
from human_moveit_config.srv import GetHumanIK
import sys
from scipy.optimize import minimize
from transformations import pose_to_list
from sensor_msgs.msg import JointState


class OptimIK(object):
def __init__(self, base, eef):
self.model = HumanModel()
self.base_name = base
self.eef_name = eef
self.weights = [3, 2, 10, 5]
self.rotation_weight = 1
self.joint_history = []
self.eef_history = []
self.joint_names = self.model.get_joints_chain(self.base_name, self.eef_name)

def _cost_function(self, q, desired_pose):
def quat_log(q):
q_log = q[-1] * q[:-1]
q_log = q_log.tolist()
q_log += [0]
return q_log

def pose_diff(c_pose, des_pose):
pos_cost = np.linalg.norm(np.array(c_pose[0]) - np.array(des_pose[0]))
rot_disp = quat_log(quaternion_multiply(quaternion_inverse(np.array(c_pose[1])), np.array(des_pose[1])))
rot_cost = np.linalg.norm(rot_disp)
return self.weights[0] * pos_cost + self.rotation_weight * self.weights[1] * rot_cost
# get the FK of the model
js = JointState()
js.position = q
js.name = self.joint_names
fk = self.model.forward_kinematic(js, base=self.base_name, links=self.eef_name)
# calculate the cost
cost = 0
cost += pose_diff(fk[self.eef_name], desired_pose)
return cost

def handle_optim_ik(self, req):
def cons_bounds(x):
return abs(x - 3.14159)
desired_pose = req.desired_poses[0]
q_init = [req.seed.position[req.seed.name.index(j)] for j in self.joint_names]
# generate constraints
cons = ({'type': 'ineq', 'fun': cons_bounds})
# call the minimize function from scipy
res = minimize(self._cost_function, q_init, constraints=cons,
args=(pose_to_list(desired_pose),), method='SLSQP',
options={'maxiter': 50, 'ftol': 1e-03})
js = JointState()
js.position = res.x
js.name = self.joint_names
return GetHumanIKResponse(js)


if __name__ == '__main__':
rospy.init_node('optimik_srv')
ik = OptimIK(sys.argv[1], sys.argv[2])
s = rospy.Service(sys.argv[3], GetHumanIK, ik.handle_optim_ik)
rospy.spin()
6 changes: 3 additions & 3 deletions src/human_moveit_config/optimize_ik.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def __init__(self, type_ik="tracik"):
rospy.wait_for_service('/ik/' + type_ik + '/' + l)
self.div_ik_srv[l] = rospy.ServiceProxy('/ik/' + type_ik + '/' + l, GetHumanIK)

def compute_sub_ik(self, group, desired_dict, result, tol=0.1):
def compute_sub_ik(self, group, desired_dict, result, seed, tol=0.1):
# get the desired pose in the correct base frame
base = self.links[group]
tr = desired_dict[group]
Expand Down Expand Up @@ -83,7 +83,7 @@ def compute_sub_ik(self, group, desired_dict, result, tol=0.1):
desired_pose.header.frame_id = base
# try:
# call the srv
res = self.div_ik_srv[group](desired_poses=[desired_pose], tolerance=tol)
res = self.div_ik_srv[group](desired_poses=[desired_pose], tolerance=tol, seed=seed)
joint_state = res.joint_state
# except Exception, e:
# print e
Expand All @@ -106,7 +106,7 @@ def handle_compute_ik_divided(self, req):
threads = [None] * nb_frames
results = {}
for i, frame in enumerate(desired_dict.keys()):
threads[i] = Thread(target=self.compute_sub_ik, args=(frame, desired_dict, results, req.tolerance))
threads[i] = Thread(target=self.compute_sub_ik, args=(frame, desired_dict, results, req.seed, req.tolerance))
threads[i].start()
# join thread results
for i in range(len(threads)):
Expand Down

0 comments on commit 3f52e1a

Please sign in to comment.