WUT Velma robot API
publish_joints_visualization.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 
6 
7 # Copyright (c) 2017, Robot Control and Pattern Recognition Group,
8 # Institute of Control and Computation Engineering
9 # Warsaw University of Technology
10 #
11 # All rights reserved.
12 #
13 # Redistribution and use in source and binary forms, with or without
14 # modification, are permitted provided that the following conditions are met:
15 # * Redistributions of source code must retain the above copyright
16 # notice, this list of conditions and the following disclaimer.
17 # * Redistributions in binary form must reproduce the above copyright
18 # notice, this list of conditions and the following disclaimer in the
19 # documentation and/or other materials provided with the distribution.
20 # * Neither the name of the Warsaw University of Technology nor the
21 # names of its contributors may be used to endorse or promote products
22 # derived from this software without specific prior written permission.
23 #
24 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 # DISCLAIMED. IN NO EVENT SHALL <COPYright HOLDER> BE LIABLE FOR ANY
28 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #
35 # Author: Dawid Seredynski
36 #
37 
38 import roslib; roslib.load_manifest('rcprg_ros_utils')
39 
40 import rospy
41 import threading
42 import math
43 import PyKDL
44 from sensor_msgs.msg import JointState
45 
46 import xml.dom.minidom as minidom
47 from rcprg_ros_utils import marker_publisher
48 
49 joint_states_lock = threading.Lock()
50 joint_state = None
51 
53  global joint_state
54  with joint_states_lock:
55  joint_state = data
56 
57 if __name__ == "__main__":
58  rospy.init_node('publish_joints_visualization', anonymous=False)
59 
60  rospy.sleep(0.5)
61 
62  try:
63  robot_description = rospy.get_param("/robot_description")
64  except KeyError as e:
65  print "Some ROS parameters are not provided:"
66  print e
67  exit(1)
68 
69  shown_joints = None
70  try:
71  shown_joints = rospy.get_param("~shown_joints")
72  except KeyError as e:
73  print "ROS param 'shown_joints' is not set. All joints are visualized."
74 
75  dom = minidom.parseString(robot_description)
76  robot = dom.getElementsByTagName("robot")
77  if len(robot) != 1:
78  print "robot_description does not contain 'robot' node"
79  exit(1)
80 
81  joints = []
82 
83  for j in robot[0].childNodes:
84  if j.localName != "joint":
85  continue
86  name = j.getAttribute("name")
87  joint_type = j.getAttribute("type")
88  if joint_type == "fixed":
89  continue
90  origin = j.getElementsByTagName("origin")
91  if len(origin) != 1:
92  print "joint '" + name + "' does contain wrong number of 'origin' nodes: " + str(len(origin))
93  exit(1)
94  axis = j.getElementsByTagName("axis")
95  if len(axis) != 1:
96  print "joint '" + name + "' contain wrong number of 'axis' nodes: " + str(len(axis))
97  exit(1)
98  limit = j.getElementsByTagName("limit")
99  if len(limit) != 1:
100  print "joint '" + name + "' contain wrong number of 'limit' nodes: " + str(len(limit))
101  exit(1)
102  parent = j.getElementsByTagName("parent")
103  if len(parent) != 1:
104  print "joint '" + name + "' contain wrong number of 'parent' nodes: " + str(len(parent))
105  exit(1)
106 
107  xyz = origin[0].getAttribute("xyz")
108  rpy = origin[0].getAttribute("rpy")
109  xyz = xyz.split()
110  rpy = rpy.split()
111  orig = PyKDL.Frame(PyKDL.Rotation.RPY(float(rpy[0]), float(rpy[1]), float(rpy[2])), PyKDL.Vector(float(xyz[0]), float(xyz[1]), float(xyz[2])))
112 
113  axis_xyz = axis[0].getAttribute("xyz")
114  axis_xyz = axis_xyz.split()
115  ax = PyKDL.Vector(float(axis_xyz[0]), float(axis_xyz[1]), float(axis_xyz[2]))
116 
117  limit_lo = float(limit[0].getAttribute("lower"))
118  limit_up = float(limit[0].getAttribute("upper"))
119  print name + ": " + str(limit_lo) + " " + str(limit_up) + " axis: " + str(ax.x()) + " " + str(ax.y()) + " " + str(ax.z()) + " "
120 
121  parent_link = parent[0].getAttribute("link")
122 
123  axis_z = ax
124  if abs(axis_z.z()) > 0.7:
125  axis_x = PyKDL.Vector(1,0,0)
126  else:
127  axis_x = PyKDL.Vector(0,0,1)
128  axis_y = axis_z * axis_x
129  axis_x = axis_y * axis_z
130  axis_x.Normalize()
131  axis_y.Normalize()
132  axis_z.Normalize()
133  rot = PyKDL.Frame(PyKDL.Rotation(axis_x,axis_y,axis_z))
134 
135  joints.append( (name, parent_link, orig, ax, limit_lo, limit_up, rot) )
136 
137  listener_joint_states = rospy.Subscriber('/joint_states', JointState, jointStatesCallback)
138 
139  limit_scale = 0.1
140 
141  pub = marker_publisher.MarkerPublisher('/joints_vis')
142  points_list = {}
143  for j in joints:
144  pl = []
145  rot = j[6]
146  angle = j[4]
147  while angle < j[5]-0.15:
148  angle_prev = angle
149  angle += 0.1
150  pl.append(PyKDL.Vector())
151  pl.append(rot*PyKDL.Vector(math.cos(angle_prev), math.sin(angle_prev),0)*limit_scale)
152  pl.append(rot*PyKDL.Vector(math.cos(angle), math.sin(angle),0)*limit_scale)
153  pl.append(PyKDL.Vector())
154  pl.append(rot*PyKDL.Vector(math.cos(angle), math.sin(angle),0)*limit_scale)
155  pl.append(rot*PyKDL.Vector(math.cos(j[5]), math.sin(j[5]),0)*limit_scale)
156  points_list[j[0]] = pl
157 
158  while not rospy.is_shutdown():
159  js = {}
160  with joint_states_lock:
161  if joint_state != None:
162  joint_idx = 0
163  for joint_name in joint_state.name:
164  js[joint_name] = joint_state.position[joint_idx]
165  joint_idx += 1
166  m_id = 0
167  for j in joints:
168  if shown_joints != None and not j[0] in shown_joints:
169  continue
170  # show axis
171  m_id = pub.publishVectorMarker(j[2]*PyKDL.Vector(), j[2]*(j[3]*0.2), m_id, 1, 0, 0, a=1.0, namespace="axes", frame=j[1], scale=0.01)
172  m_id = pub.publishTriangleListMarker(points_list[j[0]], m_id, r=0, g=1, b=0, a=1.0, namespace="limits", frame_id=j[1], T=j[2])
173  if j[0] in js:
174  rot = j[6]
175  vec = rot*PyKDL.Vector(math.cos(js[j[0]]), math.sin(js[j[0]]),0)
176  m_id = pub.publishVectorMarker(j[2]*PyKDL.Vector(), j[2]*(vec*0.15), m_id, 0, 0, 1, a=1.0, namespace="limits", frame=j[1], scale=0.01)
177  m_id = pub.publishTextMarker(j[0], m_id, 0,0,1,1, namespace='names', frame_id=j[1], T=j[2], height=0.05)
178  try:
179  rospy.sleep(0.1)
180  except:
181  break
182 
183