gen_sim_arms.py
Go to the documentation of this file.
00001 
00002 import numpy as np, math
00003 from threading import RLock
00004 import sys, copy
00005 import matplotlib.pyplot as pp
00006 
00007 import roslib; roslib.load_manifest('hrl_software_simulation_darpa_m3')
00008 
00009 import rospy
00010 import PyKDL as kdl
00011 
00012 from equilibrium_point_control.hrl_arm import HRLArm, HRLArmKinematics
00013 
00014 import hrl_lib.geometry as hg
00015 import hrl_lib.kdl_utils as ku
00016 import hrl_lib.viz as hv
00017 
00018 from hrl_msgs.msg import FloatArrayBare
00019 from visualization_msgs.msg import Marker
00020 from hrl_haptic_manipulation_in_clutter_msgs.msg import MechanicalImpedanceParams
00021 
00022 
00023 class ODESimArm(HRLArm):
00024     def __init__(self, d_robot):
00025         rospy.loginfo("Loading ODESimArm")
00026         kinematics = RobotSimulatorKDL(d_robot) # KDL chain.
00027         HRLArm.__init__(self, kinematics)
00028 
00029         self.jep_pub = rospy.Publisher('/sim_arm/command/jep', FloatArrayBare)
00030         self.cep_marker_pub = rospy.Publisher('/sim_arm/viz/cep', Marker)
00031 
00032         self.impedance_pub = rospy.Publisher('/sim_arm/command/joint_impedance',
00033                                              MechanicalImpedanceParams)
00034 
00035         rospy.Subscriber('/sim_arm/joint_angles', FloatArrayBare,
00036                          self.joint_states_cb)
00037         rospy.Subscriber('/sim_arm/joint_angle_rates', FloatArrayBare,
00038                          self.joint_rates_cb)
00039         rospy.Subscriber('/sim_arm/jep', FloatArrayBare, self.jep_cb)
00040         rospy.Subscriber('/sim_arm/joint_impedance', MechanicalImpedanceParams,
00041                          self.impedance_params_cb)
00042         rospy.Subscriber ("/delta_jep_mpc_cvxgen", FloatArrayBare, self.set_delta_ep_ros)
00043 
00044 
00045         rospy.sleep(1.)
00046         rospy.loginfo("Finished loading SimpleArmManger")
00047 
00048     def jep_cb(self, msg):
00049         with self.lock:
00050             self.ep = copy.copy(msg.data)
00051 
00052     def joint_states_cb(self, data):
00053         with self.lock:
00054             self.q = copy.copy(data.data)
00055 
00056     def joint_rates_cb(self, data):
00057         with self.lock:
00058             self.qdot = copy.copy(data.data)
00059 
00060     def impedance_params_cb(self, data):
00061         with self.lock:
00062             self.kp = copy.copy(data.k_p.data)
00063             self.kd = copy.copy(data.k_d.data)
00064 
00065     def get_joint_velocities(self):
00066         with self.lock:
00067             qdot = copy.copy(self.qdot)
00068         return qdot
00069 
00070     def set_ep(self, jep, duration=0.15):
00071         f = FloatArrayBare(jep)
00072         self.jep_pub.publish(f)
00073         self.publish_rviz_markers()
00074 
00075     def set_delta_ep_ros(self, msg):
00076         delta_jep = copy.copy(msg.data)
00077         if delta_jep is None or len(delta_jep) != 3:
00078             raise RuntimeError("set_jep value is " + str(delta_jep))
00079         
00080         with self.lock:
00081           if self.ep == None:
00082             self.ep = self.get_joint_angles()
00083             
00084           jep = (np.array(self.ep) + np.array(delta_jep)).tolist()
00085           
00086           f = FloatArrayBare(jep)
00087           self.jep_pub.publish(f)
00088 
00089     def publish_rviz_markers(self):
00090         # publish the CEP marker.
00091         jep = self.get_ep()
00092         cep, r = self.kinematics.FK(jep)
00093         o = np.matrix([0.,0.,0.,1.]).T
00094         cep_marker = hv.single_marker(cep, o, 'sphere',
00095                         '/torso_lift_link', color=(0., 0., 1., 1.),
00096                         scale = (0.02, 0.02, 0.02), duration=0.)
00097 
00098         cep_marker.header.stamp = rospy.Time.now()
00099         self.cep_marker_pub.publish(cep_marker)
00100 
00101     # kp, kd - list or np array of stiffness and damping.
00102     def set_joint_impedance(self, kp, kd):
00103         im = MechanicalImpedanceParams()
00104         im.k_p.data = kp
00105         im.k_d.data = kd
00106         self.impedance_pub.publish(im)
00107 
00108 
00109 ##
00110 # KDL for kinematics etc.
00111 class RobotSimulatorKDL(HRLArmKinematics):
00112     def __init__(self, d_robot):
00113         HRLArmKinematics.__init__(self, len(d_robot.b_jt_anchor))
00114         self.arm_type = "simulated"
00115         self.d_robot = d_robot
00116         self.right_chain = self.create_right_chain()
00117         fk, ik_v, ik_p, jac = self.create_solvers(self.right_chain)
00118 
00119         self.right_fk = fk
00120         self.right_ik_v = ik_v
00121         self.right_ik_p = ik_p
00122         self.right_jac = jac
00123         self.right_tooltip = np.matrix([0.,0.,0.]).T
00124 
00125         # marc joint limits.
00126         self.min_jtlim_arr = d_robot.b_jt_limits_min
00127         self.max_jtlim_arr = d_robot.b_jt_limits_max
00128 
00129 
00130     def create_right_chain(self):
00131         height = 0.0
00132         linkage_offset_from_ground = np.matrix([0., 0., height]).T
00133         self.linkage_offset_from_ground = linkage_offset_from_ground
00134         self.n_jts = len(self.d_robot.b_jt_anchor)
00135         rospy.loginfo("number of joints is :"+str(self.n_jts))
00136 
00137         ee_location = self.d_robot.ee_location 
00138         b_jt_anchor = self.d_robot.b_jt_anchor
00139         b_jt_axis = self.d_robot.b_jt_axis
00140 
00141         ch = kdl.Chain()
00142         prev_vec = np.copy(linkage_offset_from_ground.A1)
00143         n = len(self.d_robot.b_jt_anchor)
00144 
00145         for i in xrange(n-1):
00146             if b_jt_axis[i][0] == 1 and b_jt_axis[i][1] == 0 and b_jt_axis[i][2] == 0:
00147                 kdl_jt = kdl.Joint(kdl.Joint.RotX)
00148             elif b_jt_axis[i][0] == 0 and b_jt_axis[i][1] == 1 and b_jt_axis[i][2] == 0:
00149                 kdl_jt = kdl.Joint(kdl.Joint.RotY)
00150             elif b_jt_axis[i][0] == 0 and b_jt_axis[i][1] == 0 and b_jt_axis[i][2] == 1:
00151                 kdl_jt = kdl.Joint(kdl.Joint.RotZ)
00152             else:
00153                 print "can't do off-axis joints yet!!!"
00154 
00155             np_vec = np.array(b_jt_anchor[i+1])
00156             diff_vec = np_vec-prev_vec
00157             prev_vec = np_vec
00158             kdl_vec = kdl.Vector(diff_vec[0], diff_vec[1], diff_vec[2])            
00159             ch.addSegment(kdl.Segment(kdl_jt, kdl.Frame(kdl_vec)))
00160 
00161         np_vec = np.copy(ee_location.A1)
00162         diff_vec = np_vec-prev_vec
00163 
00164         if b_jt_axis[n-1][0] == 1 and b_jt_axis[n-1][1] == 0 and b_jt_axis[n-1][2] == 0:
00165             kdl_jt = kdl.Joint(kdl.Joint.RotX)
00166         elif b_jt_axis[n-1][0] == 0 and b_jt_axis[n-1][1] == 1 and b_jt_axis[n-1][2] == 0:
00167             kdl_jt = kdl.Joint(kdl.Joint.RotY)
00168         elif b_jt_axis[n-1][0] == 0 and b_jt_axis[n-1][1] == 0 and b_jt_axis[n-1][2] == 1:
00169             kdl_jt = kdl.Joint(kdl.Joint.RotZ)
00170         else:
00171             print "can't do off-axis joints yet!!!"
00172 
00173         kdl_vec = kdl.Vector(diff_vec[0], diff_vec[1], diff_vec[2])            
00174         ch.addSegment(kdl.Segment(kdl_jt, kdl.Frame(kdl_vec)))
00175         
00176         return ch
00177 
00178     def create_solvers(self, ch):
00179          fk = kdl.ChainFkSolverPos_recursive(ch)
00180          ik_v = kdl.ChainIkSolverVel_pinv(ch)
00181          ik_p = kdl.ChainIkSolverPos_NR(ch, fk, ik_v)
00182          jac = kdl.ChainJntToJacSolver(ch)
00183          return fk, ik_v, ik_p, jac
00184 
00185     def FK_kdl(self, q, link_number):
00186         fk = self.right_fk
00187         endeffec_frame = kdl.Frame()
00188         kinematics_status = fk.JntToCart(q, endeffec_frame,
00189                                          link_number)
00190         if kinematics_status >= 0:
00191             return endeffec_frame
00192         else:
00193             rospy.loginfo('Could not compute forward kinematics.')
00194             return None
00195 
00196     ## returns point in torso lift link.
00197     def FK_vanilla(self, q, link_number=None):
00198         if link_number == None:
00199             link_number = self.n_jts
00200         link_number = min(link_number, self.n_jts)
00201 
00202         q = self.list_to_kdl(q)
00203         frame = self.FK_kdl(q, link_number)
00204         pos = frame.p
00205         pos = ku.kdl_vec_to_np(pos)
00206         pos = pos + self.linkage_offset_from_ground
00207         m = frame.M
00208         rot = ku.kdl_rot_to_np(m)
00209 
00210         return pos, rot
00211 
00212     def kdl_to_list(self, q):
00213         if q == None:
00214             return None
00215         n = self.n_jts
00216         q_list = [0] * n
00217         for i in xrange(n):
00218             q_list[i] = q[i]
00219         return q_list
00220 
00221     def list_to_kdl(self, q):
00222         if q == None:
00223             return None
00224         n = len(q)
00225         q_kdl = kdl.JntArray(n)
00226         for i in xrange(n):
00227             q_kdl[i] = q[i]
00228         return q_kdl
00229 
00230     ## compute Jacobian at point pos. 
00231     # p is in the ground coord frame.
00232     def jacobian(self, q, pos=None):
00233         if pos == None:
00234             pos = self.FK(q)[0]
00235 
00236         v_list = []
00237         w_list = []
00238 
00239         #ee, r = self.FK(q)
00240         #pos = ee
00241 
00242         for i in xrange(self.n_jts):
00243             p, rot = self.FK_vanilla(q, i)
00244             r = pos - p
00245             z_idx = self.right_chain.getSegment(i).getJoint().getType() - 1
00246             z = rot[:, z_idx]
00247             v_list.append(np.matrix(np.cross(z.A1, r.A1)).T)
00248             w_list.append(z)
00249 
00250         J = np.row_stack((np.column_stack(v_list), np.column_stack(w_list)))
00251         return J
00252 
00253     def clamp_to_joint_limits(self, q):
00254         return np.clip(q, self.min_jtlim_arr, self.max_jtlim_arr)
00255 
00256     def within_joint_limits(self, q, delta_list=None):
00257         if delta_list == None:
00258             delta_list = [0]*len(q)
00259 
00260         min_arr = self.min_jtlim_arr
00261         max_arr = self.max_jtlim_arr
00262 
00263         q_arr = np.array(q)
00264         d_arr = np.array(delta_list)
00265 
00266         return np.all((q_arr <= max_arr+d_arr, q_arr >= min_arr+d_arr))
00267 
00268     def get_joint_limits(self):
00269         return self.min_jtlim_arr, self.max_jtlim_arr
00270 
00271     # plot the arm using matplotlib.
00272     # flip_xy - x will point up and +ve y will be to the left. This is
00273     # to match how we look at the arm in rviz.
00274     def plot_arm(self, q, color, alpha, flip_xy, linewidth=2):
00275         pts = [[0.,0.,0.]]
00276         for i in range(len(q)):
00277             p,_ = self.FK(q, i+1)
00278             pts.append(p.A1.tolist())
00279 
00280         pts_2d = np.array(pts)[:,0:2]
00281         direc_list = (pts_2d[1:] - pts_2d[:-1]).tolist()
00282 
00283         for i, d in enumerate(direc_list):
00284             d_vec = np.matrix(d).T
00285             d_vec = d_vec / np.linalg.norm(d_vec)
00286             w = np.cross(d_vec.A1, np.array([0., 0., 1.])) * 0.03/2
00287             x1 = pts_2d[i,0]
00288             y1 = pts_2d[i,1]
00289             x2 = pts_2d[i+1,0]
00290             y2 = pts_2d[i+1,1]
00291 
00292             x_data = np.array([x1+w[0], x1-w[0], x2-w[0], x2+w[0], x1+w[0]])
00293             y_data = np.array([y1+w[1], y1-w[1], y2-w[1], y2+w[1], y1+w[1]])
00294 
00295             if flip_xy:
00296                 tmp = y_data
00297                 y_data = x_data
00298                 x_data = -tmp
00299 
00300             pp.plot(x_data, y_data, '-', alpha=alpha, color=color,
00301                     linewidth=linewidth)
00302 
00303 
00304 if __name__ == '__main__':
00305     rospy.init_node('ode_arms_test')
00306     import hrl_common_code_darpa_m3.robot_config.six_link_planar as d_robot
00307     ode_arm = ODESimArm(d_robot)
00308 
00309     # test_jep = np.radians([30., 20., 45.])
00310     test_jep = np.radians(np.zeros(ode_arm.kinematics.n_jts))
00311     # test_jep = np.radians([90]*6)    
00312     # test_jep = np.radians([0., 0., 0.])
00313     p, _ = ode_arm.kinematics.FK(test_jep, ode_arm.kinematics.n_jts)
00314     print 'p:', p.A1
00315 
00316     ode_arm.set_ep(test_jep)
00317 
00318 
00319 


hrl_software_simulation_darpa_m3
Author(s): Marc Killpack and Advait Jain. Advisor: Prof. Charlie Kemp. Healthcare Robotics Lab, Georgia Tech
autogenerated on Wed Nov 27 2013 11:35:07