arm_server.py
Go to the documentation of this file.
00001 #!/usr/bin/python
00002 #
00003 # Copyright (c) 2009, Georgia Tech Research Corporation
00004 # All rights reserved.
00005 # 
00006 # Redistribution and use in source and binary forms, with or without
00007 # modification, are permitted provided that the following conditions are met:
00008 #     * Redistributions of source code must retain the above copyright
00009 #       notice, this list of conditions and the following disclaimer.
00010 #     * Redistributions in binary form must reproduce the above copyright
00011 #       notice, this list of conditions and the following disclaimer in the
00012 #       documentation and/or other materials provided with the distribution.
00013 #     * Neither the name of the Georgia Tech Research Corporation nor the
00014 #       names of its contributors may be used to endorse or promote products
00015 #       derived from this software without specific prior written permission.
00016 # 
00017 # THIS SOFTWARE IS PROVIDED BY GEORGIA TECH RESEARCH CORPORATION ''AS IS'' AND
00018 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00019 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00020 # DISCLAIMED. IN NO EVENT SHALL GEORGIA TECH BE LIABLE FOR ANY DIRECT, INDIRECT,
00021 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00022 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00023 # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00024 # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
00025 # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00026 # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027 #
00028 
00029 # Author: Advait Jain
00030 
00031 # moved this to the top to get PyKDL from the ROS package for the Meka
00032 # modules as well.
00033 import roslib; roslib.load_manifest('hrl_cody_arms')
00034 roslib.load_manifest('force_torque') # Advait hack on Oct 25, 2011
00035 
00036 import force_torque.FTClient as ftc
00037 
00038 
00039 import m3.rt_proxy as m3p
00040 import m3.arm
00041 import m3.toolbox as m3t
00042 import m3.pwr as m3w
00043 import m3.loadx6
00044 
00045 import m3.component_factory as m3f
00046 
00047 import cody_arm_client as ac
00048 
00049 import numpy as np, math
00050 import sys, time, os
00051 import copy
00052 from threading import RLock
00053 
00054 import rospy
00055 
00056 import hrl_lib.transforms as tr
00057 from hrl_msgs.msg import FloatArray
00058 from std_msgs.msg import Header, Bool, Empty
00059 
00060 from sensor_msgs.msg import JointState
00061 
00062 THETA_GC = 5
00063 TORQUE_GC = 4
00064 THETA = 3
00065 OFF = 0 # in OFF mode also, the behavior is strange. Not the same as hitting the estop (Advait, Jan 1 2010)
00066 
00067 
00068 ## 1D kalman filter update.
00069 def kalman_update(xhat, P, Q, R, z):
00070     #time update
00071     xhatminus = xhat
00072     Pminus = P + Q
00073     #measurement update
00074     K = Pminus / (Pminus + R)
00075     xhat = xhatminus + K * (z-xhatminus)
00076     P = (1-K) * Pminus
00077     return xhat, P
00078 
00079 class MekaArmSettings():
00080     def __init__(self, stiffness_list=[0.7,0.7,0.8,0.8,0.3],
00081                  control_mode='theta_gc'):
00082         ''' stiffness_list: list of 5 stiffness values for joints 0-4.
00083             control_mode: 'theta_gc' or 'torque_gc'
00084         '''
00085         self.set_stiffness_scale(stiffness_list)
00086         self.control_mode = control_mode
00087 
00088     def set_stiffness_scale(self, l):
00089         # for safety of wrist roll. Advait Jun 18, 2010.
00090         # changed to 0.2 from 0.3 (Advait, Sept 19, 2010)
00091         l[4] = min(l[4], 0.2)
00092         self.stiffness_list = l
00093 
00094 
00095 class MekaArmServer():
00096     def __init__(self, right_arm_settings=None,
00097                  left_arm_settings=None, use_netft_r = False,
00098                  use_netft_l = False, enable_right_arm=True,
00099                  enable_left_arm=True):
00100         self.arm_settings = {}  # dict is set in set_arm_settings
00101 
00102         self.left_arm_ft = {'force': np.matrix(np.zeros((3,1),dtype='float32')),
00103                             'torque': np.matrix(np.zeros((3,1),dtype='float32'))}
00104         self.right_arm_ft = {'force': np.matrix(np.zeros((3,1),dtype='float32')),
00105                              'torque': np.matrix(np.zeros((3,1),dtype='float32'))}
00106 
00107         # kalman filtering force vector. (self.step and bias_wrist_ft)
00108         self.Q_force, self.R_force = {}, {}
00109         self.xhat_force, self.P_force = {}, {}
00110 
00111         self.Q_force['right_arm'] = [1e-3, 1e-3, 1e-3, 1e-3, 1e-3, 1e-3]
00112         self.R_force['right_arm'] = [0.1**2, 0.1**2, 0.1**2, 0.05**2, 0.05**2, 0.05**2]
00113         self.xhat_force['right_arm'] = [0., 0., 0., 0., 0., 0.]
00114         self.P_force['right_arm'] = [1.0, 1.0, 1.0, 0., 0., 0.]
00115 
00116         self.Q_force['left_arm'] = [1e-3, 1e-3, 1e-3, 1e-3, 1e-3, 1e-3]
00117         self.R_force['left_arm'] = [0.1**2, 0.1**2, 0.1**2, 0.05**2, 0.05**2, 0.05**2]
00118         self.xhat_force['left_arm'] = [0., 0., 0., 0., 0., 0.]
00119         self.P_force['left_arm'] = [1.0, 1.0, 1.0, 0., 0., 0.]
00120 
00121         self.enable_left_arm = enable_left_arm
00122         self.enable_right_arm = enable_right_arm
00123 
00124         if not enable_right_arm:
00125             right_arm_settings = None
00126             self.right_arm_ft = None
00127             self.Q_force['right_arm'] = None
00128             self.R_force['right_arm'] = None
00129             self.P_force['right_arm'] = None
00130             self.xhat_force['right_arm'] = None
00131 
00132         if not enable_left_arm:
00133             left_arm_settings = None
00134             self.left_arm_ft = None
00135             self.Q_force['left_arm'] = None
00136             self.R_force['left_arm'] = None
00137             self.P_force['left_arm'] = None
00138             self.xhat_force['left_arm'] = None
00139 
00140         self.initialize_joints(right_arm_settings, left_arm_settings)
00141 
00142         #self.initialize_gripper()
00143 
00144 
00145         #----- ROS interface ---------
00146         rospy.init_node('arm_server', anonymous=False)
00147 
00148         if use_netft_r:
00149             self.ftclient_r = ftc.FTClient('force_torque_ft5', True)
00150             self.ftclient_r.bias()
00151         else:
00152             self.ftclient_r = None
00153 
00154         if use_netft_l:
00155             self.ftclient_l = ftc.FTClient('force_torque_ft6', True)
00156             self.ftclient_l.bias()
00157         else:
00158             self.ftclient_l = None
00159 
00160 
00161         self.q_r_pub = rospy.Publisher('/r_arm/q', FloatArray)
00162         self.q_l_pub = rospy.Publisher('/l_arm/q', FloatArray)
00163 
00164         self.qdot_r_pub = rospy.Publisher('/r_arm/qdot', FloatArray)
00165         self.qdot_l_pub = rospy.Publisher('/l_arm/qdot', FloatArray)
00166 
00167         self.force_raw_r_pub = rospy.Publisher('/r_arm/force_raw', FloatArray)
00168         self.force_raw_l_pub = rospy.Publisher('/l_arm/force_raw', FloatArray)
00169         self.force_r_pub = rospy.Publisher('/r_arm/force', FloatArray)
00170         self.force_l_pub = rospy.Publisher('/l_arm/force', FloatArray)
00171 
00172         self.jep_r_pub = rospy.Publisher('/r_arm/jep', FloatArray)
00173         self.jep_l_pub = rospy.Publisher('/l_arm/jep', FloatArray)
00174         self.alph_r_pub = rospy.Publisher('/r_arm/joint_impedance_scale', FloatArray)
00175         self.alph_l_pub = rospy.Publisher('/l_arm/joint_impedance_scale', FloatArray)
00176 
00177         self.torque_r_pub = rospy.Publisher('/r_arm/joint_torque', FloatArray)
00178         self.torque_l_pub = rospy.Publisher('/l_arm/joint_torque', FloatArray)
00179 
00180         self.mot_temp_r_pub = rospy.Publisher('/r_arm/joint_motor_temp', FloatArray)
00181         self.mot_temp_l_pub = rospy.Publisher('/l_arm/joint_motor_temp', FloatArray)
00182 
00183         self.pwr_state_pub = rospy.Publisher('/arms/pwr_state', Bool)
00184         self.joint_state_pub = rospy.Publisher('/joint_states', JointState)
00185         
00186         rospy.Subscriber('/r_arm/command/jep', FloatArray, self.r_jep_cb)
00187         rospy.Subscriber('/l_arm/command/jep', FloatArray, self.l_jep_cb)
00188         rospy.Subscriber('/r_arm/command/joint_impedance_scale', FloatArray, self.r_alpha_cb)
00189         rospy.Subscriber('/l_arm/command/joint_impedance_scale', FloatArray, self.l_alpha_cb)
00190 
00191         # publishing to this message will stop the arms but also crash
00192         # the server (since meka server crashes.) Advait Nov 14, 2010
00193         rospy.Subscriber('/arms/stop', Empty, self.stop)
00194         rospy.Subscriber('/arms/command/motors_off', Empty,
00195                          self.motors_off)
00196 
00197         self.cb_lock = RLock()
00198         self.r_jep = None # see set_jep
00199         self.l_jep = None # see set_jep
00200         self.q_r = None # using this to compute qdot
00201         self.q_l = None # using this to compute qdot
00202         self.q_rHOT = None # using this to compute qdot # added_by_tapo, Jan 23-2013
00203         self.q_lHOT = None # using this to compute qdot # added_by_tapo, Jan 23-2013
00204         self.time_stamp = None # using this to compute qdot
00205 
00206         d = {}
00207         d['right_arm'] = ac.get_joint_name_list('r')
00208         d['left_arm'] = ac.get_joint_name_list('l')
00209         self.joint_names_list = d
00210 
00211     def set_arm_settings(self,right_arm_settings,left_arm_settings):
00212         self.arm_settings['right_arm'] = right_arm_settings
00213         self.arm_settings['left_arm'] = left_arm_settings
00214 
00215         for arm,arm_settings in zip(['right_arm','left_arm'],[right_arm_settings,left_arm_settings]):
00216             joint_component_list = self.joint_list_dict[arm]
00217 
00218 # OFF mode doesn't seem to work. (Advait, Jan 1 2010)
00219             if arm_settings == None:
00220                 if joint_component_list != None:
00221                     for c in joint_component_list:
00222                         c.set_control_mode(OFF)
00223                 continue
00224 
00225             stiffness_list = arm_settings.stiffness_list
00226 
00227             if arm_settings.control_mode == 'torque_gc':
00228                 print 'setting control mode to torque_gc'
00229                 for c in joint_component_list:
00230                     c.set_control_mode(TORQUE_GC)
00231                     c.set_torque_mNm(0.0)
00232             elif arm_settings.control_mode == 'theta_gc':
00233                 print 'setting control mode to theta_gc'
00234                 for i in range(5):
00235                     joint_component_list[i].set_control_mode(THETA_GC)
00236                     joint_component_list[i].set_stiffness(stiffness_list[i])
00237                     joint_component_list[i].set_slew_rate_proportion(1.)
00238 
00239                 joint_component_list[5].set_control_mode(THETA)
00240                 joint_component_list[5].set_slew_rate_proportion(1.)
00241                 joint_component_list[6].set_control_mode(THETA)
00242                 joint_component_list[6].set_slew_rate_proportion(1.)
00243 
00244             elif arm_settings.control_mode == 'wrist_theta_gc':
00245                 print 'setting control mode to theta_gc include wrist joints'
00246                 for i in range(7):
00247                     joint_component_list[i].set_control_mode(THETA_GC)
00248                     joint_component_list[i].set_stiffness(stiffness_list[i])
00249                     joint_component_list[i].set_slew_rate_proportion(1.)
00250 
00251             else:
00252                 print 'hrl_robot.initialize_joints. unknown control mode for ', arm,':', arm_settings.control_mode
00253 
00254     # put a few things into safeop so that individual joint
00255     # components work.
00256     def safeop_things(self):
00257         robot_name = 'm3humanoid_bimanual_mr1'
00258         chain_names = ['m3arm_ma1', 'm3arm_ma2']
00259         dynamatics_nms = ['m3dynamatics_ma1', 'm3dynamatics_ma2']
00260 
00261         self.proxy.make_safe_operational(robot_name)
00262         for c in chain_names:
00263             self.proxy.make_safe_operational(c)
00264         for d in dynamatics_nms:
00265             self.proxy.make_safe_operational(d)
00266 
00267     def initialize_joints(self, right_arm_settings, left_arm_settings):
00268         self.proxy = m3p.M3RtProxy()
00269         self.proxy.start(True, True) # the second true enables ROS (needed for the skin patch)
00270 
00271         l1 = ['m3pwr_pwr003']
00272 
00273         if self.enable_right_arm:
00274             l1.append('m3loadx6_ma1_l0')
00275             l1.append('m3arm_ma1')
00276 
00277         if left_arm_settings is not None:
00278             l1.append('m3loadx6_ma2_l0')
00279             l1.append('m3arm_ma2')
00280 
00281         for c in l1:
00282             if not self.proxy.is_component_available(c):
00283                 raise m3t.M3Exception('Component '+c+' is not available.')
00284         
00285         self.joint_list_dict = {}
00286 
00287         if self.enable_right_arm:
00288             right_l = []
00289             for c in ['m3joint_ma1_j0','m3joint_ma1_j1','m3joint_ma1_j2',
00290                       'm3joint_ma1_j3','m3joint_ma1_j4','m3joint_ma1_j5',
00291                       'm3joint_ma1_j6']:
00292                 if not self.proxy.is_component_available(c):
00293                     raise m3t.M3Exception('Component '+c+' is not available.')
00294                 right_l.append(m3f.create_component(c))
00295             self.joint_list_dict['right_arm'] = right_l
00296         else:
00297             self.joint_list_dict['right_arm'] = None
00298 
00299         if self.enable_left_arm:
00300             left_l = []
00301             for c in ['m3joint_ma2_j0','m3joint_ma2_j1','m3joint_ma2_j2',
00302                       'm3joint_ma2_j3','m3joint_ma2_j4','m3joint_ma2_j5',
00303                       'm3joint_ma2_j6']:
00304                 if not self.proxy.is_component_available(c):
00305                     raise m3t.M3Exception('Component '+c+' is not available.')
00306                 left_l.append(m3f.create_component(c))
00307             self.joint_list_dict['left_arm'] = left_l
00308         else:
00309             self.joint_list_dict['left_arm'] = None
00310 
00311         for arm,arm_settings in zip(['right_arm','left_arm'],[right_arm_settings,left_arm_settings]):
00312             if arm_settings == None:
00313                 continue
00314             for comp in self.joint_list_dict[arm]:
00315                 self.proxy.subscribe_status(comp)
00316                 self.proxy.publish_command(comp)
00317 
00318         self.set_arm_settings(right_arm_settings,left_arm_settings)
00319 
00320         self.pwr=m3f.create_component('m3pwr_pwr003')
00321         self.proxy.subscribe_status(self.pwr)
00322         self.proxy.publish_command(self.pwr)
00323 
00324         self.arms = {}
00325 
00326         if self.enable_right_arm:
00327             right_fts=m3.loadx6.M3LoadX6('m3loadx6_ma1_l0')
00328             self.proxy.subscribe_status(right_fts)
00329 
00330             self.arms['right_arm']=m3.arm.M3Arm('m3arm_ma1')
00331             self.proxy.subscribe_status(self.arms['right_arm'])
00332         else:
00333             right_fts = None
00334             self.arms['right_arm'] = None
00335 
00336         if self.enable_left_arm:
00337             left_fts=m3.loadx6.M3LoadX6('m3loadx6_ma2_l0')
00338             self.proxy.subscribe_status(left_fts)
00339 
00340             self.arms['left_arm']=m3.arm.M3Arm('m3arm_ma2')
00341             self.proxy.subscribe_status(self.arms['left_arm'])
00342         else:
00343             left_fts = None
00344             self.arms['left_arm'] = None
00345 
00346         self.fts = {'right_arm':right_fts,'left_arm':left_fts}
00347 
00348         self.proxy.step()
00349         self.proxy.step()
00350 
00351     def initialize_gripper(self):
00352         #self.right_gripper = m3h.M3Gripper('m3gripper_mg0')
00353         self.right_gripper = m3h.M3Gripper('m3gripper_mg1')
00354         self.proxy.publish_command(self.right_gripper)
00355         self.proxy.subscribe_status(self.right_gripper)
00356 
00357     def step(self):
00358         self.proxy.step()
00359         l = []
00360         if self.enable_right_arm:
00361             l.append('right_arm')
00362         if self.enable_left_arm:
00363             l.append('left_arm')
00364 
00365         for arm in l:
00366             z = self.get_wrist_force(arm).A1 # Force vector
00367             #if arm == 'right_arm':
00368             #    z = self.get_wrist_force_nano().A1
00369 
00370             for i in range(6):
00371                 xhat, p = kalman_update(self.xhat_force[arm][i],
00372                                         self.P_force[arm][i],
00373                                         self.Q_force[arm][i],
00374                                         self.R_force[arm][i], z[i])
00375                 if abs(z[i] - self.xhat_force[arm][i]) > 3.:
00376                     xhat = z[i] # not filtering step changes.
00377                 self.xhat_force[arm][i] = xhat
00378                 self.P_force[arm][i] = p
00379 
00380     def step_ros(self):
00381         r_arm = 'right_arm'
00382         l_arm = 'left_arm'
00383 
00384         self.cb_lock.acquire()
00385 
00386         if self.enable_left_arm:
00387             l_jep = copy.copy(self.l_jep)
00388             l_alpha = copy.copy(self.arm_settings['left_arm'].stiffness_list)
00389 
00390         if self.enable_right_arm:
00391             r_jep = copy.copy(self.r_jep)
00392             r_alpha = copy.copy(self.arm_settings['right_arm'].stiffness_list)
00393 
00394         self.cb_lock.release()
00395 
00396         if self.enable_left_arm:
00397             self.set_jep(l_arm, l_jep)
00398             self.set_alpha(l_arm, l_alpha)
00399 
00400         if self.enable_right_arm:
00401             self.set_jep(r_arm, r_jep)
00402             self.set_alpha(r_arm, r_alpha)
00403 
00404         self.step()
00405 
00406         motor_pwr_state = self.is_motor_power_on()
00407 
00408         if not motor_pwr_state:
00409             self.maintain_configuration()
00410 
00411         if self.enable_right_arm:
00412             q_r = self.get_joint_angles(r_arm)
00413             tau_r = self.get_joint_torques(r_arm)
00414             mot_temp_r = self.get_motor_temps(r_arm)
00415         else:
00416             q_r = None
00417             tau_r = None
00418             mot_temp_r = None
00419 
00420         if self.enable_left_arm:
00421             q_l = self.get_joint_angles(l_arm)
00422             tau_l = self.get_joint_torques(l_arm)
00423             mot_temp_l = self.get_motor_temps(l_arm)
00424         else:
00425             q_l = None
00426             tau_l = None
00427             mot_temp_l = None
00428 
00429         # it seems like this estimate of joint velocity should really be filtered
00430         # or at least a better estimate of the derivative (higher order difference equation)
00431         # - marc Jul 13, 2012
00432         # added one more term to achieve a better estimate of the derivative - tapo Jan 23, 2013
00433         t_now = rospy.get_time()
00434         if self.q_r != None and self.q_l != None and self.q_rHOT != None and self.q_lHOT != None and self.time_stamp != None:
00435             dt = t_now - self.time_stamp
00436             #qdot_r = (np.array(q_r) - np.array(self.q_r)) / dt
00437             qdot_r = (-np.array(q_r) + 4*np.array(self.q_r) - 3*np.array(self.q_rHOT)) / (2*dt)
00438             #qdot_l = (np.array(q_l) - np.array(self.q_l)) / dt
00439             qdot_l = (-np.array(q_l) + 4*np.array(self.q_l) - 3*np.array(self.q_lHOT)) / (2*dt)
00440         else:
00441             qdot_r = np.zeros(7)
00442             qdot_l = np.zeros(7)
00443 
00444         self.q_rHOT = self.q_r
00445         self.q_lHOT = self.q_l
00446         self.q_r = q_r
00447         self.q_l = q_l
00448         self.time_stamp = t_now
00449 
00450         if self.enable_right_arm:
00451             f_raw_r = self.get_wrist_force(r_arm).A1.tolist()
00452             f_r = self.xhat_force[r_arm]
00453 
00454         if self.enable_left_arm:
00455             f_raw_l = self.get_wrist_force(l_arm).A1.tolist()
00456             f_l = self.xhat_force[l_arm]
00457 
00458         # publish stuff over ROS.
00459         time_stamp = rospy.Time.now()
00460         h = Header()
00461         h.stamp = time_stamp
00462 
00463         h.frame_id = '/torso_lift_link'
00464         pos = []
00465         nms = []
00466 
00467         if self.enable_right_arm:
00468             self.q_r_pub.publish(FloatArray(h, q_r))
00469             self.qdot_r_pub.publish(FloatArray(h, qdot_r))
00470             self.jep_r_pub.publish(FloatArray(h, r_jep))
00471             self.alph_r_pub.publish(FloatArray(h, r_alpha))
00472             self.torque_r_pub.publish(FloatArray(h, tau_r))
00473             self.mot_temp_r_pub.publish(FloatArray(h, mot_temp_r))
00474 
00475             nms = nms + self.joint_names_list['right_arm']
00476             pos = pos + q_r
00477 
00478             h.frame_id = 'should_not_be_using_this'
00479             self.force_raw_r_pub.publish(FloatArray(h, f_raw_r))
00480             self.force_r_pub.publish(FloatArray(h, f_r))
00481             
00482         if enable_left_arm:
00483             self.q_l_pub.publish(FloatArray(h, q_l))
00484             self.qdot_l_pub.publish(FloatArray(h, qdot_l))
00485             self.jep_l_pub.publish(FloatArray(h, l_jep))
00486             self.alph_l_pub.publish(FloatArray(h, l_alpha))
00487             self.torque_l_pub.publish(FloatArray(h, tau_l))
00488             self.mot_temp_l_pub.publish(FloatArray(h, mot_temp_l))
00489 
00490             nms = nms + self.joint_names_list['left_arm']
00491             pos = pos + q_l
00492 
00493             h.frame_id = 'should_not_be_using_this'
00494             self.force_raw_l_pub.publish(FloatArray(h, f_raw_l))
00495             self.force_l_pub.publish(FloatArray(h, f_l))
00496 
00497         self.joint_state_pub.publish(JointState(h, nms, pos,
00498                                     [0.]*len(pos), [0.]*len(pos)))
00499         self.pwr_state_pub.publish(Bool(motor_pwr_state))
00500 
00501     def is_motor_power_on(self):
00502         return self.pwr.is_motor_power_on(None)
00503 
00504     # Advait, Aug 8, 2009
00505     # two steps in motors_on and off because with simply one step
00506     # pwr.is_motor_on does not get the correct value. (I think this is
00507     # because at the clock edge when motor on command is sent, the power
00508     # is still off and thus the status is not affected.)
00509     def motors_off(self, msg=None):
00510         self.pwr.set_motor_power_off()
00511 
00512     def motors_on(self):
00513         self.maintain_configuration()
00514         self.pwr.set_motor_power_on()
00515         self.step()
00516         self.step()
00517 
00518     def maintain_configuration(self):
00519         l = []
00520         if self.enable_left_arm:
00521             l.append('left_arm')
00522         if self.enable_right_arm:
00523             l.append('right_arm')
00524 
00525         for arm in l:
00526             q = self.get_joint_angles(arm)
00527             if self.arm_settings[arm] == None:
00528                 continue
00529             if 'theta_gc' not in self.arm_settings[arm].control_mode:
00530                 raise RuntimeError('bad control mode: %s', self.arm_settings[arm].control_mode)
00531             self.set_jep(arm, q)
00532             self.cb_lock.acquire()
00533             if arm == 'right_arm':
00534                 self.r_jep = q
00535             else:
00536                 self.l_jep = q
00537             self.cb_lock.release()
00538 
00539     def power_on(self):
00540         self.maintain_configuration()
00541         self.proxy.make_operational_all()
00542         self.safeop_things()
00543         self.pwr.set_motor_power_on()
00544         self.step()
00545         self.step()
00546 
00547     def stop(self, msg=None):
00548         self.pwr.set_motor_power_off()
00549         self.step()
00550         self.proxy.stop()
00551 
00552     ##3X1 numpy matrix of forces measured by the wrist FT sensor.
00553     #(This is the force that the environment is applying on the wrist)
00554     # @param arm - 'left_arm' or 'right_arm'
00555     # @return in SI units
00556     #coord frame - tool tip coord frame (parallel to the base frame in the home position)
00557     # 2010/2/5 Advait, Aaron King, Tiffany verified that coordinate frame 
00558     # from Meka is the left-hand coordinate frame.
00559     def get_wrist_force(self, arm):
00560         if arm == 'right_arm' and self.ftclient_r != None:
00561             return self.get_wrist_force_netft('r')
00562 
00563         if arm == 'left_arm' and self.ftclient_l != None:
00564             return self.get_wrist_force_netft('l')
00565 
00566         m = []
00567         lc = self.fts[arm]
00568         m.append(lc.get_Fx_mN()/1000.)
00569         m.append(lc.get_Fy_mN()/1000.)
00570         m.append(-lc.get_Fz_mN()/1000.)        
00571 
00572         m.append(lc.get_Tx_mNm()/1000.)
00573         m.append(lc.get_Ty_mNm()/1000.)
00574         m.append(-lc.get_Tz_mNm()/1000.)        
00575 
00576         m = np.matrix(m).T
00577         r = tr.Rz(math.radians(-30.0))
00578 
00579         m1 = r * m[0:3,:]
00580         m1[1,0] = -m1[1,0]
00581         m1[2,0] = -m1[2,0]
00582 
00583         m2 = r * m[3:,:]
00584         m2[1,0] = -m2[1,0]
00585         m2[2,0] = -m2[2,0]
00586 
00587         return np.row_stack((m1, m2))
00588 
00589     def get_wrist_force_netft(self, arm):
00590         if arm == 'r':
00591             w = self.ftclient_r.read()
00592         elif arm == 'l':
00593             w = self.ftclient_l.read()
00594 
00595         r = tr.Rz(math.radians(30.))
00596         f = r * w[0:3]
00597         t = r * w[0:3]
00598         f[1,0] = f[1,0] * -1
00599         t[1,0] = t[1,0] * -1
00600         return np.row_stack((f,t))
00601 
00602     def get_wrist_torque(self, arm):
00603         m = []
00604         lc = self.fts[arm]
00605         m = tr.Rz(math.radians(-30.0))*np.matrix(m).T
00606         m[1,0] = -m[1,0]
00607         m[2,0] = -m[2,0]
00608         return m
00609 
00610 
00611 
00612     #-------------------- getting and setting joint angles ------------
00613 
00614     ##
00615     # @param arm - 'left_arm' or 'right_arm'
00616     # @return list of 7 joint accelerations in RADIANS/s^2.
00617     #         according to meka's coordinate frames.
00618     def get_joint_accelerations(self, arm):
00619         #return self.arms[arm].get_thetadotdot_rad().tolist()
00620         raise RuntimeError('The meka joint accelerations are incorrect (Because the joint velocities are incorrect - Tapo, Jan 23, 2013). Computing my own joint accelerations.')
00621 
00622     ##
00623     # @param arm - 'left_arm' or 'right_arm'
00624     # @return list of 7 joint velocities in RADIANS/s.
00625     #         according to meka's coordinate frames.
00626     def get_joint_velocities(self, arm):
00627         #return self.arms[arm].get_thetadot_rad().tolist()
00628         raise RuntimeError('The meka joint velocities seem incorrect. (Advait, July 6, 2011). Computing my own joint velocities.')
00629 
00630     def get_joint_torques(self, arm):
00631         ''' returns list of 7 joint torques in mNm
00632         '''
00633         return self.arms[arm].get_torque_mNm().tolist()
00634 
00635     def get_motor_temps(self, arm):
00636         ''' returns list of 7 motor temperatures in Celsius
00637         '''
00638         return self.arms[arm].get_motor_temp_C().tolist()
00639 
00640     def get_joint_angles(self, arm):
00641         ''' returns list of 7 joint angles in RADIANS.
00642             according to meka's coordinate frames.
00643         '''
00644         return self.arms[arm].get_theta_rad().tolist()
00645 
00646     def l_jep_cb(self, msg):
00647         self.cb_lock.acquire()
00648         self.l_jep = msg.data
00649         self.cb_lock.release()
00650 
00651     def r_jep_cb(self, msg):
00652         self.cb_lock.acquire()
00653         self.r_jep = msg.data
00654         self.cb_lock.release()
00655 
00656     ##
00657     # @param q - list of 7 joint angles in RADIANS. according to meka's coordinate frames.
00658     def set_jep(self, arm, q):
00659         if self.arm_settings[arm] == None:
00660             return
00661         if self.arm_settings[arm].control_mode != 'theta_gc' and \
00662             self.arm_settings[arm].control_mode != 'wrist_theta_gc':
00663             raise RuntimeError('Bad control mode: %s'%(self.arm_settings[arm].control_mode))
00664 
00665         for i,qi in enumerate(q):
00666             ## NOTE - meka's set_theta_deg takes angle in radians.
00667             #self.joint_list_dict[arm][i].set_theta_deg(qi)
00668             # Not anymore. (Advait Aug 27, 2009)
00669             self.joint_list_dict[arm][i].set_theta_rad(qi)
00670 
00671         self.cb_lock.acquire()
00672         if arm == 'right_arm':
00673             self.r_jep = q
00674         else:
00675             self.l_jep = q
00676         self.cb_lock.release()
00677 
00678     def r_alpha_cb(self, msg):
00679         self.cb_lock.acquire()
00680         self.arm_settings['right_arm'].set_stiffness_scale(list(msg.data))
00681         self.cb_lock.release()
00682 
00683     def l_alpha_cb(self, msg):
00684         self.cb_lock.acquire()
00685         self.arm_settings['left_arm'].set_stiffness_scale(list(msg.data))
00686         self.cb_lock.release()
00687 
00688     def set_alpha(self, arm, alpha):
00689         jcl = self.joint_list_dict[arm]
00690         for i,a in enumerate(alpha):
00691             jcl[i].set_stiffness(a)
00692 
00693 
00694 
00695 if __name__ == '__main__':
00696     import optparse
00697 
00698     p = optparse.OptionParser()
00699     p.add_option('--enable_net_ft_r', action='store_true', dest='netft_r',
00700                  help='use net ft for the right arm')
00701     p.add_option('--enable_net_ft_l', action='store_true', dest='netft_l',
00702                  help='use net ft for the left arm') #Tiffany 11/11/2011
00703     p.add_option('--arm_to_use', action='store', dest='arm_to_use',
00704                  help='use only one arm (l or r)', type='string')
00705     opt, args = p.parse_args()
00706 
00707     try:
00708         settings_r = MekaArmSettings(stiffness_list=[0.1939,0.6713,0.748,0.7272,0.75])
00709         #settings_r = None
00710         settings_l = MekaArmSettings(stiffness_list=[0.1939,0.6713,0.748,0.7272,0.75])
00711         #settings_l = None
00712 
00713         if opt.arm_to_use == 'l':
00714             enable_left_arm = True
00715             enable_right_arm = False
00716         elif opt.arm_to_use == 'r':
00717             enable_left_arm = False
00718             enable_right_arm = True
00719         elif opt.arm_to_use == 'b':
00720             enable_right_arm = True
00721             enable_left_arm = True
00722         else:
00723             raise RuntimeError('Unrecognized value for the arm_to_use command line argument')
00724 
00725         cody_arms = MekaArmServer(settings_r, settings_l, opt.netft_r,
00726                                   opt.netft_l, enable_right_arm,
00727                                   enable_left_arm)
00728 
00729 #        print 'hit a key to power up the arms.'
00730 #        k=m3t.get_keystroke()
00731         cody_arms.power_on()
00732 
00733         while not rospy.is_shutdown():
00734             cody_arms.step_ros()
00735             rospy.sleep(0.005)
00736         cody_arms.stop()
00737 
00738     except m3t.M3Exception:
00739         print '############################################################'
00740         print 'In all likelihood the Meka server is not running.'
00741         print '############################################################'
00742         raise
00743     except:
00744         # only use cody_arms if it was successfully created.
00745         if 'cody_arms' in locals():
00746             cody_arms.stop()
00747         raise
00748 
00749 
00750 
00751 
00752 


hrl_cody_arms
Author(s): Advait Jain, Advisor: Prof. Charlie Kemp, Lab: Healthcare Robotics Lab
autogenerated on Wed Nov 27 2013 12:11:49