MAGIKS  1.1
Manipulator General Inverse Kinematic Solver
 All Classes Namespaces Files Functions Variables Pages
pyride_synchronizer.py
Go to the documentation of this file.
1 ## @file pyride_synchronizer.py
2 # @brief Contains simplified functions to control PR2 using pyride engine
3 # @author Nima Ramezani Taghiabadi
4 #
5 # PhD Researcher
6 # Faculty of Engineering and Information Technology
7 # University of Technology Sydney (UTS)
8 # Broadway, Ultimo, NSW 2007, Australia
9 # Phone No. : 04 5027 4611
10 # Email(1) : nima.ramezani@gmail.com
11 # Email(2) : Nima.RamezaniTaghiabadi@uts.edu.au
12 # @version 7.0
13 #
14 # Start date: 09 April 2014
15 # Last Revision: 20 July 2015
16 
17 '''
18 Changes from ver 5.0:
19  1- The new version supports MAGIKS (The general velocity-based IK engine) for online trajectory tracking
20  In association with version 4.0 of pr2_arm_kinematics
21 '''
22 
23 import pr2_kinematics as pr2lib
24 import pyride_interpreter as pint
25 import PyPR2, math, time, copy, sys, numpy as np
26 import general_python as genpy
27 
28 from math_tools import general_math as gen
29 from math_tools.geometry import trigonometry as trig, rotation as rot, geometry as geo, trajectory as trajlib
30 from math_tools.algebra import vectors_and_matrices as vecmat
31 from magiks.vision import laser_scan_support as lss
32 
33 r_arm_joint_names =['r_shoulder_pan_joint', 'r_shoulder_lift_joint', 'r_upper_arm_roll_joint', 'r_elbow_flex_joint', 'r_forearm_roll_joint', 'r_wrist_flex_joint', 'r_wrist_roll_joint']
34 l_arm_joint_names =['l_shoulder_pan_joint', 'l_shoulder_lift_joint', 'l_upper_arm_roll_joint', 'l_elbow_flex_joint', 'l_forearm_roll_joint', 'l_wrist_flex_joint', 'l_wrist_roll_joint']
35 
36 def read_raw_trajectory(duration = 10.0, delay = 0.5):
37  t0 = time.time()
38  t = t0
39 
40  pint.activate_trajectory_input()
41  rt = trajlib.Trajectory_Polynomial()
42 
43  while t - t0 < duration:
44  print "I am adding this point: ", pint.rt_position ," at time: ", t-t0
45  rt.add_point(phi = t - t0, pos = np.copy(pint.rt_position))
46  time.sleep(delay)
47  t = time.time()
48 
49  return rt
50 
52  # Calibration:
53  '''
54  Trying to compute DH parameters of the right arm according to the FK measured from the robot
55  '''
56  q = np.zeros(10)
57 
58  # Get the current right arm joint values:
59  rajd = PyPR2.getArmJointPositions(False) # gets the Right Arm Joint Dictionary
60  for i in range(7):
61  q[i] = rajd[r_arm_joint_names[i]]
62 
63  q[1] = q[1] + math.pi/2
64 
65  q = trig.angles_standard_range(q)
66 
67  # determining a0
68  t = PyPR2.getRelativeTF('r_shoulder_pan_link' , 'r_shoulder_lift_link')
69  p = t['position']
70  q[7] = p[0] # This is a0
71 
72  # determining d2
73  t = PyPR2.getRelativeTF('r_upper_arm_roll_link' , 'r_elbow_flex_link')
74  p = t['position']
75  q[8] = p[0] # This is a0
76 
77  # determining d4
78  t = PyPR2.getRelativeTF('r_forearm_roll_link' , 'r_wrist_flex_link')
79  p = t['position']
80  q[9] = p[0] # This is d4
81 
82  return(q)
83 
85  # Calibration:
86  '''
87  Trying to compute DH parameters of the left arm according to the FK measured from the robot
88  '''
89  q = np.zeros(10)
90 
91  # Get the current right arm joint values:
92  lajd = PyPR2.getArmJointPositions(True) # gets the Left Arm Joint Dictionary
93  for i in range(7):
94  q[i] = lajd[l_arm_joint_names[i]]
95 
96  q[1] = q[1] + math.pi/2
97  q = trig.angles_standard_range(q)
98  # determining a0
99  t = PyPR2.getRelativeTF('l_shoulder_pan_link' , 'l_shoulder_lift_link')
100  p = t['position']
101  q[7] = p[0]
102 
103  # determining d2
104  t = PyPR2.getRelativeTF('r_upper_arm_roll_link' , 'r_elbow_flex_link')
105  p = t['position']
106  q[8] = p[0]
107 
108  # determining d4
109  t = PyPR2.getRelativeTF('r_forearm_roll_link' , 'r_wrist_flex_link')
110  p = t['position']
111  q[9] = p[0]
112 
113  return(q)
114 
116  q = np.zeros(7)
117 
118  # Determining h_ts
119  p = PyPR2.getRelativeTF('base_footprint', 'torso_lift_link')['position']
120  q[0] = p[2] # This is h_ts or theta[7]
121  '''
122  There is a 50 mm offset in x direction between footprint (Torso origin) p_BO in the paper and the base_footprint defined for PR2.
123  So I will consider this offset in parameter b0
124  '''
125  q[6] = p[0] # This is b0
126 
127  # Determining X_BO and Y_BO:
128  p = PyPR2.getRobotPose()['position'] # This should give the global coordinates of the base_footprint
129  assert gen.equal(p[2], 0.0, epsilon = 0.01) # The robot base_footprint must be on the ground (Accuracy = 1 cm)
130  q[1] = p[0] # This is X_BO (theta[8])
131  q[2] = p[1] # This is Y_BO (theta[9])
132 
133  # Determining tau:
134  '''
135  o = PyPR2.getRobotPose()['orientation']
136  assert gen.equal(np.linalg.norm(o), 1.0)
137  # h = (o[3],o[0],o[1], o[2])
138  R = rot.rotation_matrix(o)
139  uvect_i = vecmat.as_vector([1.0, 0.0, 0.0])
140  uvect_k = vecmat.as_vector([0.0, 0.0, 1.0])
141  q[3] = vecmat.vectors_angle(R[:, 0], uvect_i, positive_direction = uvect_k) # This is tau (theta[10])
142  '''
143  q[3] = pint.body_angle(in_degrees = False) # this is theta[10]
144 
145  # Determining l0
146  p = PyPR2.getRelativeTF('torso_lift_link' , 'r_shoulder_pan_link')['position']
147  assert gen.equal(p[0], 0.0)
148  assert gen.equal(p[2], 0.0)
149  q[4] = - p[1] # This is l0
150 
151  # Determining d7
152  pr = PyPR2.getRelativeTF('r_wrist_roll_link' , 'r_gripper_r_finger_tip_link')['position']
153  pl = PyPR2.getRelativeTF('r_wrist_roll_link' , 'r_gripper_l_finger_tip_link')['position']
154  p = (vecmat.as_vector(pr) + vecmat.as_vector(pl))/2
155  assert gen.equal(p[1], 0.0)
156  assert gen.equal(p[2], 0.0)
157  q[5] = p[0] # This is d7
158 
159  return(q)
160 
161 ## This class introduces a data structure for complete kinematics of a PR2 robot which can sychronize itself with the real robot
162 # or the robot in simulation.
163 # An instance of this class is an object supported by all kinematic functions inherited from class
164 # packages.nima.robotics.kinematics.special_geometries.pr2.pr2_kinematics.PR2()
165 # containing additional methods in order to actuate, move and control the real robot and/or get the sensory data from it
166 # The object can synchronize itself with the robot in both forward and inverse directions via pyride interface engine.
167 # In other words, any changes in the status and configuration of the object can be directly applied
168 # to the real robot or robot in simulation and vice versa.
169 # Forward synchronization is to actuate the robot to the configuration of the object and
170 # inverse synchronization is to set the object with the configuration of the real robot.
171 class PyRide_PR2(pr2lib.PR2):
172  '''
173  '''
174  ## Class Constructor
175  def __init__(self, run_magiks = False):
176 
177  q_d = np.zeros(18)
178  self.r_arm_joint_names = r_arm_joint_names
179  self.l_arm_joint_names = l_arm_joint_names
180 
181  q_r = calibrate_pr2_r_arm()
182  q_l = calibrate_pr2_l_arm()
183  q_t = calibrate_pr2_torso()
184 
185  ## A dictionary specifying the maximum waiting time when you choose to wait for any motion to finish. \n
186  # This time can be different for the motion of different parts of the robot. \n
187  # max_wait_time['rarm']: Refers to the motion of the right arm (Change in joints q[0] - q[6]) \n
188  # max_wait_time['larm']: Refers to the motion of the left arm (Change in joints q[11] - q[17]) \n
189  # max_wait_time['body']: Refers to the navigation of the body (Change in joints q[8], q[9] , q[10]) \n
190  # max_wait_time['trunk']: Refers to the trunk lifting motion (Change in joint q[7])
191  self.max_wait_time = {'rarm':15.0, 'larm':15.0, 'body':60, 'robot':20, 'trunk':20 }
192 
193  assert gen.equal(q_r[7], q_l[7])
194  assert gen.equal(q_r[8], q_l[8])
195  assert gen.equal(q_r[9], q_l[9])
196 
197  #pr2lib.PR2.__init__(self)
198  super(PyRide_PR2, self).__init__(a0 = q_r[7], d2 = q_r[8], d4 = q_r[9], d7 = q_t[5], l0 = q_t[4], b0 = q_t[6], run_magiks = run_magiks)
199 
200  q_d = np.concatenate((q_r[0:7], q_t[0:4], q_l[0:7]))
201  super(PyRide_PR2, self).set_config(q_d)
202 
203  self.set_target(self.end_position(), self.end_orientation())
204  self.rarm.set_target(self.rarm.wrist_position(), self.rarm.wrist_orientation())
205  self.larm.set_target(self.larm.wrist_position(), self.larm.wrist_orientation())
206 
207  ## A float specifying the speed of arm gripper in the operational space in m/sec
208  self.arm_speed = 0.1
209 
210  self.arm_max_speed = 1.0
211  self.base_laser_scan_range = range(400, 640)
212  self.tilt_laser_scan_range = range(80, 300)
213 
214  self.larm_reference = True
215 
216  def trunk_synced(self):
217  '''
218  Returns True if robot and object body heights are identical
219  '''
220  p = PyPR2.getRelativeTF('base_footprint', 'torso_lift_link')['position']
221  return gen.equal(p[2] , self.q[7], epsilon = 0.01)
222 
223  def body_synced(self):
224  '''
225  Returns True if robot and object body positions are identical
226  '''
227  bp = pint.body_position()
228  ba = pint.body_angle(in_degrees = False)
229 
230  fx = gen.equal(bp[0], self.q[8], epsilon = 0.1)
231  fy = gen.equal(bp[1], self.q[9], epsilon = 0.1)
232  ft = gen.equal(ba , self.q[10], epsilon = 0.02)
233 
234  return(fx and fy and ft)
235 
236  ## Use this function to check if the right arm of the object is synced with the right arm of the real robot
237  # @param None
238  # @return A boolean: True, if the joint angles of the right arm of the object instance
239  # are all equal to their equivalents in the real robot, False if not
240  def rarm_synced(self):
241  return vecmat.equal(trig.angles_standard_range(pint.rarm_joints(in_degrees = False)), trig.angles_standard_range(self.rarm.config.q), epsilon = 0.01)
242 
243  ## Use this function to check if the left arm of the object is synced with the left arm of the real robot
244  # @param None
245  # @return A boolean: True, if the joint angles of the left arm of the object instance
246  # are all equal to their equivalents in the real robot, False if not
247  def larm_synced(self):
248  return vecmat.equal(trig.angles_standard_range(pint.larm_joints(in_degrees = False)), trig.angles_standard_range(self.larm.config.q), epsilon = 0.01)
249 
250  ## Use this function if you want the robot to say something.
251  # @param s A string what you want the robot to say
252  # @return None
253  def say(self, s):
254  PyPR2.say(s)
255 
256  ## Use this function to check if the robot is synchronized with the object.
257  # @param limb_list An array of strings specifying which parts should be checked.
258  # @return None
259  def synced(self, limb_list = ['body', 'rarm', 'larm', 'trunk']):
260  sn = True
261  if 'body' in limb_list:
262  sn = sn and self.body_synced()
263  if 'rarm' in limb_list:
264  sn = sn and self.rarm_synced()
265  if 'larm' in limb_list:
266  sn = sn and self.larm_synced()
267  return sn
268 
269  ## Synchronizes the object with the robot and verifies the equity of forward kinematics for both the right and left arm endeffectors.
270  # @param None
271  # @return None
272  def sync_object(self):
273 
274  q_r = calibrate_pr2_r_arm()
275  q_l = calibrate_pr2_l_arm()
276  q_t = calibrate_pr2_torso()
277 
278  q_d = np.concatenate((q_r[0:7], q_t[0:4], q_l[0:7]))
279 
280  assert super(PyRide_PR2, self).set_config(q_d)
281 
282  laggp1 = self.larm_end_position(relative = False) # Left Arm Global Gripper Position from object fk
283  laggp2 = pint.pos_larm_grip() # Left Arm Global Gripper Position measured from robot
284 
285  assert vecmat.equal(laggp1, laggp2, epsilon = 0.1) # verify equality with 10 cm accuracy
286 
287  raggp1 = self.rarm_end_position(relative = False) # Right Arm Global Gripper Position from object fk
288  raggp2 = pint.pos_rarm_grip() # Right Arm Global Gripper Position measured from robot
289 
290  assert vecmat.equal(raggp1, raggp2, epsilon = 0.1) # verify equality with 10 cm accuracy
291 
292  ## Synchronizes the position and orientation of the real robot body or robot in simulation with the object.
293  # If the body pose is not already synced, it takes the configuration specified by <b> self.q[8:11] </b>
294  # @param ttr A float specifying <em> time to reach </em> in seconds
295  # @param wait A boolean: \li If True, the system waits until the the body pose is synchronized or <b> self.max_wait_time['body'] </b> is elapsed.
296  # (You don't exit the function before the motion is finished or the maximum waiting time is elapsed)
297  # \li If False, you will exit the function immidiately while the defined motion is running
298  # @return A boolean: \li True If the body is successfully synchronized with the object at the time of function exit \n
299  # \li False If the body fails to synchronize for any reason \n
300  # \b Note: If parameter \b wait is False, the function returns True only if the body is already synced
301  def sync_body(self, ttr = 5.0, wait = True, max_wait_time = 60.0):
302  if not self.body_synced():
303  pint.move_robot_to(x = self.q[8], y = self.q[9], tau = self.q[10], time_to_reach = ttr, in_degrees = False) # Move the robot body
304  if wait:
305  max_wait_time = gen.ensured_in_range(max_wait_time, 30.0, 300.0)
306  t0 = time.time()
307  t = 0.0
308  while (t < self.max_wait_time_body) and (not self.body_synced()):
309  pint.move_robot_to(x = self.q[8], y = self.q[9], tau = self.q[10], time_to_reach = ttr, in_degrees = False) # Move the robot body first
310  pint.wait_until_finished(limb_list = ['body'], max_time = 0.2*self.max_wait_time_body)
311  t = time.time() - t0
312  return self.body_synced()
313 
314  def set_config_synced(self, qd, ttr = 5.0, max_time = 120.0, limb_list = ['body', 'rarm', 'larm']):
315  '''
316  sets the given configuration to the object and
317  synchronizes the robot with the object.
318  If the given joints are feasible, the robot takes the given configuration.
319  The function will return False if the robot can not reach the desired configuration within max_time
320  '''
321  if self.set_config(qd): # Make sure the given joints are feasible
322  t0 = time.time()
323  t = 0.0
324  while (t < max_time) and (not self.synced(limb_list)):
325  if ('body' in limb_list) and (not self.body_synced()):
326  pint.move_robot_to(x = self.q[8], y = self.q[9], tau = self.q[10], time_to_reach = ttr, in_degrees = False) # Move the robot body first
327  else:
328  pint.body_reached = True
329  if ('rarm' in limb_list) and (not self.rarm_synced()):
330  pint.take_rarm_to(self.rarm.config.q, time_to_reach = ttr) # Move the right arm
331  else:
332  pint.rarm_reached = True
333  if ('larm' in limb_list) and (not self.larm_synced()):
334  pint.take_larm_to(self.larm.config.q, time_to_reach = ttr) # Move the left arm
335  else:
336  pint.larm_reached = True
337 
338  assert pint.wait_until_finished(limb_list = limb_list)
339  t = time.time() - t0
340  else:
341  print "Warning from PyRide_PR2.set_config_synced(): Given joints are not feasible. Configuration was not set"
342  return self.synced(limb_list)
343 
344  ## Synchronizes the right arm of the real robot or robot in simulation with the right arm of the object.
345  # If the right arm is not already synced, it takes the configuration specified by <b> self.q[0:7] </b> or <b> self.rarm.config.q[0:7] </b>
346  # @param ttr A float specifying <em> time to reach </em> in seconds
347  # @param wait A boolean: \li If True, the system waits until the the right arm is synchronized or <b> self.max_wait_time['rarm'] </b> is elapsed.
348  # (You don't exit the function before the motion is finished or the maximum waiting time is elapsed)
349  # \li If False, you will exit the function immidiately while the defined motion is running
350  # @return A boolean: \li True If the right arm is successfully synchronized with the object at the time of function exit \n
351  # \li False If the right arm fails to synchronize for any reason \n
352  # \b Note: If parameter \b wait is False, the function returns True only if the right arm is already synced
353  def sync_rarm(self, ttr = 5.0, wait = True):
354  if not self.rarm_synced():
355  pint.take_rarm_to(self.rarm.config.q, time_to_reach = ttr)
356  if wait:
357  pint.wait_until_finished(limb_list = ['rarm'], max_time = self.max_wait_time['rarm'])
358  return self.rarm_synced()
359 
360  ## Synchronizes the left arm of the real robot or robot in simulation with the left arm of the object.
361  # If the left arm is not already synced, it takes the configuration specified by <b> self.q[11:18] </b> or <b> self.larm.config.q[0:7] </b>
362  # @param ttr A float specifying <em> time to reach </em> in seconds
363  # @param wait A boolean: \li If True, the system waits until the arm reaches the target or <b> self.max_wait_time['larm'] </b> is elapsed.
364  # (You don't exit the function before the motion is finished or the maximum waiting time is elapsed)
365  # \li If False, you will exit the function immidiately while the defined motion is running.
366  # @return A boolean: \li True If the left arm is successfully synchronized with the object at the time of function exit
367  # \li False If the left arm fails to synchronize for any reason \n
368  # \b Note: If parameter \b wait is False, the function returns True only if the left arm is already synced
369  def sync_larm(self, ttr = 5.0, wait = True):
370  if not self.larm_synced():
371  pint.take_larm_to(self.larm.config.q, time_to_reach = ttr)
372  if wait:
373  pint.wait_until_finished(limb_list = ['larm'], max_time = self.max_wait_time['larm'])
374  return self.larm_synced()
375 
376  ## Synchronizes the real robot or robot in simulation with the object.
377  # The body, trunk, right and left arms synchronize simultaneously. If each part is already synced, it will not move.
378  # If the system is in \em Free-Base mode, the robot navigates to the position specified by \f$ x = q[8] \f$ and \f$ y = q[9] \f$
379  # and twists to rotation angle specified by \f$ \tau = q[10] \f$.
380  # (If the system is in \em fixed-base mode, the body will not move) \n
381  # The right arm takes the configuration specified by <b> self.q[0:7] </b> or <b> self.rarm.config.q[0:7] </b> \n
382  # The left arm takes the configuration specified by <b> self.q[11:18] </b> or <b> self.larm.config.q[0:7] </b>
383  # @param ttr A float specifying <em> time to reach </em> in seconds
384  # @param wait A boolean: \li If True, the system waits until the robot is synchronized or <b> self.max_wait_time['robot'] </b> is elapsed.
385  # (You don't exit the function before the motion is finished or the maximum waiting time is elapsed)
386  # \li If False, you will exit the function immidiately while the motion is running
387  # @return A boolean: \li True If robot is successfully synchronized with the object at the time of function exit
388  # \li False The robot fails to synchronize for any reason \n
389  # \b Note: If parameter \b wait is False, the function returns True only if the robot is already synced
390  def sync_robot(self, ttr = 5.0, wait = True):
391  '''
392  '''
393  ll = []
394  if (self.control_mode == 'free-base') and (not self.body_synced()):
395  self.set_config_synced(self.q, ttr = ttr, wait = False)
396  ll.append('body')
397 
398  self.sync_rarm(ttr = ttr, wait = False)
399  ll.append('rarm')
400  self.sync_larm(ttr = ttr, wait = False)
401  ll.append('larm')
402 
403  if wait:
404  pint.wait_until_finished(limb_list = ll, max_time = self.max_wait_time['robot'])
405 
406  return self.synced(limb_list = ll)
407 
408  ## Solves the Inverse Kinematics for the right arm with given redundant parameter \f$ \phi \f$
409  # and takes the right arm endeffector to the target specified by properties \b self.rarm.xd and \b self.rarm.Rd .
410  # @param phi A float by which you specify the value of the desired redundant parameter (The desired value of shoulder-pan joint).
411  # If phi = None, then the optimum phi corresponding to the minimum value of the objective function
412  # will be selected. (The default value is None)
413  # @param ttr A float specifying <em> time to reach </em> in seconds.
414  # Use this parameter to specify the amount of time needed to reach the target.
415  # Obviously this value influences the speed of motion.
416  # @param wait A boolean: \li If True, the system waits until the right arm gipper takes the desired target pose or <b> self.max_wait_time['rarm'] </b> is elapsed.
417  # (You don't exit the function before the target is achieved or the maximum waiting time is elapsed)
418  # \li If False, you will exit the function immidiately while the motion is running
419  # @return A boolean: \li True If the right arm can reach the target successfully
420  # \li False If the arm fails to reach the target for any reason \n
421  # \b Note: If parameter \b wait is False, the function returns True if an IK solution is found for the right arm.
422  def rarm_target(self, phi = None, ttr = 5.0, wait = True):
423  func_name = ".rarm_target()"
424  self.rarm.set_target(self.rarm.xd, self.rarm.Rd) # make sure the target parameters are set
425  if phi == None:
426  if self.rarm.goto_target(optimize = True):
427  qr = self.rarm.config.q
428  elif self.rarm.goto_target(optimize = False):
429  qr = self.rarm.config.q
430  else:
431  assert False, genpy.err_str(__name__, self.__class__.__name__, sys._getframe().f_code.co_name, "Could not find an IK solution for given target. Make sure the target pose is in the workspace")
432  else:
433  C = self.rarm.permission_set_position()
434  if phi in C:
435  qr = self.rarm.IK_config(phi)
436  else:
437  assert False, genpy.err_str(__name__, self.__class__.__name__, sys._getframe().f_code.co_name, "Given phi is not in the permission set")
438 
439  if qr == None:
440  assert False, genpy.err_str(__name__, self.__class__.__name__, sys._getframe().f_code.co_name, "No IK solution found for the given redundant parameter phi! Change the value of the redundant parameter and try again")
441  elif self.rarm.config.set_config(qr):
442  self.q[0:7] = qr
443  else:
444  print "Error from PyRidePR2.rarm_target(): This should not happen! Check your code."
445  return False
446 
447  return self.sync_robot(ttr = ttr, wait = wait) or (not wait)
448 
449  ## Solves the Inverse Kinematics for the left arm with given redundant parameter \f$ \phi \f$
450  # and takes the right arm endeffector to the target specified by properties \b self.larm.xd and \b self.larm.Rd .
451  # @param phi A float by which you specify the value of the desired redundant parameter (The desired value of shoulder-pan joint).
452  # If phi = None, then the optimum phi corresponding to the minimum value of the objective function
453  # will be selected. (The default value is None)
454  # @param ttr A float specifying <em> time to reach </em> in seconds.
455  # Use this parameter to specify the amount of time needed to reach the target.
456  # Obviously this value influences the speed of motion.
457  # @param wait A boolean: \li If True, the system waits until the left arm gipper takes the desired target pose or <b> self.max_wait_time['larm'] </b> is elapsed.
458  # (You don't exit the function before the target is achieved or the maximum waiting time is elapsed)
459  # \li If False, you will exit the function immidiately while the motion is running
460  # @return A boolean: \li True If the left arm can reach the target successfully
461  # \li False If the arm fails to reach the target for any reason \n
462  # \b Note: If parameter \b wait is False, the function returns True if an IK solution is found for the left arm.
463  def larm_target(self, phi = None, ttr = 5.0, wait = True):
464  '''
465  Solves the Inverse Kinematics for the left arm with given redundant parameter "phi"
466  and takes the right arm endeffector to the target specified by self.larm.xd and self.larm.Rd
467  if phi = None, then the optimum phi will be selected.
468  '''
469 
470  self.larm.set_target(self.larm.xd, self.larm.Rd) # make sure the target parameters are set
471  if phi == None:
472  if self.larm.goto_target(optimize = True):
473  ql = self.larm.config.q
474  else:
475  assert False, genpy.err_str(__name__, self.__class__.__name__, sys._getframe().f_code.co_name, "Could not find an IK solution for given target. Make sure the target pose is in the workspace")
476 
477  else:
478  C = self.larm.permission_set_position()
479  if phi in C:
480  ql = self.larm.IK_config(phi)
481  else:
482  assert False, genpy.err_str(__name__, self.__class__.__name__, sys._getframe().f_code.co_name, "Given phi is not in the permission set")
483  if ql == None:
484  assert False, genpy.err_str(__name__, self.__class__.__name__, sys._getframe().f_code.co_name, "No IK solution found for the given redundant parameter phi! Change the value of the redundant parameter and try again")
485  else:
486  if self.larm.config.set_config(ql):
487  self.q[11:18] = ql
488  else:
489  print "Error from PyRidePR2.larm_target(): This should not happen! Check your code."
490  return False
491 
492  return self.sync_robot(ttr = ttr, wait = wait) or (not wait)
493 
494  ## Solves the Inverse Kinematics for the reference arm with given redundant parameter \f$ \phi \f$
495  # The instructions are exactly the same as functions <b> self.rarm_target() </b> and <b> self.larm_target() </b>
496  def arm_target(self, phi = None, ttr = 5.0, wait = True):
497  if self.larm_reference:
498  return self.larm_target(phi = phi, ttr = ttr, wait = wait)
499  else:
500  return self.rarm_target(phi = phi, ttr = ttr, wait = wait)
501 
502  def reach_target(self):
503  '''
504  # should change to goto_target() calling the goto_target() function of the super class
505  Solves the IK in the current control mode and takes the robot endeffector to the desired pose specified by self.xd and self.Rd
506  '''
507  if self.larm_reference:
508  tl = ['larm']
509  else:
510  tl = ['rarm']
511 
512  if self.control_mode == "Free-Base":
513  tl.append('body')
514 
515  if self.goto_target():
516  self.set_config_synced(qd = self.q, limb_list = tl)
517  return True
518  else:
519  self.sync_object()
520  return False
521 
522  def reference_arm(self):
523  if self.larm_reference:
524  return(self.larm)
525  else:
526  return(self.rarm)
527 
528  ## Moves the reference arm wrist in backward direction maintaining the gripper orientation
529  # @param dx A float specifying the distance (in meters) by which the wrist should move in backward direction
530  # @param relative A boolean for selecting the orientation with respect to which the backward direction is defined \n
531  # If True, the backward direction is defined relative to the gripper orientation \n
532  # if False the absolute backward direction (with respect to the robot trunk) is considered
533  # @return A boolean: True, if the arm wrist reach the target successfully and
534  # False, if the IK fails to find a feasible solution or for any reason the wrist can not reach its target
535  def arm_back(self, dx = 0.1, relative = False, wait = True):
536  ttr = abs(dx/self.arm_speed)
537  arm = self.reference_arm()
538  pos = arm.wrist_position()
539  ori = arm.wrist_orientation()
540  if relative:
541  n = ori[:,2]
542  else:
543  n = rot.i_uv
544 
545  pos = pos - dx*n
546 
547  arm.set_target(pos, ori)
548  return self.arm_target(ttr = ttr, wait = wait)
549 
550  ## Moves the reference arm wrist in forward direction maintaining the gripper orientation
551  # @param dx A float specifying the distance (in meters) by which the wrist should move in forward direction
552  # @param relative A boolean for selecting the orientation with respect to which the forward direction is defined \n
553  # If True, the forward direction is defined relative to the gripper orientation \n
554  # If False the absolute forward direction (with respect to the robot trunk) is considered
555  # @return A boolean: True if the arm wrist reach the target successfully
556  # False if the IK fails to find a feasible solution or for any reason the wrist can not reach its target
557  def arm_forward(self, dx = 0.1, relative = False, wait = True):
558  ttr = abs(dx/self.arm_speed)
559  arm = self.reference_arm()
560  pos = arm.wrist_position()
561  ori = arm.wrist_orientation()
562  if relative:
563  n = ori[:,2]
564  else:
565  n = rot.i_uv
566  pos = pos + dx*n
567  arm.set_target(pos, ori)
568  return self.arm_target(ttr = ttr, wait = wait)
569 
570  ## Moves the reference arm wrist in downward direction maintaining the gripper orientation
571  # @param dx A float specifying the distance (in meters) by which the wrist should move in downward direction
572  # @param relative A boolean for selecting the orientation with respect to which the downward direction is defined \n
573  # If True, the downward direction is defined relative to the gripper orientation \n
574  # If False the absolute downward direction (with respect to the robot trunk) is considered
575  # @return A boolean: True if the arm wrist reach the target successfully
576  # False if the IK fails to find a feasible solution or for any reason the wrist can not reach its target
577  def arm_down(self, dx = 0.1, relative = False, wait = True):
578  ttr = abs(dx/self.arm_speed)
579  arm = self.reference_arm()
580  pos = arm.wrist_position()
581  ori = arm.wrist_orientation()
582  if relative:
583  h = ori[:,1]
584  else:
585  h = rot.k_uv
586  pos = pos - dx*h
587  arm.set_target(pos, ori)
588  return self.arm_target(ttr = ttr, wait = wait)
589 
590  ## Moves the reference arm wrist in upward direction maintaining the gripper orientation
591  # @param dx A float specifying the distance (in meters) by which the wrist should move in upward direction
592  # @param relative A boolean for selecting the orientation with respect to which the upward direction is defined \n
593  # If True, the upward direction is defined relative to the gripper orientation \n
594  # If False the absolute upward direction (with respect to the robot trunk) is considered
595  # @return A boolean: True if the arm wrist reach the target successfully
596  # False if the IK fails to find a feasible solution or for any reason the wrist can not reach its target
597  def arm_up(self, dx = 0.1, relative = False, wait = True):
598  ttr = abs(dx/self.arm_speed)
599  arm = self.reference_arm()
600  pos = arm.wrist_position()
601  ori = arm.wrist_orientation()
602  if relative:
603  h = ori[:,1]
604  else:
605  h = rot.k_uv
606  pos = pos + dx*h
607  arm.set_target(pos, ori)
608  return self.arm_target(ttr = ttr, wait = wait)
609 
610  ## Moves the reference arm wrist to the right maintaining the gripper orientation
611  # @param dx A float specifying the distance (in meters) by which the wrist should move to the right
612  # @param relative A boolean for selecting the orientation with respect to which the direction to the right is defined
613  # If True, the right direction is defined relative to the gripper orientation,
614  # if False the absolute direction to the right (with respect to the robot trunk) is considered
615  # @return A boolean: True if the arm wrist reach the target successfully
616  # False if the IK fails to find a feasible solution or for any reason the wrist can not reach its target
617  def arm_right(self, dx = 0.1, relative = False, wait = True):
618  '''
619  moves the arm to the right as much as dx (m) maintaining the orientation
620  '''
621  ttr = abs(dx/self.arm_speed)
622  arm = self.reference_arm()
623  pos = arm.wrist_position()
624  ori = arm.wrist_orientation()
625  if relative:
626  w = ori[:,0]
627  else:
628  w = rot.j_uv
629  pos = pos - dx*w
630  arm.set_target(pos, ori)
631  return self.arm_target(ttr = ttr, wait = wait)
632 
633  ## Moves the reference arm wrist to the left maintaining the gripper orientation.
634  # The speed of motion is set by property self.arm_speed
635  # @param dx A float specifying the distance (in meters) by which the wrist should move to the left
636  # @param relative A boolean for selecting the orientation with respect to which the left direction is defined
637  # If True, the left direction is defined relative to the gripper orientation,
638  # if False the absolute left direction (with respect to the robot trunk) is considered
639  # @return A boolean: True if the arm wrist reach the target successfully
640  # False if the IK fails to find a feasible solution or for any reason the wrist can not reach its target
641  def arm_left(self, dx = 0.1, relative = False, wait = True):
642  ttr = abs(dx/self.arm_speed)
643  arm = self.reference_arm()
644  pos = arm.wrist_position()
645  ori = arm.wrist_orientation()
646  if relative:
647  w = ori[:,0]
648  else:
649  w = rot.j_uv
650  pos = pos + dx*w
651  arm.set_target(pos, ori)
652  return self.arm_target(ttr = ttr, wait = wait)
653 
654  ## Moves the reference arm wrist to the left and downward direction maintaining the gripper orientation.
655  # The speed of motion is set by property self.arm_speed
656  # @param dx A float specifying the distance (in meters) by which the wrist should move to the left
657  # @param dy A float specifying the distance (in meters) by which the wrist should move downwards
658  # @param relative A boolean for selecting the orientation with respect to which the left and downward directions are defined
659  # If True, the left and downward directions are defined relative to the gripper orientation,
660  # if False the absolute left and downward directions (with respect to the robot trunk) are considered
661  # @return A boolean: True if the arm wrist reach the target successfully
662  # False if the IK fails to find a feasible solution or for any reason the wrist can not reach its target
663  def arm_left_down(self, dx = 0.1, dy = 0.1, relative = False, wait = True):
664  ttr = math.sqrt(dx*dx + dy*dy)/self.arm_speed
665  arm = self.reference_arm()
666  pos = arm.wrist_position()
667  ori = arm.wrist_orientation()
668  if relative:
669  w = ori[:,0]
670  h = ori[:,1]
671  else:
672  w = rot.j_uv
673  h = rot.k_uv
674  pos = pos + dx*w - dy*h
675  arm.set_target(pos, ori)
676  return self.arm_target(ttr = ttr, wait = wait)
677 
678  ## Moves the reference arm wrist to both left and upward directions maintaining the gripper orientation.
679  # The speed of motion is set by property self.arm_speed
680  # @param dx A float specifying the distance (in meters) by which the wrist should move to the left
681  # @param dy A float specifying the distance (in meters) by which the wrist should move upwards
682  # @param relative A boolean for selecting the orientation with respect to which the left and upward directions are defined
683  # If True, the left and upward directions are defined relative to the gripper orientation,
684  # if False the absolute left and upward directions (with respect to the robot trunk) are considered
685  # @return A boolean: True if the arm wrist reach the target successfully
686  # False if the IK fails to find a feasible solution or for any reason the wrist can not reach its target
687  def arm_left_up(self, dx = 0.1, dy = 0.1, relative = False, wait = True):
688  ttr = math.sqrt(dx*dx + dy*dy)/self.arm_speed
689  arm = self.reference_arm()
690  pos = arm.wrist_position()
691  ori = arm.wrist_orientation()
692  if relative:
693  w = ori[:,0]
694  h = ori[:,1]
695  else:
696  w = rot.j_uv
697  h = rot.k_uv
698  pos = pos + dx*w + dy*h
699  arm.set_target(pos, ori)
700  return self.arm_target(ttr = ttr, wait = wait)
701 
702  def arm_right_up(self, dx = 0.1, dy = 0.1, relative = False, wait = True):
703  '''
704  moves the arm to the left as much as dx (m) maintaining the orientation
705  '''
706  ttr = math.sqrt(dx*dx + dy*dy)/self.arm_speed
707  arm = self.reference_arm()
708  pos = arm.wrist_position()
709  ori = arm.wrist_orientation()
710  if relative:
711  w = ori[:,0]
712  h = ori[:,1]
713  else:
714  w = rot.j_uv
715  h = rot.k_uv
716  pos = pos - dx*w + dy*h
717  arm.set_target(pos, ori)
718  return self.arm_target(ttr = ttr, wait = wait)
719 
720  def arm_right_down(self, dx = 0.1, dy = 0.1, relative = False, wait = True):
721  '''
722  moves the arm to the left as much as dx (m) maintaining the orientation
723  '''
724  ttr = math.sqrt(dx*dx + dy*dy)/self.arm_speed
725  arm = self.reference_arm()
726  pos = arm.wrist_position()
727  ori = arm.wrist_orientation()
728  if relative:
729  w = ori[:,0]
730  h = ori[:,1]
731  else:
732  w = rot.j_uv
733  h = rot.k_uv
734  pos = pos - dx*w - dy*h
735  arm.set_target(pos, ori)
736  return self.arm_target(ttr = ttr, wait = wait)
737 
738  ## Starting from the current wrist position , the arm wrist draws an arc around the given \b center
739  # with the given \b angle in the plane specified by the given \b normal vector.
740  # @param center A numpy vector of 3 elements specifying the position of the arc center w.r.t. the starting point and
741  # should be in the coordinate system of the gripper
742  # @param angle A float specifying the arc angle in radians (The default value is \f$ \pi \f$)
743  # @param N An integer specifying the number of key points in the arc trajectory (The default value is 100)
744  # @param normal A numpy vector of 3 elements specifying a vector perpendicular to the arc plane.
745  # The given vector should be in the coordinate system of the gripper and
746  # must be perpendicular to the vector given by parameter \b center
747  # (The default value is unit vector \f$ i = [1.0, 0.0, 0.0] \f$ specifying the forward direction w.r.t. the gripper)
748  # @param wait A boolean: \li If True, the system waits until the arc reaches the end of arc trajectory.
749  # (You don't exit the function before the trajectory is finished)
750  # \li If False, you will exit the function immidiately while the defined motion is running
751  # @return A boolean: \li True if the arc trajectory is successfully projected to the jointspace and
752  # in case argument \b wait is True, the wrist finishes the trajectory successfully
753  # \li False if for any reason the IK trajectory projection fails or in case parameter \b wait is True,
754  # the robot wrist fails to finish the trajectory
755  def arm_arc(self, center = np.array([0.0, -0.05, 0.0]), angle = math.pi, normal = np.array([1.0, 0.0, 0.0]), N = 100, wait = True):
756  '''
757  '''
758  # assert genmath.equal(vecmat.angle(center, normal), 0.0), "Error from PyRide_PR2(): center and normal must be perpendicular"
759 
760  #tt = trajlib.Trajectory_Polynomial()
761  #jt = trajlib.Trajectory_Polynomial(dimension = 7)
762  d_theta = angle/N
763  r = np.linalg.norm(center)
764  ttr = r*d_theta/self.arm_speed
765 
766  arm = self.reference_arm()
767  p0 = arm.wrist_position()
768  ori = arm.wrist_orientation()
769  '''
770  J = [- vecmat.normalize(center)]
771  J = np.append(J, [vecmat.normalize(normal)])
772  Jdag = vecmat.right_pseudo_inverse(J)
773  '''
774  #tt.add_point(phi = 0.0, pos = p0)
775  #jt.add_point(phi = 0.0, pos = arm.config.q)
776  if self.larm_reference:
777  g = pint.gen_larm_joint_posvel_dict(arm.config.q, np.zeros(7), 0.0)
778  else:
779  g = pint.gen_rarm_joint_posvel_dict(arm.config.q, np.zeros(7), 0.0)
780 
781  config_list = [g]
782 
783  for i in range(N):
784  theta = (i+1)*d_theta
785  '''
786  b = np.array([math.cos(theta), 0.0])
787  x = np.dot(Jdag, b)
788  pos = p0 + center + r*normalize(x)
789  '''
790  q0 = np.copy(arm.config.q)
791  ax = np.append(theta, vecmat.normalize(normal))
792  R = rot.rotation_matrix(ax, parametrization = 'angle_axis')
793  pos = p0 + center - np.dot(R, center)
794  arm.set_target(pos, ori)
795  arm.config.qm = np.copy(arm.config.q)
796  if arm.move_towards_target(max_speed = self.arm_max_speed, ttr = d_theta):
797  if i == N - 1:
798  vel = np.zeros(7)
799  else:
800  vel = (arm.config.q - q0)/ttr
801 
802  if self.larm_reference:
803  g = pint.gen_larm_joint_posvel_dict(arm.config.q, vel, ttr)
804  else:
805  g = pint.gen_rarm_joint_posvel_dict(arm.config.q, vel, ttr)
806  else:
807  print "The arc is not in the workspace!"
808  return False
809 
810  config_list.append(g)
811 
812  if self.larm_reference:
813  pint.larm_failed = False
814  pint.larm_reached = False
815  moving_limbs = ['larm']
816  else:
817  pint.rarm_failed = False
818  pint.rarm_reached = False
819  moving_limbs = ['rarm']
820 
821  PyPR2.moveArmWithJointTrajectoryAndSpeed(config_list)
822  arm.config.qm = 0.5*(arm.config.ql+arm.config.qh)
823  if wait:
824  pint.wait_until_finished(limb_list = moving_limbs, max_time = 10*N*ttr)
825  self.sync_object()
826 
827  ## Changes the orientation of the reference arm gripper to a desired direction with out changing the wrist position.
828  # @direction A string specifying the direction. Must be selected among: \n
829  # 'forward', 'backward', 'upward', 'downward', 'right', 'left'
830  # @param ttr A float specifying the time to reach the target orientation
831  # @param wait A boolean: \li If True, the system waits until the arm gripper
832  # is reached to the desired orientation or <b> self.max_wait_time </b> of the reference arm is elapsed.
833  # (You don't exit the function before the motion is finished or the maximum waiting time is elapsed)
834  # \li If False, you will exit the function immidiately while the defined motion is running
835  # @return A boolean: \li True if the arm gripper reach the target orientation successfully
836  # \li False if the IK fails to find a feasible solution or for any reason the gripper can not reach the target orientation.
837  def arm_orient(self, direction = 'forward', ttr = 2.0, wait = True):
838  if direction == 'upward':
839  ori = rot.point_upward_orientation
840  elif direction == 'downward':
841  ori = rot.point_downward_orientation
842  elif direction == 'forward':
843  ori = rot.point_forward_orientation
844  elif direction == 'backward':
845  ori = rot.point_backward_orientation
846  elif direction == 'right':
847  ori = rot.point_right_orientation
848  elif direction == 'left':
849  ori = rot.point_left_orientation
850  else:
851  assert False, genpy.err_str(__name__, self.__class__.__name__, sys._getframe().f_code.co_name, direction + " is not a valid value for direction")
852 
853  self.sync_object()
854  arm = self.reference_arm()
855  pos = arm.wrist_position()
856  arm.set_target(pos, ori)
857  return self.arm_target(ttr = ttr, wait = wait)
858 
859  def front_line_tilt(self):
860  '''
861  Returns the front line of tilt scan
862  '''
863  if not pint.tl_active:
864  self.activate_tilt_laser()
865 
866  (a, b, r) = lss.front_line(dist = pint.tl_dist, position_range = self.tilt_laser_scan_range, angle_min = -0.829031407833, angle_step = 0.00436332309619)
867 
868  return (a, b, np.linalg.norm(r) )
869 
870  def front_line_base(self):
871  '''
872  Returns the front line of tilt scan
873  '''
874  if not pint.bl_active:
875  self.activate_base_laser()
876 
877  (a, b, r) = lss.front_line(dist = pint.bl_dist, position_range = self.base_laser_scan_range, angle_min = -2.26892805099, angle_step = 0.00436332309619)
878 
879  return (a, b, np.linalg.norm(r) )
880 
881  '''
882  def front_plane(self):
883 
884  # Start:
885  dist = copy.copy(pint.dist)
886 
887  (beta, intercept, residuals) = front_line(dist)
888  stay = True
889  while stay:
890  outliers = rlib.which(residuals , '<' , 0.1 )
891  dist = rlib.pick(dist, - outliers)
892  (beta, intercept, residuals) = front_line(dist)
893  '''
894 
895  ## Runs a given arm task-space pose trajectory on the robot. The given trajectory will be tracked by the wrist.
896  # @param pos_traj An instance of class packages.nima.robotics.kinematics.task_space.trajectory.Trajectory_Polynomial()
897  # specifying the trajectory in the 3D taskspace to be tracked by the arm.
898  # @param ori_traj An instance of class packages.nima.robotics.kinematics.task_space.trajectory.Trajectory_Polynomial()
899  # specifying the trajectory in the 3D taskspace to be tracked by the arm.
900  def arm_trajectory(self, pos_traj, ori_traj = None, resolution = 50, relative = True, wait = True):
901  '''
902  First, projects the given taskspace pose trajectory into the jointspace
903  using both velocity-based and position-based inverse kinematics of the arm and
904  creates a joint trajectory.
905  Then the joint trajectory is given to function run_config_trajectory of pyride_interpreter to run on the robot.
906  '''
907  L = sum(pos_traj.points_dist()) # You will need to accommodate for orientation as well
908 
909  self.sync_object()
910  arm = self.reference_arm()
911 
912  assert resolution > 4, genpy.err_str(__name__, self.__class__.__name__, sys._getframe().f_code.co_name, str(resolution) + " is an invalid value for resolution. Must be greater than 4")
913 
914  keep_dt = arm.dt
915  arm.dt = pos_traj.phi_end/resolution
916  #jt = arm.js_project(pos_traj, ori_traj, relative = relative, traj_type = 'polynomial')
917  jt = arm.js_project(pos_traj, ori_traj, relative = relative)
918  arm.dt = keep_dt
919 
920  #jt.segment[0].interpolate() # Check why you have to do an extra interpolate .... !!!!
921  #jt.consistent_velocities()
922  '''
923  jt.plot()
924  jt.plot(1)
925  jt.plot(4)
926 
927  (pt, ot) = arm.project_to_ts(jt)
928  pt.plot3d()
929  '''
930 
931  pint.run_config_trajectory(jt, duration = L/self.arm_speed, dt = None, phi_dot = None, is_left_arm = self.larm_reference)
932 
933  if self.larm_reference:
934  moving_limbs = ['larm']
935  else:
936  moving_limbs = ['rarm']
937 
938  if wait:
939  pint.wait_until_finished(limb_list = moving_limbs, max_time = 10*L/self.arm_speed)
940 
941  self.sync_object()
942 
943  ## Activates the Kinematic Control Service
944  def activate_kc(self):
945  self.kc_service_cnt = 0
946  self.prev_qdot = np.zeros(7)
947  self.kc_gain = 1.0
948  PyPR2.registerRawTrajectoryInput( self.kc_service )
949  assert PyPR2.useJointVelocityControl(True)
950 
951  ## Deactivates the Kinematic Control Service
952  def deactivate_kc(self):
953  self.kc_service_cnt = 0
954  PyPR2.registerRawTrajectoryInput( None )
955  assert PyPR2.useJointVelocityControl(False)
956 
957  def kc_service(self, data):
958  if self.larm_reference:
959  pe = self.p_EFL_WL
960  actual_pos = pint.larm_wrist_position()
961  actual_ori = geo.Orientation_3D(pint.larm_wrist_orientation(), representation = 'quaternion')
962  actual_jnt = pint.larm_joints(in_degrees = False)
963  else:
964  pe = self.p_EFR_WR
965  actual_pos = pint.rarm_wrist_position()
966  actual_ori = geo.Orientation_3D(pint.rarm_wrist_orientation(), representation = 'quaternion')
967  actual_jnt = pint.rarm_joints(in_degrees = False)
968 
969  self.kc_service_cnt += 1
970  self.sync_object()
971  arm = self.reference_arm()
972  desired_pos = np.array(data['position'])
973  desired_ori = geo.Orientation_3D(data['orientation'], representation = 'quaternion')
974  desired_pos -= np.dot(desired_ori['matrix'], pe)
975  arm.set_target(desired_pos, desired_ori['matrix'])
976  if self.kc_service_cnt == 1:
977  '''
978  self.kc_time = data['timestamp']
979  self.t0 = data['timestamp']
980  '''
981  self.kc_time = 0.0
982  self.t0 = time.time()
983  self.prev_err = arm.pose_metric()
984  self.kc_ptd = trajlib.Trajectory_Polynomial()
985  self.kc_otd = trajlib.Orientation_Trajectory_Polynomial()
986  self.kc_pta = trajlib.Trajectory_Polynomial()
987  self.kc_ota = trajlib.Orientation_Trajectory_Polynomial()
988  self.kc_jtd = trajlib.Trajectory(dimension = 7, capacity = 10)
989  self.kc_jta = trajlib.Trajectory(dimension = 7, capacity = 10)
990  '''
991  arm.goto_target(optimize = True)
992  '''
993  self.kc_jtd.add_point(phi = self.kc_time, pos = np.copy(arm.config.q), vel = np.zeros(7), acc = np.zeros(7))
994  else:
995  '''
996  dt = data['timestamp'] - self.kc_time
997  self.kc_time = data['timestamp']
998  '''
999  dt = time.time() - self.t0 - self.kc_time
1000  self.kc_time += dt
1001  if data['in_progress']:
1002  q0 = np.copy(arm.config.q)
1003  arm.config.qm = np.copy(arm.config.q)
1004  # arm.goto_target(optimize = True)
1005  arm.dt = dt
1006  if arm.moveto_target(optimize = True):
1007  jdir = arm.config.q - q0
1008  q_dot = jdir/dt
1009 
1010  (jpos, vel, acc) = trajlib.feasible_position(Xd = np.copy(arm.config.q), X0 = q0, V0 = self.prev_qdot, X_min = arm.config.ql, X_max = arm.config.qh, v_max = arm.max_js, a_max = arm.max_ja, dt = dt, smooth = True)
1011  pint.send_arm_joint_speed(vel, is_left_arm = self.larm_reference)
1012  self.prev_qdot = np.copy(vel)
1013 
1014  self.kc_jtd.add_point(phi = self.kc_time, pos = jpos, vel = vel, acc = acc)
1015  else:
1016  self.kc_jtd.add_point(phi = self.kc_time, pos = np.copy(arm.config.q), vel = np.zeros(7), acc = np.zeros(7))
1017  pint.send_arm_joint_speed(np.zeros(7), is_left_arm = self.larm_reference)
1018  arm.config.qm = 0.5*(arm.config.ql + arm.config.qh)
1019  self.deactivate_kc()
1020 
1021  self.kc_ptd.add_point(phi = self.kc_time, pos = np.copy(desired_pos))
1022  self.kc_otd.add_point(phi = self.kc_time, ori = copy.deepcopy(desired_ori))
1023  self.kc_pta.add_point(phi = self.kc_time, pos = np.copy(actual_pos))
1024  self.kc_ota.add_point(phi = self.kc_time, ori = copy.deepcopy(actual_ori))
1025  self.kc_jta.add_point(phi = self.kc_time, pos = np.copy(actual_jnt))
1026 
1027  def arm_track(self, k = 1.0, delay = 0.1, max_speed = 1.0, relative = True):
1028 
1029  ts = time.time()
1030  t0 = 0.0
1031 
1032  arm = self.reference_arm()
1033  assert arm.magiks_running
1034 
1035  self.sync_object()
1036 
1037  # activate raw trajectory input:
1038  pint.activate_trajectory_input()
1039  if pint.rt_orientation == None:
1040  H = arm.ik.transfer_matrices()
1041  ra = arm.ik.task_frame[0].orientation(H)
1042  pint.rt_orientation = np.copy(ra['matrix'])
1043 
1044  if relative:
1045  H = arm.ik.transfer_matrices()
1046  p0 = arm.ik.task_point[0].position(H) - pint.rt_position
1047  ra = arm.ik.task_frame[0].orientation(H)
1048  R0 = np.dot(ra['matrix'], pint.rt_orientation.T)
1049  else:
1050  p0 = np.zeros(3)
1051  R0 = np.eye(3)
1052 
1053  t = time.time() - ts
1054  dt = t - t0
1055  t0 = t
1056 
1057  stay = True
1058  cnt = 0
1059  q_dot = np.zeros(7)
1060 
1061  while stay:
1062  cnt += 1
1063  p = p0 + pint.rt_position
1064  # p = p0 + pint.rt_position
1065  R = np.dot(R0, pint.rt_orientation)
1066  # arm.set_target(p, R)
1067  arm.ik.set_target([p], [geo.Orientation_3D(R, np.zeros((3,3)))])
1068 
1069  t = time.time() - ts
1070  dt = t - t0
1071 
1072  # print
1073  # print "q_dot : ", q_dot
1074  # print "ik.q : ", ik.q
1075  # print "ik.q + dt*q_dot: ", ik.q + dt*q_dot
1076 
1077  # ik.set_config(ik.q + dt*q_dot)
1078 
1079  # print "q_dt after sync: ", (ik.q - q_p)/dt
1080 
1081  err = arm.ik.pose_error()
1082  ern = arm.ik.pose_error_norm()
1083  Je = arm.ik.error_jacobian()
1084 
1085  if arm.ik.ik_settings.algorithm == "JPI":
1086  Je_dag = np.linalg.pinv(Je)
1087  else:
1088  assert False
1089 
1090  # q_dot = - np.dot(Je_dag, np.append(pint.rt_velocity, np.zeros(3)) + k*err)
1091  # q_dot = - np.dot(Je_dag, k*np.append(pint.rt_velocity, np.zeros(3)))
1092  q_dot = k*arm.ik.ik_direction()
1093  # q_dot = arm.ik_direction()
1094 
1095  qf = arm.config.q + q_dot*dt # estimated joint values in the future (next time step)
1096  arm.ik.set_config(qf)
1097  '''
1098  if arm.ik.pose_error_norm() < ern:
1099  # error is expected to reduce, send the joint speed
1100  landa = 1.0
1101  pint.send_arm_joint_speed(q_dot, is_left_arm = self.larm_reference)
1102  else:
1103  # error is going to raise, send the speed with a gain
1104  landa = 0.01/(0.01 + ern)
1105  '''
1106  pint.send_arm_joint_speed(q_dot, is_left_arm = self.larm_reference)
1107  '''
1108  # pint.send_arm_joint_speed(q_dot*k, is_left_arm = self.larm_reference)
1109 
1110  if cnt == 100*(cnt/100):
1111  print
1112  print "cnt: ", cnt
1113  print "traj pos:", pint.rt_position
1114  print "Actual: ", ik.task_point[0].position(ik.transfer_matrices())
1115  print "Desired: ", ik.task_point[0].rd
1116  print "Pose err:", ik.pose_error_norm()
1117  print "Qd Norm: ", np.linalg.norm(q_dot)
1118  '''
1119  t = time.time() - ts
1120  t0 = t
1121  print "times: ", t, dt
1122  # time.sleep(0.01)
1123  '''
1124  print
1125  print "CJV: ", ik.q
1126  print "EJV: ", ik.q + dt*q_dot
1127  '''
1128  stay = (t < 100.0)
1129 
1130  print "Time Out!"
1131  pint.send_arm_joint_speed(np.zeros(7), is_left_arm = self.larm_reference)
1132  pint.deactivate_trajectory_input()
1133  # self.sync_object()
def deactivate_kc
Deactivates the Kinematic Control Service.
def sync_body
Synchronizes the position and orientation of the real robot body or robot in simulation with the obje...
def synced
Use this function to check if the robot is synchronized with the object.
def arm_left_up
Moves the reference arm wrist to both left and upward directions maintaining the gripper orientation...
def arm_back
Moves the reference arm wrist in backward direction maintaining the gripper orientation.
def arm_up
Moves the reference arm wrist in upward direction maintaining the gripper orientation.
max_wait_time
A dictionary specifying the maximum waiting time when you choose to wait for any motion to finish...
def sync_robot
Synchronizes the real robot or robot in simulation with the object.
def sync_object
Synchronizes the object with the robot and verifies the equity of forward kinematics for both the rig...
def arm_forward
Moves the reference arm wrist in forward direction maintaining the gripper orientation.
def larm_target
Solves the Inverse Kinematics for the left arm with given redundant parameter and takes the right ar...
def sync_rarm
Synchronizes the right arm of the real robot or robot in simulation with the right arm of the object...
def larm_synced
Use this function to check if the left arm of the object is synced with the left arm of the real robo...
This class introduces a data structure for complete kinematics of a PR2 robot which can sychronize it...
def arm_down
Moves the reference arm wrist in downward direction maintaining the gripper orientation.
def say
Use this function if you want the robot to say something.
def arm_left
Moves the reference arm wrist to the left maintaining the gripper orientation.
def sync_larm
Synchronizes the left arm of the real robot or robot in simulation with the left arm of the object...
def activate_kc
Activates the Kinematic Control Service.
def arm_left_down
Moves the reference arm wrist to the left and downward direction maintaining the gripper orientation...
def rarm_synced
Use this function to check if the right arm of the object is synced with the right arm of the real ro...
def arm_orient
Changes the orientation of the reference arm gripper to a desired direction with out changing the wri...
def arm_trajectory
Runs a given arm task-space pose trajectory on the robot.
def arm_target
Solves the Inverse Kinematics for the reference arm with given redundant parameter The instructions ...
arm_speed
A float specifying the speed of arm gripper in the operational space in m/sec.
def rarm_target
Solves the Inverse Kinematics for the right arm with given redundant parameter and takes the right a...
def arm_right
Moves the reference arm wrist to the right maintaining the gripper orientation.
def arm_arc
Starting from the current wrist position , the arm wrist draws an arc around the given center with th...