WUT Velma robot API
test_velma_ik_geom.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 # Inverse kinematics for KUKA LWR 4+ robot
4 # Copyright (c) 2021, Robot Control and Pattern Recognition Group,
5 # Institute of Control and Computation Engineering
6 # Warsaw University of Technology
7 #
8 # All rights reserved.
9 #
10 # Redistribution and use in source and binary forms, with or without
11 # modification, are permitted provided that the following conditions are met:
12 # * Redistributions of source code must retain the above copyright
13 # notice, this list of conditions and the following disclaimer.
14 # * Redistributions in binary form must reproduce the above copyright
15 # notice, this list of conditions and the following disclaimer in the
16 # documentation and/or other materials provided with the distribution.
17 # * Neither the name of the Warsaw University of Technology nor the
18 # names of its contributors may be used to endorse or promote products
19 # derived from this software without specific prior written permission.
20 #
21 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
22 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 # DISCLAIMED. IN NO EVENT SHALL <COPYright HOLDER> BE LIABLE FOR ANY
25 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #
32 # Author: Dawid Seredynski
33 #
34 
35 import rospy
36 import copy
37 import cv2
38 import PyKDL
39 import math
40 import numpy as np
41 import random
42 
43 from visualization_msgs.msg import *
44 from sensor_msgs.msg import JointState
45 
47 from velma_kinematics.velma_ik_geom import KinematicsSolverLWR4, KinematicsSolverVelma
48 
49 def strFrame(T):
50  qx, qy, qz, qw = T.M.GetQuaternion()
51  return 'PyKDL.Frame(PyKDL.Rotation.Quaternion({}, {}, {}, {}), PyKDL.Vector({}, {}, {}))'.format(qx, qy, qz, qw, T.p.x(), T.p.y(), T.p.z())
52 
53 def printFrame(T):
54  print strFrame(T)
55 
56 def testFK(arm_name):
57  assert arm_name in ('right', 'left')
58  m_pub = MarkerPublisher('velma_ik_geom')
59  js_pub = rospy.Publisher('/joint_states', JointState, queue_size=1000)
60  rospy.sleep(0.5)
61 
62  solv = KinematicsSolverLWR4()
63  js_msg = JointState()
64  for i in range(7):
65  js_msg.name.append('{}_arm_{}_joint'.format(arm_name, i))
66  js_msg.position.append(0.0)
67 
68  js_msg.name.append('torso_0_joint')
69  js_msg.position.append(0.0)
70 
71  phase = 0.0
72  while not rospy.is_shutdown():
73  q = [ math.sin(phase),
74  math.sin(phase*1.1),
75  math.sin(phase*1.2),
76  math.sin(phase*1.3),
77  math.sin(phase*1.4),
78  math.sin(phase*1.5),
79  math.sin(phase*1.6)]
80  phase += 0.01
81 
82  T_A0_A7 = solv.calculateFk( q )
83  m_id = 0
84  m_id = m_pub.publishFrameMarker(T_A0_A7, m_id, scale=0.5,
85  frame='calib_{}_arm_base_link'.format(arm_name), namespace='default')
86  js_msg.header.stamp = rospy.Time.now()
87  for i in range(7):
88  js_msg.position[i] = q[i]
89  js_pub.publish(js_msg)
90 
91  rospy.sleep(0.04)
92 
94  limits = [[-2.96, 2.96],
95  [-2.09, 2.09],
96  [-2.96, 2.96],
97  [-2.095, 2.095],
98  [-2.96, 2.96],
99  [-2.09, 2.09],
100  [-2.96, 2.96],]
101 
102  result = []
103  samples = 4
104  for q0 in np.linspace(limits[0][0], limits[0][1], samples, endpoint=True):
105  for q1 in np.linspace(limits[1][0], limits[1][1], samples, endpoint=True):
106  for q2 in np.linspace(limits[2][0], limits[2][1], samples, endpoint=True):
107  for q3 in np.linspace(limits[3][0], limits[3][1], samples, endpoint=True):
108  for q4 in np.linspace(limits[4][0], limits[4][1], samples, endpoint=True):
109  for q5 in np.linspace(limits[5][0], limits[5][1], samples, endpoint=True):
110  for q6 in np.linspace(limits[6][0], limits[6][1], samples, endpoint=True):
111  result.append( (q0, q1, q2, q3, q4, q5, q6) )
112  return result
113 
114 def testIk1():
115  solv = KinematicsSolverLWR4()
116 
117  samples = generateTestQ()
118  samples_count = len(samples)
119  print('Number of samples: {}'.format(samples_count))
120 
121  for sample_idx, sample in enumerate(samples):
122  q = sample
123  # Calculate FK
124  print('sample: {} / {}'.format(sample_idx, samples_count))
125  T_A0_A7d = solv.calculateFk( q )
126  #print(' T_A0_A7d: {}'.format(strFrame(T_A0_A7d)))
127 
128  for elbow_circle_angle in np.linspace(-math.pi, math.pi, 10, endpoint=True):
129  #print(' elbow_circle_angle: {}'.format(elbow_circle_angle))
130  iq = solv.calculateIk(T_A0_A7d, elbow_circle_angle, False, False, False)
131  T_A0_A7 = solv.calculateFk( iq )
132  # compare results
133  diff = PyKDL.diff(T_A0_A7, T_A0_A7d, 1.0)
134  if diff.vel.Norm() > 0.00001 or diff.rot.Norm() > 0.00001:
135  print('ERROR: {}: {}, {}, {}, {}'.format(sample_idx, sample, elbow_circle_angle, strFrame(T_A0_A7d), strFrame(T_A0_A7)))
136  return
137 
138 def testIk2(arm_name, T_A0_A7d, ampl):
139  assert arm_name in ('right', 'left')
140 
141  m_pub = MarkerPublisher('velma_ik_geom')
142  js_pub = rospy.Publisher('/joint_states', JointState, queue_size=1000)
143  rospy.sleep(0.5)
144 
145  solv = KinematicsSolverLWR4()
146 
147  js_msg = JointState()
148  for i in range(7):
149  js_msg.name.append('{}_arm_{}_joint'.format(arm_name, i))
150  js_msg.position.append(0.0)
151 
152  js_msg.name.append('torso_0_joint')
153  js_msg.position.append(0.0)
154 
155  base_link_name = 'calib_{}_arm_base_link'.format(arm_name)
156  phase = 0.0
157  while not rospy.is_shutdown():
158  tx = ampl * math.sin(phase)
159  ty = ampl * math.sin(phase*1.1)
160  tz = ampl * math.sin(phase*1.2)
161  T_A0_A7d2 = PyKDL.Frame(PyKDL.Rotation(), PyKDL.Vector(tx, ty, tz)) * T_A0_A7d
162  elbow_circle_angle = phase*1.3
163  phase += 0.01
164 
165  flip_elbow = (math.sin(phase*1.51) > 0)
166  flip_ee = (math.sin(phase*1.93) > 0)
167  flip_shoulder = (math.sin(phase*2.73) > 0)
168  q = solv.calculateIk(T_A0_A7d2, elbow_circle_angle, flip_shoulder, flip_elbow, flip_ee)
169  pt_shoulder = solv.getDebug('pt_shoulder')
170  elbow_pt = solv.getDebug('elbow_pt')
171  ee_pt = solv.getDebug('ee_pt')
172  #T_A0_A6 = solv.getDebug('T_A0_A6')
173  m_id = 0
174  if not pt_shoulder is None and not ee_pt is None:
175  m_id = m_pub.publishVectorMarker(pt_shoulder, ee_pt, m_id, 1, 0, 0, a=1,
176  frame=base_link_name, namespace='default', scale=0.01)
177  if not pt_shoulder is None and not elbow_pt is None:
178  m_id = m_pub.publishVectorMarker(pt_shoulder, elbow_pt, m_id, 1, 0, 0, a=1,
179  frame=base_link_name, namespace='default', scale=0.01)
180 
181  m_id = m_pub.publishFrameMarker(T_A0_A7d2, m_id, scale=0.1,
182  frame=base_link_name, namespace='default')
183  js_msg.header.stamp = rospy.Time.now()
184  for i in range(7):
185  if q[i] is None:
186  js_msg.position[i] = 0.0
187  else:
188  js_msg.position[i] = q[i]
189  js_pub.publish(js_msg)
190 
191  rospy.sleep(0.04)
192 
194  while True:
195  qx = random.gauss(0.0, 1.0)
196  qy = random.gauss(0.0, 1.0)
197  qz = random.gauss(0.0, 1.0)
198  qw = random.gauss(0.0, 1.0)
199  q_len = math.sqrt( qx**2 + qy**2 + qz**2 + qw**2 )
200  if q_len > 0.001:
201  qx /= q_len
202  qy /= q_len
203  qz /= q_len
204  qw /= q_len
205  return PyKDL.Rotation.Quaternion(qx, qy, qz, qw)
206 
207 def testIk3(arm_name):
208  assert arm_name in ('right', 'left')
209 
210  m_pub = MarkerPublisher('velma_ik_geom')
211  js_pub = rospy.Publisher('/joint_states', JointState, queue_size=1000)
212  rospy.sleep(0.5)
213 
214  flips = []
215  for flip_shoulder in (True, False):
216  for flip_elbow in (True, False):
217  for flip_ee in (True, False):
218  flips.append( (flip_shoulder, flip_elbow, flip_ee) )
219  solv = KinematicsSolverVelma()
220 
221  torso_angle = 0.0
222 
223  if arm_name == 'right':
224  central_point = PyKDL.Vector( 0.7, -0.7, 1.4 )
225  else:
226  central_point = PyKDL.Vector( 0.7, 0.7, 1.4 )
227 
228  js_msg = JointState()
229  for i in range(7):
230  js_msg.name.append('{}_arm_{}_joint'.format(arm_name, i))
231  js_msg.position.append(0.0)
232 
233  js_msg.name.append('torso_0_joint')
234  js_msg.position.append(torso_angle)
235 
236  base_link_name = 'calib_{}_arm_base_link'.format(arm_name)
237  phase = 0.0
238  while not rospy.is_shutdown():
239  # Get random pose
240  T_B_A7d = PyKDL.Frame(randomOrientation(), central_point + PyKDL.Vector(random.uniform(-0.4, 0.4), random.uniform(-0.4, 0.4), random.uniform(-0.4, 0.4)))
241 
242  m_id = 0
243  m_id = m_pub.publishFrameMarker(T_B_A7d, m_id, scale=0.1,
244  frame='world', namespace='default')
245 
246  for flip_shoulder, flip_elbow, flip_ee in flips:
247  for elbow_circle_angle in np.linspace(-math.pi, math.pi, 20):
248  arm_q = solv.calculateIkArm(arm_name, T_B_A7d, torso_angle, elbow_circle_angle, flip_shoulder, flip_elbow, flip_ee)
249 
250  if not arm_q[0] is None:
251  js_msg.header.stamp = rospy.Time.now()
252  for i in range(7):
253  js_msg.position[i] = arm_q[i]
254  js_pub.publish(js_msg)
255  rospy.sleep(0.04)
256  if rospy.is_shutdown():
257  break
258  if rospy.is_shutdown():
259  break
260  rospy.sleep(0.04)
261 
262 def main():
263  rospy.init_node('test_velma_ik_geom', anonymous=False)
264 
265  # Requires:
266  # roslaunch velma_description upload_robot.launch
267  # rosrun robot_state_publisher robot_state_publisher
268 
269  v_solv = KinematicsSolverVelma()
270  printFrame( v_solv.getLeftArmBaseFk(0.0) )
271  printFrame( v_solv.getRightArmBaseFk(0.0) )
272  printFrame( v_solv.getLeftArmFk(0.0, [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) )
273  printFrame( v_solv.getRightArmFk(0.0, [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) )
274 
275  #testFK('right')
276  #return 0
277 
278  #T_A0_A7d = PyKDL.Frame(PyKDL.Rotation.Quaternion(0, 0.00304150858481, 0.0910915674525, 0.995837876145), PyKDL.Vector(0.10227842037159, 0.2623692295165, 0.30143578700507))
279  #testIk2( 'left', T_A0_A7d, 0.5 )
280  testIk3( 'left' )
281  return 0
282 
283 if __name__ == "__main__":
284  exit(main())
def testIk2(arm_name, T_A0_A7d, ampl)
This class is an interface to ROS markers publisher.
Kinematics solver (FK, IK) for WUT Velma robot.
Kinematics solver (FK, IK) for Kuka LWR 4+.