pr2_utils.py
Go to the documentation of this file.
00001 import roslib; roslib.load_manifest('rcommander')
00002 import rospy
00003 import actionlib
00004 import trajectory_msgs.msg as tm
00005 import numpy as np
00006 import functools as ft
00007 import sensor_msgs.msg as sm
00008 import std_msgs.msg as stdm
00009 import pr2_controllers_msgs.msg as pm
00010 import geometry_msgs.msg as gm
00011 import geometry_msgs.msg as geo
00012 import time
00013 from kinematics_msgs.srv import GetKinematicSolverInfo
00014 from pycontroller_manager.pycontroller_manager import ControllerManager
00015 from PyQt4.QtGui import *
00016 from PyQt4.QtCore import *
00017 import tf_utils as tfu
00018 from object_manipulator.convert_functions import stamp_pose
00019 import tf.transformations as tr
00020 from tf_broadcast_server.srv import GetTransforms
00021 import rcommander.tool_utils as tu
00022 import roslib
00023 import os.path as pt
00024 
00025 
00026 class SE3Tool:
00027 
00028     def __init__(self):
00029         self.frames_service = rospy.ServiceProxy('get_transforms', GetTransforms)
00030 
00031     def make_se3_boxes(self, pbox):
00032         self.xline = tu.double_spin_box(pbox, -3.,3.,.01) #QLineEdit(pbox)
00033         self.yline = tu.double_spin_box(pbox, -3.,3.,.01) #QLineEdit(pbox)
00034         self.zline = tu.double_spin_box(pbox, -3.,3.,.01) #QLineEdit(pbox)
00035         self.phi_line   = tu.double_spin_box(pbox, -360., 360., 1) #QLineEdit(pbox)
00036         self.theta_line = tu.double_spin_box(pbox, -360., 360., 1) #QLineEdit(pbox)
00037         self.psi_line   = tu.double_spin_box(pbox, -360., 360., 1) #QLineEdit(pbox)
00038     
00039         position_box = QGroupBox('Position', pbox)
00040         position_layout = QFormLayout(position_box)
00041         position_box.setLayout(position_layout)
00042         position_layout.addRow("&X", self.xline)
00043         position_layout.addRow("&Y", self.yline)
00044         position_layout.addRow("&Z", self.zline)
00045     
00046         orientation_box = QGroupBox('Orientation', pbox)
00047         orientation_layout = QFormLayout(orientation_box)
00048         orientation_box.setLayout(orientation_layout)
00049         orientation_layout.addRow("&Phi",   self.phi_line)
00050         orientation_layout.addRow("&Theta", self.theta_line)
00051         orientation_layout.addRow("&Psi",   self.psi_line)
00052     
00053         return [position_box, orientation_box]
00054     
00055     def make_frame_box(self, pbox):
00056         frame_box = QComboBox(pbox)
00057         #for f in self.tf_listener.getFrameStrings():
00058         for f in self.frames_service().frames:
00059             frame_box.addItem(f)
00060         return frame_box
00061     
00062     def make_task_frame_box(self, pbox):
00063         self.frame_box = self.make_frame_box(pbox)
00064         return self.frame_box
00065 
00066     def get_posestamped(self):
00067         pose  = geo.Pose()
00068         pose.position = geo.Point(*[float(vr.value()) for vr in [self.xline, self.yline, self.zline]])
00069         pose.orientation = geo.Quaternion(*tr.quaternion_from_euler(*[float(np.radians(vr.value())) for vr in [self.phi_line, self.theta_line, self.psi_line]]))
00070         ps = stamp_pose(pose, str(self.frame_box.currentText()))
00071         return ps
00072 
00073     def set_posestamped(self, pose_stamped):
00074         for value, vr in zip(position(pose_stamped.pose.position), [self.xline, self.yline, self.zline]):
00075             vr.setValue(value)
00076         for value, vr in zip(tr.euler_from_quaternion(quaternion(pose_stamped.pose.orientation)), [self.phi_line, self.theta_line, self.psi_line]):
00077             vr.setValue(value)
00078         idx = tu.combobox_idx(self.frame_box, pose_stamped.header.frame_id)
00079         self.frame_box.setCurrentIndex(idx)
00080 
00081 
00082 class ListManager:
00083 
00084     def __init__(self, get_current_data_cb, set_current_data_cb, add_element_cb=None, name_preffix='point'):
00085         self.get_current_data_cb = get_current_data_cb
00086         self.set_current_data_cb = set_current_data_cb
00087         self.add_element_cb = add_element_cb
00088         self.name_preffix = name_preffix
00089         self.data_list = []
00090 
00091     def item_selection_changed_cb(self):
00092         selected = self.list_widget.selectedItems()
00093         if len(selected) == 0:
00094             return
00095         idx = self._find_index_of(str(selected[0].text()))
00096         self.curr_selected = idx
00097         self.set_current_data_cb(self.data_list[idx]['data'])
00098 
00099     def set_default_selection(self):
00100         if len(self.data_list) > 0:
00101             self.list_widget.setCurrentItem(0)
00102 
00103     def _find_index_of(self, name):
00104         for idx, tup in enumerate(self.data_list):
00105             if tup['name'] == name:
00106                 return idx
00107         return None
00108 
00109     def make_widgets(self, parent, connector):
00110         self.list_box = QWidget(parent)
00111         self.list_box_layout = QHBoxLayout(self.list_box)
00112         self.list_box_layout.setMargin(0)
00113 
00114         self.list_widget = QListWidget(self.list_box)
00115         connector.connect(self.list_widget, SIGNAL('itemSelectionChanged()'), self.item_selection_changed_cb)
00116         self.list_box_layout.addWidget(self.list_widget)
00117 
00118         self.list_widget_buttons = QWidget(parent)
00119         self.lbb_hlayout = QHBoxLayout(self.list_widget_buttons)
00120 
00121 
00122         base_path = roslib.packages.get_pkg_dir('rcommander_pr2_gui')
00123 
00124         icon = QIcon()
00125         icon.addPixmap(QPixmap(pt.join(base_path, "icons/AddButton.png")), QIcon.Normal, QIcon.Off)
00126         self.add_button = QPushButton(self.list_widget_buttons)
00127         self.add_button.setToolTip('Add')
00128         self.add_button.setIcon(icon)
00129         connector.connect(self.add_button, SIGNAL('clicked()'), self.add_cb)
00130 
00131         icon = QIcon()
00132         icon.addPixmap(QPixmap(pt.join(base_path, "icons/RemoveButton.png")), QIcon.Normal, QIcon.Off)
00133         self.remove_button = QPushButton(self.list_widget_buttons)
00134         self.remove_button.setToolTip('Remove')
00135         self.remove_button.setIcon(icon)
00136         connector.connect(self.remove_button, SIGNAL('clicked()'), self.remove_pose_cb)
00137 
00138         icon = QIcon()
00139         icon.addPixmap(QPixmap(pt.join(base_path, "icons/SaveButton.png")), QIcon.Normal, QIcon.Off)
00140         self.save_button = QPushButton(self.list_widget_buttons)
00141         self.save_button.setToolTip('Save')
00142         self.save_button.setIcon(icon)
00143         connector.connect(self.save_button, SIGNAL('clicked()'), self.save_button_cb)
00144 
00145         spacer = QSpacerItem(40, 20, QSizePolicy.Minimum, QSizePolicy.Expanding)
00146 
00147         icon = QIcon()
00148         #print 'PATH', pt.join(base_path, "icons/UpButton.png")
00149         icon.addPixmap(QPixmap(pt.join(base_path, "icons/UpButton.png")), QIcon.Normal, QIcon.Off)
00150         self.move_up_button = QPushButton(self.list_widget_buttons)
00151         self.move_up_button.setToolTip('Up')
00152         self.move_up_button.setIcon(icon)
00153         connector.connect(self.move_up_button, SIGNAL('clicked()'), self.move_up_cb)
00154 
00155         icon = QIcon()
00156         icon.addPixmap(QPixmap(pt.join(base_path, "icons/DownButton.png")), QIcon.Normal, QIcon.Off)
00157         self.move_down_button = QPushButton(self.list_widget_buttons)
00158         self.move_down_button.setToolTip('Down')
00159         self.move_down_button.setIcon(icon)
00160         connector.connect(self.move_down_button, SIGNAL('clicked()'), self.move_down_cb)
00161 
00162         self.lbb_hlayout.addWidget(self.add_button)
00163         self.lbb_hlayout.addWidget(self.remove_button)
00164         self.lbb_hlayout.addWidget(self.save_button)
00165         self.lbb_hlayout.addItem(spacer)
00166         self.lbb_hlayout.addWidget(self.move_up_button)
00167         self.lbb_hlayout.addWidget(self.move_down_button)
00168         self.lbb_hlayout.setContentsMargins(2, 2, 2, 2)
00169         return [self.list_box, self.list_widget_buttons]
00170 
00171 
00172     def _refill_list_widget(self, data_list):
00173         self.list_widget.clear()
00174         for d in data_list:
00175             self.list_widget.addItem(d['name'])
00176 
00177     def _has_name(self, test_name):
00178         for rec in self.data_list:
00179             if rec['name'] == test_name:
00180                 return True
00181             else:
00182                 return False
00183 
00184     def _create_name(self):
00185         idx = len(self.data_list)
00186         tentative_name = self.name_preffix + ('%d' % idx)
00187         while self._has_name(tentative_name):
00188             idx = idx + 1
00189             tentative_name = self.name_preffix + ('%d' % idx)
00190         return tentative_name
00191 
00192     def add_cb(self):
00193         name = self._create_name()
00194         self.data_list.append({'name': name, 
00195                                'data': self.get_current_data_cb()})
00196         self._refill_list_widget(self.data_list)
00197         if self.add_element_cb != None:
00198             self.add_element_cb()
00199 
00200     def _selected_idx(self):
00201         #Get currently selected
00202         selected = self.list_widget.selectedItems()
00203         if len(selected) == 0:
00204             return None
00205         sname = str(selected[0].text())
00206 
00207         #Remove it from list_widget and joint_angs_list
00208         idx = self._find_index_of(sname)
00209         return idx
00210     
00211     def move_up_cb(self):
00212         #get the current index
00213         idx = self._selected_idx()
00214         if idx == None:
00215             return
00216 
00217         #pop & insert it
00218         item = self.data_list.pop(idx)
00219         self.data_list.insert(idx-1, item)
00220 
00221         #refresh
00222         self._refill_list_widget(self.data_list)
00223         self.list_widget.setCurrentItem(self.list_widget.item(idx-1))
00224 
00225     def move_down_cb(self):
00226         #get the current index
00227         idx = self._selected_idx()
00228         if idx == None:
00229             return
00230 
00231         #pop & insert it
00232         item = self.data_list.pop(idx)
00233         self.data_list.insert(idx+1, item)
00234 
00235         #refresh
00236         self._refill_list_widget(self.data_list)
00237         self.list_widget.setCurrentItem(self.list_widget.item(idx+1))
00238 
00239     def select_default_item(self):
00240         self.list_widget.setCurrentItem(self.list_widget.item(0))
00241 
00242     def save_button_cb(self):
00243         idx = self._selected_idx()
00244         if idx == None:
00245             return
00246         el = self.data_list[idx]
00247         self.data_list[idx] = {'name': el['name'],
00248                                'data': self.get_current_data_cb()}
00249 
00250     def remove_pose_cb(self):
00251         idx = self._selected_idx()
00252         if idx == None:
00253             return
00254         if idx == None:
00255             raise RuntimeError('Inconsistency detected in list')
00256         else:
00257             self.data_list.pop(idx)
00258         self._refill_list_widget(self.data_list)
00259 
00260     def get_data(self):
00261         #return [p['data'] for p in self.data_list]
00262         return self.data_list
00263 
00264     def set_data(self, data_list):
00265         self.data_list = data_list
00266         self._refill_list_widget(self.data_list)
00267 
00268 
00269 
00270 def position(point):
00271     return [point.x, point.y, point.z]
00272 
00273 def quaternion(quaternion):
00274     return [quaternion.x, quaternion.y, quaternion.z, quaternion.w]
00275 
00276 #Test this
00277 def unwrap2(cpos, npos):
00278     two_pi = 2*np.pi
00279     nin = npos % two_pi
00280     n_multiples_2pi = np.floor(cpos/two_pi)
00281     return nin + n_multiples_2pi*two_pi
00282 
00283 def standard_rad(t):
00284     if t > 0:
00285         return ((t + np.pi) % (np.pi * 2))  - np.pi
00286     else:
00287         return ((t - np.pi) % (np.pi * -2)) + np.pi
00288 
00289 ##
00290 # Takes a normal ROS callback channel and gives it an on demand query style
00291 # interface.
00292 class GenericListener:
00293     ##
00294     # Message has to have a header
00295     # @param node_name name of node (if haven't been inited)
00296     # @param message_type type of message to listen for
00297     # @param listen_channel ROS channel to listen
00298     # @param frequency the frequency to expect messages (used to print warning statements to console)
00299     # @param message_extractor function to preprocess the message into a desired format
00300     # @param queue_size ROS subscriber queue (None = infinite)
00301     def __init__(self, node_name, message_type, listen_channel,
00302                  frequency, message_extractor=None, queue_size=None):
00303         #try:
00304             #print node_name, ': inited node.'
00305             #rospy.init_node(node_name, anonymous=True)
00306         #except rospy.ROSException, e:
00307         #    pass
00308         self.last_msg_returned   = None   #Last message returned to callers from this class
00309         self.last_call_back      = None   #Local time of last received message
00310         self.delay_tolerance     = 1/frequency #in seconds
00311         self.reading             = {'message':None, 'msg_id':-1}
00312         self.curid               = 0
00313         self.message_extractor = message_extractor
00314 
00315         def callback(*msg):
00316             #If this is a tuple (using message filter)
00317             if 'header' in dir(msg):
00318                 if msg.__class__ == ().__class__:
00319                     msg_number = msg[0].header.seq
00320                 else:
00321                     msg_number = msg.header.seq
00322             else:
00323                 msg_number = self.curid
00324                 self.curid += 1
00325 
00326             #*msg makes everything a tuple.  If length is one, msg = (msg, )
00327             if len(msg) == 1:
00328                 msg = msg[0]
00329             
00330             self.reading  = {'message':msg, 'msg_id':msg_number}
00331 
00332             #Check for delayed messages
00333             self.last_call_back = time.time() #record when we have been called back last
00334 
00335         if message_type.__class__ == [].__class__:
00336             import message_filters
00337             subscribers = [message_filters.Subscriber(channel, mtype) for channel, mtype in zip(listen_channel, message_type)]
00338             queue_size = 10
00339             ts = message_filters.TimeSynchronizer(subscribers, queue_size)
00340             ts.registerCallback(callback)
00341         else:
00342             rospy.Subscriber(listen_channel, message_type, callback,
00343                              queue_size = queue_size)
00344 
00345         self.node_name = node_name
00346         #print node_name,': subscribed to', listen_channel
00347         rospy.loginfo('%s: subscribed to %s' % (node_name, listen_channel))
00348 
00349     def _check_for_delivery_hiccups(self):
00350         #If have received a message in the past
00351         if self.last_call_back != None:
00352             #Calculate how it has been
00353             time_diff = time.time() - self.last_call_back
00354             #If it has been longer than expected hz, complain
00355             if time_diff > self.delay_tolerance:
00356                 print self.node_name, ': have not heard back from publisher in', time_diff, 's'
00357 
00358     def _wait_for_first_read(self, quiet=False):
00359         if not quiet:
00360             rospy.loginfo('%s: waiting for reading ...' % self.node_name)
00361         while self.reading['message'] == None and not rospy.is_shutdown():
00362             rospy.sleep(0.1)
00363             #if not quiet:
00364             #    print self.node_name, ': waiting for reading ...'
00365 
00366     ## 
00367     # Supported use cases
00368     # rfid   - want to get a reading, can be stale, no duplication allowed (allow None),        query speed important
00369     # hokuyo - want to get a reading, can be stale, no duplication allowed (don't want a None), willing to wait for new data (default)
00370     # ft     - want to get a reading, can be stale, duplication allowed    (don't want a None), query speed important
00371     # NOT ALLOWED                                   duplication allowed,                        willing to wait for new data
00372     def read(self, allow_duplication=False, willing_to_wait=True, warn=False, quiet=True):
00373         if allow_duplication:
00374             if willing_to_wait:
00375                 raise RuntimeError('Invalid settings for read.')
00376             else: 
00377                 # ft - want to get a reading, can be stale, duplication allowed (but don't want a None), query speed important
00378                 #self._wait_for_first_read(quiet)
00379                 reading                = self.reading
00380                 self.last_msg_returned = reading['msg_id']
00381                 if self.message_extractor is not None:
00382                     return self.message_extractor(reading['message'])
00383                 else:
00384                     return reading['message']
00385         else:
00386             if willing_to_wait:
00387                 # hokuyo - want to get a reading, can be stale, no duplication allowed (don't want a None), willing to wait for new data (default)
00388                 self._wait_for_first_read(quiet)
00389                 while self.reading['msg_id'] == self.last_msg_returned and not rospy.is_shutdown():
00390                     if warn:
00391                         self._check_for_delivery_hiccups()
00392                     rospy.sleep(1/1000.0)
00393                 reading = self.reading
00394                 self.last_msg_returned = reading['msg_id']
00395                 if self.message_extractor is not None:
00396                     return self.message_extractor(reading['message'])
00397                 else:
00398                     return reading['message']
00399             else:
00400                 # rfid   - want to get a reading, can be stale, no duplication allowed (allow None),        query speed important
00401                 if self.last_msg_returned == self.reading['msg_id']:
00402                     return None
00403                 else:
00404                     reading = self.reading
00405                     self.last_msg_returned = reading['msg_id']
00406                     if self.message_extractor is not None:
00407                         return self.message_extractor(reading['message'])
00408                     else:
00409                         return reading['message']
00410 
00411 
00412 class Joint:
00413 
00414     def __init__(self, name, joint_provider):
00415         self.joint_provider = joint_provider
00416         self.joint_names = rospy.get_param('/%s/joints' % name)
00417         self.pub = rospy.Publisher('%s/command' % name, tm.JointTrajectory)
00418         self.names_index = None
00419         self.zeros = [0 for j in range(len(self.joint_names))]
00420 
00421     def pose(self, joint_states=None):
00422         #print 'POSE!!!'
00423         if joint_states == None:
00424             joint_states = self.joint_provider()
00425         #print 'JOINT STATE'
00426 
00427         if self.names_index == None:
00428             self.names_index = {}
00429             for i, n in enumerate(joint_states.name):
00430                 self.names_index[n] = i
00431             self.joint_idx = [self.names_index[n] for n in self.joint_names]
00432         #print 'GOT POSE. RETURNING'
00433 
00434         return (np.matrix(joint_states.position).T)[self.joint_idx, 0]
00435 
00436     def _create_trajectory(self, pos_mat, times, vel_mat=None):
00437         #Make JointTrajectoryPoints
00438         points = [tm.JointTrajectoryPoint() for i in range(pos_mat.shape[1])]
00439         for i in range(pos_mat.shape[1]):
00440             points[i].positions = pos_mat[:,i].A1.tolist()
00441             points[i].accelerations = self.zeros
00442             if vel_mat == None:
00443                 points[i].velocities = self.zeros
00444             else:
00445                 points[i].velocities = vel_mat[:,i].A1.tolist()
00446 
00447         for i in range(pos_mat.shape[1]):
00448             points[i].time_from_start = rospy.Duration(times[i])
00449 
00450         #Create JointTrajectory
00451         jt = tm.JointTrajectory()
00452         jt.joint_names = self.joint_names
00453         jt.points = points
00454         jt.header.stamp = rospy.get_rostime() + rospy.Duration(1.)
00455         return jt
00456 
00457     def set_poses(self, pos_mat, times):
00458         #pos_mat = np.column_stack([self.pose(), pos_mat])
00459         #times = [0] + times
00460         #times = times + .1
00461         joint_trajectory = self._create_trajectory(pos_mat, times)
00462         print 'Sending message', joint_trajectory
00463         self.pub.publish(joint_trajectory)
00464 
00465     def get_joint_names(self):
00466         return self.joint_names
00467 
00468 
00469 class PR2Arm(Joint):
00470 
00471     def __init__(self, joint_provider, tf_listener, arm):
00472         joint_controller_name = arm + '_arm_controller'
00473         cart_controller_name = arm + '_cart'
00474         Joint.__init__(self, joint_controller_name, joint_provider)
00475         self.arm = arm
00476         self.tf_listener = tf_listener
00477         #print 'PR2ARM; called CONTROLLERS'
00478         self.client = actionlib.SimpleActionClient('/%s/joint_trajectory_action' % joint_controller_name, pm.JointTrajectoryAction)
00479         self.joint_controller_name = joint_controller_name
00480 
00481         self.cart_posure_pub = rospy.Publisher("/%s/command_posture" % cart_controller_name, stdm.Float64MultiArray).publish
00482         self.cart_pose_pub = rospy.Publisher("/%s/command_pose" % cart_controller_name, gm.PoseStamped).publish
00483         if arm == 'l':
00484             self.full_arm_name = 'left'
00485         else:
00486             self.full_arm_name = 'right'
00487 
00488 
00489         #if use_kinematics:
00490             #self.kinematics = pr2k.PR2ArmKinematics(self.full_arm_name, self.tf_listener)
00491         #self.ik_utilities = iku.IKUtilities(self.full_arm_name, self.tf_listener) 
00492         self.limits_dict, self.vel_limit_dict = self._limits()
00493 
00494         self.POSTURES = {
00495             'off':          np.matrix([]),
00496             'mantis':       np.matrix([0, 1, 0,  -1, 3.14, -1, 3.14]).T,
00497             'elbowupr':     np.matrix([-0.79,0,-1.6,  9999, 9999, 9999, 9999]).T,
00498             'elbowupl':     np.matrix([0.79,0,1.6 , 9999, 9999, 9999, 9999]).T,
00499             'old_elbowupr': np.matrix([-0.79,0,-1.6, -0.79,3.14, -0.79,5.49]).T,
00500             'old_elbowupl': np.matrix([0.79,0,1.6, -0.79,3.14, -0.79,5.49]).T,
00501             'elbowdownr':   np.matrix([-0.028262077316910873, 1.2946342642324222, -0.25785640577652386, -1.5498884526859626]).T, 
00502             'elbowdownl':   np.matrix([-0.0088195719039858515, 1.2834828245284853, 0.20338442004843196, -1.5565279256852611]).T
00503             }
00504 
00505     def get_limits(self):
00506         return self.limits_dict
00507 
00508     def get_vel_limits(self):
00509         return self.vel_limit_dict
00510 
00511     def _limits(self):
00512         service_name = '/pr2_%s_arm_kinematics/get_ik_solver_info' % self.full_arm_name
00513         print service_name
00514         proxy = rospy.ServiceProxy(service_name, GetKinematicSolverInfo)
00515         #import pdb
00516         #pdb.set_trace()
00517         info = proxy().kinematic_solver_info
00518         limit_dict = {}
00519         vel_limit_dict = {}
00520         for idx, name in enumerate(info.joint_names):
00521             limit = info.limits[idx]
00522             if limit.has_position_limits:
00523                 limit_dict[name] = [limit.min_position, limit.max_position]
00524             if limit.has_velocity_limits:
00525                 vel_limit_dict[name] = limit.max_velocity
00526         return limit_dict, vel_limit_dict
00527 
00528     def set_posture(self, posture_mat):
00529         self.cart_posure_pub(stdm.Float64MultiArray(data=posture_mat.A1.tolist()))
00530 
00531     ##
00532     # Send a cartesian pose to *_cart controllers
00533     # @param trans len 3 list
00534     # @param rot len 3 list
00535     # @param frame string
00536     # @param msg_time float
00537     def set_cart_pose(self, trans, rot, frame, msg_time):
00538         ps = gm.PoseStamped()
00539         for i, field in enumerate(['x', 'y', 'z']):
00540             exec('ps.pose.position.%s = trans[%d]' % (field, i))
00541         for i, field in enumerate(['x', 'y', 'z', 'w']):
00542             exec('ps.pose.orientation.%s = rot[%d]' % (field, i))
00543         ps.header.frame_id = frame
00544         ps.header.stamp = rospy.Time(msg_time)
00545         self.cart_pose_pub(ps)
00546 
00547     ##
00548     # @param pos_mat column matrix of poses
00549     # @param times array of times
00550     def set_poses(self, pos_mat, times, vel_mat=None, block=True):
00551         #p = self.pose()
00552         #for i in range(pos_mat.shape[1]):
00553         #    pos_mat[4,i] = unwrap2(p[4,0], pos_mat[4,i])
00554         #    pos_mat[6,i] = unwrap2(p[6,0], pos_mat[6,i])
00555         #    p = pos_mat[:,i]
00556 
00557         pos_mat = np.column_stack([self.pose(), pos_mat])
00558         #print 'SETPOSES', times, times.__class__
00559         times   = np.concatenate(([0], times))
00560         times = times + .1
00561         #print "SET POSES", pos_mat.shape, len(times)
00562         joint_traj = Joint._create_trajectory(self, pos_mat, times, vel_mat)
00563 
00564         #Create goal msg
00565         #joint_traj.header.stamp = rospy.get_rostime() + rospy.Duration(5.)
00566         g = pm.JointTrajectoryGoal()
00567         g.trajectory = joint_traj
00568         #g.trajectory.header.stamp = rospy.get_rostime() + rospy.Duration(1.)
00569         self.client.send_goal(g)
00570         if block:
00571             return self.client.wait_for_result()
00572         return self.client.get_state()
00573 
00574     def stop_trajectory_execution(self):
00575         self.client.cancel_all_goals()
00576 
00577     def has_active_goal(self):
00578         s = self.client.get_state()
00579         if s == amsg.GoalStatus.ACTIVE or s == amsg.GoalStatus.PENDING:
00580             return True
00581         else:
00582             return False
00583 
00584     def set_poses_monitored(self, pos_mat, times, vel_mat=None, block=True, time_look_ahead=.050):
00585         joint_traj = Joint._create_trajectory(self, pos_mat, times, vel_mat)
00586 
00587         #Create goal msg
00588         #joint_traj.header.stamp = rospy.get_rostime() + rospy.Duration(1.)
00589         g = pm.JointTrajectoryGoal()
00590         g.trajectory = joint_traj
00591         self.client.send_goal(g)
00592         if block:
00593             return self.client.wait_for_result()
00594         return self.client.get_state()
00595 
00596     def set_pose(self, pos, nsecs=5., block=True):
00597         for i in range(2):
00598             cpos = self.pose()
00599         pos[4,0] = unwrap(cpos[4,0], pos[4,0])
00600         pos[6,0] = unwrap(cpos[6,0], pos[6,0])
00601         self.set_poses(np.column_stack([pos]), np.array([nsecs]), block=block)
00602         #self.set_poses(np.column_stack([cpos, pos]), np.array([min_time, min_time+nsecs]), block=block)
00603 
00604     def pose_cartesian(self, frame='base_link'):
00605         gripper_tool_frame = self.arm + '_gripper_tool_frame'
00606         return tfu.transform(frame, gripper_tool_frame, self.tf_listener)
00607 
00608     def pose_cartesian_tf(self, frame='base_link'):
00609         p, r = tfu.matrix_as_tf(self.pose_cartesian(frame))
00610         return np.matrix(p).T, np.matrix(r).T
00611 
00612 
00613 class PR2Torso(Joint):
00614 
00615     def __init__(self, joint_provider):
00616         Joint.__init__(self, 'torso_controller', joint_provider)
00617         self.torso = actionlib.SimpleActionClient('torso_controller/position_joint_action', pm.SingleJointPositionAction)
00618         rospy.loginfo('waiting for torso_controller')
00619         self.torso.wait_for_server()
00620 
00621     def set_pose(self, p, block=True):
00622         self.torso.send_goal(pm.SingleJointPositionGoal(position = p))
00623         if block:
00624             self.torso.wait_for_result()
00625         return self.torso.get_state()
00626 
00627 
00628 class PR2Head(Joint):
00629 
00630     def __init__(self, joint_provider):
00631         Joint.__init__(self, 'head_traj_controller', joint_provider)
00632 
00633     def set_pose(self, pos, length=5., block=False):
00634         for i in range(2):
00635             cpos = self.pose()
00636         MIN_TIME = .1
00637         self.set_poses(np.column_stack([cpos, pos]), np.array([MIN_TIME, MIN_TIME+length]))
00638 
00639 class PR2:
00640 
00641     def __init__(self, tf_listener):
00642         #print '===================================='
00643         #print 'PR2 OBJECT CREATED'
00644         #print '===================================='
00645         self.tf_listener = tf_listener
00646         jl = GenericListener('joint_state_listener', sm.JointState, 'joint_states', 100)
00647         joint_provider = ft.partial(jl.read, allow_duplication=False, willing_to_wait=True, warn=False, quiet=True)
00648         self.left = PR2Arm(joint_provider, tf_listener, 'l')
00649         self.right = PR2Arm(joint_provider, tf_listener, 'r')
00650         self.torso = PR2Torso(joint_provider)
00651         self.head = PR2Head(joint_provider)
00652         self.controller_manager = ControllerManager()
00653 


rcommander_pr2_gui
Author(s): Hai Nguyen
autogenerated on Thu Dec 12 2013 12:09:58