WUT Velma robot API
marker_publisher.py
Go to the documentation of this file.
1 
4 
5 # Copyright (c) 2015, Robot Control and Pattern Recognition Group,
6 # Institute of Control and Computation Engineering
7 # Warsaw University of Technology
8 #
9 # All rights reserved.
10 #
11 # Redistribution and use in source and binary forms, with or without
12 # modification, are permitted provided that the following conditions are met:
13 # * Redistributions of source code must retain the above copyright
14 # notice, this list of conditions and the following disclaimer.
15 # * Redistributions in binary form must reproduce the above copyright
16 # notice, this list of conditions and the following disclaimer in the
17 # documentation and/or other materials provided with the distribution.
18 # * Neither the name of the Warsaw University of Technology nor the
19 # names of its contributors may be used to endorse or promote products
20 # derived from this software without specific prior written permission.
21 #
22 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 # DISCLAIMED. IN NO EVENT SHALL <COPYright HOLDER> BE LIABLE FOR ANY
26 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #
33 # Author: Dawid Seredynski
34 #
35 
36 import rospy
37 
38 from std_msgs.msg import ColorRGBA
39 #from sensor_msgs.msg import *
40 from geometry_msgs.msg import Vector3, Pose, Point, Quaternion
41 from visualization_msgs.msg import Marker, MarkerArray
42 
43 import PyKDL
44 import copy
45 
47  """!
48  This class is an interface to ROS markers publisher.
49  """
50  def __init__(self, namespace):
51  self._pub_marker = rospy.Publisher(namespace, MarkerArray, queue_size=1000)
52  self.__pending_markers = []
53 
54  def publishAll(self):
55  m = MarkerArray()
56  m.markers = self.__pending_markers
57  self._pub_marker.publish(m)
58  self.__pending_markers = []
59 
61  return len(self.__pending_markers)
62 
63  def publishTextMarker(self, text, i, r=1, g=0, b=0, a=1, namespace='default', frame_id='torso_base', T=None, height=0.1):
64  m = MarkerArray()
65  marker = Marker()
66  marker.header.frame_id = frame_id
67  marker.header.stamp = rospy.Time.now()
68  marker.ns = namespace
69  marker.id = i
70  marker.type = Marker.TEXT_VIEW_FACING
71  marker.text = text
72  marker.action = Marker.ADD
73  if T != None:
74  point = T.p
75  q = T.M.GetQuaternion()
76  marker.pose = Pose( Point(point.x(),point.y(),point.z()), Quaternion(q[0],q[1],q[2],q[3]) )
77  #else:
78  # marker.pose = Pose( Point(pt.x(),pt.y(),pt.z()), Quaternion(0,0,0,1) )
79  marker.scale.z = height
80  marker.color = ColorRGBA(r,g,b,a)
81  m.markers.append(marker)
82  self._pub_marker.publish(m)
83  return i+1
84 
85  def publishSinglePointMarker(self, pt, i, r=1, g=0, b=0, a=1, namespace='default',
86  frame_id='torso_base', m_type=Marker.CUBE, scale=Vector3(0.005, 0.005, 0.005), T=None):
87  m_id = self.addSinglePointMarker(pt, i, r=r, g=g, b=b, a=a, namespace=namespace,
88  frame_id=frame_id, m_type=m_type, scale=scale, T=T)
89  self.publishAll()
90  return m_id
91 
92  @staticmethod
93  def createSinglePointMarker(pt, i, r=1, g=0, b=0, a=1, namespace='default', frame_id='torso_base', m_type=Marker.CUBE, scale=Vector3(0.005, 0.005, 0.005), T=None):
94  marker = Marker()
95  marker.header.frame_id = frame_id
96  marker.header.stamp = rospy.Time.now()
97  marker.ns = namespace
98  marker.id = i
99  marker.type = m_type
100  marker.action = Marker.ADD
101  if T != None:
102  point = T*pt
103  q = T.M.GetQuaternion()
104  marker.pose = Pose( Point(point.x(),point.y(),point.z()), Quaternion(q[0],q[1],q[2],q[3]) )
105  else:
106  marker.pose = Pose( Point(pt.x(),pt.y(),pt.z()), Quaternion(0,0,0,1) )
107  marker.scale = scale
108  marker.color = ColorRGBA(r,g,b,a)
109  return marker
110 
111  def addSinglePointMarker(self, pt, i, r=1, g=0, b=0, a=1, namespace='default', frame_id='torso_base', m_type=Marker.CUBE, scale=Vector3(0.005, 0.005, 0.005), T=None):
112  # marker = Marker()
113  # marker.header.frame_id = frame_id
114  # marker.header.stamp = rospy.Time.now()
115  # marker.ns = namespace
116  # marker.id = i
117  # marker.type = m_type
118  # marker.action = Marker.ADD
119  # if T != None:
120  # point = T*pt
121  # q = T.M.GetQuaternion()
122  # marker.pose = Pose( Point(point.x(),point.y(),point.z()), Quaternion(q[0],q[1],q[2],q[3]) )
123  # else:
124  # marker.pose = Pose( Point(pt.x(),pt.y(),pt.z()), Quaternion(0,0,0,1) )
125  # marker.scale = scale
126  # marker.color = ColorRGBA(r,g,b,a)
127  self.__pending_markers.append(
128  MarkerPublisher.createSinglePointMarker(
129  pt, i, r, g, b, a, namespace, frame_id, m_type, scale, T) )
130  return i+1
131 
132  def eraseMarkers(self, idx_from, idx_to, frame_id='torso_base', namespace='default'):
133  m = MarkerArray()
134  for idx in range(idx_from, idx_to):
135  marker = Marker()
136  marker.header.frame_id = frame_id
137  marker.header.stamp = rospy.Time.now()
138  marker.ns = namespace
139  marker.id = idx
140  marker.action = Marker.DELETE
141  m.markers.append(marker)
142  if len(m.markers) > 0:
143  self._pub_marker.publish(m)
144 
145 # the old implementation is very slow:
146 # def publishMultiPointsMarker(self, pt, base_id, r=1, g=0, b=0, namespace='default', frame_id='torso_base', m_type=Marker.CUBE, scale=Vector3(0.002, 0.002, 0.002), T=None):
147 # m = MarkerArray()
148 # ret_id = copy.copy(base_id)
149 # for i in range(0, len(pt)):
150 # marker = Marker()
151 # marker.header.frame_id = frame_id
152 # marker.header.stamp = rospy.Time.now()
153 # marker.ns = namespace
154 # marker.id = ret_id
155 # ret_id += 1
156 # marker.type = m_type
157 # marker.action = Marker.ADD
158 # if T != None:
159 # point = T*pt[i]
160 # marker.pose = Pose( Point(point.x(),point.y(),point.z()), Quaternion(0,0,0,1) )
161 # else:
162 # marker.pose = Pose( Point(pt[i].x(),pt[i].y(),pt[i].z()), Quaternion(0,0,0,1) )
163 # marker.scale = scale
164 # marker.color = ColorRGBA(r,g,b,0.5)
165 # m.markers.append(marker)
166 # self._pub_marker.publish(m)
167 # return ret_id
168 
169  def publishLineStripMarker(self, pt, base_id, r=1, g=0, b=0, a=1, namespace='default', frame_id='torso_base', width=0.01, T=None):
170  m = MarkerArray()
171  ret_id = copy.copy(base_id)
172 
173  marker = Marker()
174  marker.header.frame_id = frame_id
175  marker.header.stamp = rospy.Time.now()
176  marker.ns = namespace
177  marker.id = ret_id
178  ret_id += 1
179  marker.type = Marker.LINE_STRIP
180  marker.action = Marker.ADD
181  if T != None:
182  qx, qy, qz, qw = T.M.GetQuaternion()
183  marker.pose = Pose( Point(T.p.x(),T.p.y(),T.p.z()), Quaternion(qx,qy,qz,qw) )
184  marker.scale.x = width
185  marker.color = ColorRGBA(r,g,b,a)
186 
187  for p in pt:
188  marker.points.append( Point(p.x(), p.y(), p.z()) )
189 
190  m.markers.append(marker)
191  self._pub_marker.publish(m)
192  return ret_id
193 
194  def publishLineListMarker(self, pt, base_id, r=1, g=0, b=0, a=1, namespace='default', frame_id='torso_base', width=0.01, T=None):
195  m = MarkerArray()
196  ret_id = copy.copy(base_id)
197 
198  marker = Marker()
199  marker.header.frame_id = frame_id
200  marker.header.stamp = rospy.Time.now()
201  marker.ns = namespace
202  marker.id = ret_id
203  ret_id += 1
204  marker.type = Marker.LINE_LIST
205  marker.action = Marker.ADD
206  if T != None:
207  qx, qy, qz, qw = T.M.GetQuaternion()
208  marker.pose = Pose( Point(T.p.x(),T.p.y(),T.p.z()), Quaternion(qx,qy,qz,qw) )
209  marker.scale.x = width
210  marker.color = ColorRGBA(r,g,b,a)
211 
212  for p in pt:
213  marker.points.append( Point(p.x(), p.y(), p.z()) )
214 
215  m.markers.append(marker)
216  self._pub_marker.publish(m)
217  return ret_id
218 
219  def publishMultiPointsMarker(self, pt, base_id, r=1, g=0, b=0, a=1, namespace='default', frame_id='torso_base', m_type=Marker.CUBE, scale=Vector3(0.002, 0.002, 0.002), T=None):
220  m = MarkerArray()
221  ret_id = copy.copy(base_id)
222 
223  marker = Marker()
224  marker.header.frame_id = frame_id
225  marker.header.stamp = rospy.Time.now()
226  marker.ns = namespace
227  marker.id = ret_id
228  ret_id += 1
229  if m_type == Marker.CUBE:
230  marker.type = Marker.CUBE_LIST
231  elif m_type == Marker.SPHERE:
232  marker.type = Marker.SPHERE_LIST
233  marker.action = Marker.ADD
234  if T is None:
235  marker.pose = Pose( Point(0, 0, 0), Quaternion(0, 0, 0, 1) )
236  else:
237  qx, qy, qz, qw = T.M.GetQuaternion()
238  marker.pose = Pose( Point(T.p.x(),T.p.y(),T.p.z()), Quaternion(qx,qy,qz,qw) )
239  marker.scale = scale
240  marker.color = ColorRGBA(r,g,b,a)
241 
242  for p in pt:
243  marker.points.append( Point(p.x(), p.y(), p.z()) )
244 
245  m.markers.append(marker)
246  self._pub_marker.publish(m)
247  return ret_id
248 
249  def publishMultiPointsMarkerWithSize(self, pt, base_id, r=1, g=0, b=0, namespace='default', frame_id='torso_base', m_type=Marker.SPHERE, T=None):
250  m = MarkerArray()
251  ret_id = copy.copy(base_id)
252  if T == None:
253  T = PyKDL.Frame()
254  for i in range(0, len(pt)):
255  marker = Marker()
256  marker.header.frame_id = frame_id
257  marker.header.stamp = rospy.Time.now()
258  marker.ns = namespace
259  marker.id = ret_id
260  ret_id += 1
261  marker.type = m_type
262  marker.action = Marker.ADD
263  point = T*pt[i][0]
264  marker.pose = Pose( Point(point.x(),point.y(),point.z()), Quaternion(0,0,0,1) )
265  marker.scale = Vector3(pt[i][1], pt[i][1], pt[i][1])
266  marker.color = ColorRGBA(r,g,b,0.5)
267  m.markers.append(marker)
268  self._pub_marker.publish(m)
269  return ret_id
270 
271  def publishTriangleListMarker(self, points_list, base_id, r=1, g=0, b=0, a=1.0, namespace='default', frame_id='torso_base', T=None):
272  m = MarkerArray()
273  marker = Marker()
274  marker.header.frame_id = frame_id
275  marker.header.stamp = rospy.Time.now()
276  marker.ns = namespace
277  marker.id = base_id
278  marker.type = Marker.TRIANGLE_LIST
279  marker.action = Marker.ADD
280  marker.scale = Vector3(1,1,1)
281  marker.color = ColorRGBA(r,g,b,a)
282  if T == None:
283  T = PyKDL.Frame()
284  q = T.M.GetQuaternion()
285  marker.pose = Pose( Point(T.p.x(),T.p.y(),T.p.z()), Quaternion(q[0],q[1],q[2],q[3]) )
286  for pt in points_list:
287  marker.points.append(Point(pt.x(), pt.y(), pt.z()))
288  m.markers.append(marker)
289  self._pub_marker.publish(m)
290  return base_id + 1
291 
292  def publishVectorMarker(self, v1, v2, i, r, g, b, a=0.5, frame='torso_base', namespace='default', scale=0.001):
293  m_id = self.addVectorMarker(v1, v2, i, r=r, g=g, b=b, a=a, frame=frame, namespace=namespace, scale=scale)
294  self.publishAll()
295  return m_id
296 
297  def addVectorMarker(self, v1, v2, i, r, g, b, a=0.5, frame='torso_base', namespace='default', scale=0.001):
298  # marker = Marker()
299  # marker.header.frame_id = frame
300  # marker.header.stamp = rospy.Time.now()
301  # marker.ns = namespace
302  # marker.id = i
303  # marker.type = Marker.ARROW
304  # marker.action = Marker.ADD
305  # marker.points.append(Point(v1.x(), v1.y(), v1.z()))
306  # marker.points.append(Point(v2.x(), v2.y(), v2.z()))
307  # marker.pose = Pose( Point(0,0,0), Quaternion(0,0,0,1) )
308  # marker.scale = Vector3(scale, 2.0*scale, 0)
309  # marker.color = ColorRGBA(r,g,b,a)
310  self.__pending_markers.append( MarkerPublisher.createVectorMarker(v1, v2, i, r, g, b, a, frame, namespace, scale) )
311  return i+1
312 
313  @staticmethod
314  def createVectorMarker(v1, v2, i, r, g, b, a=0.5, frame='torso_base', namespace='default', scale=0.001):
315  marker = Marker()
316  marker.header.frame_id = frame
317  marker.header.stamp = rospy.Time.now()
318  marker.ns = namespace
319  marker.id = i
320  marker.type = Marker.ARROW
321  marker.action = Marker.ADD
322  marker.points.append(Point(v1.x(), v1.y(), v1.z()))
323  marker.points.append(Point(v2.x(), v2.y(), v2.z()))
324  marker.pose = Pose( Point(0,0,0), Quaternion(0,0,0,1) )
325  marker.scale = Vector3(scale, 2.0*scale, 0)
326  marker.color = ColorRGBA(r,g,b,a)
327  return marker
328 
329  def publishFrameMarker(self, T, base_id, scale=0.1, frame='torso_base', namespace='default'):
330  m_id = self.addFrameMarker(T, base_id, scale=scale, frame=frame, namespace=namespace)
331  self.publishAll()
332  return m_id
333 
334  def addFrameMarker(self, T, base_id, scale=0.1, frame='torso_base', namespace='default'):
335  self.addVectorMarker(T*PyKDL.Vector(), T*PyKDL.Vector(scale,0,0), base_id, 1, 0, 0, 1, frame, namespace, scale*0.1)
336  self.addVectorMarker(T*PyKDL.Vector(), T*PyKDL.Vector(0,scale,0), base_id+1, 0, 1, 0, 1, frame, namespace, scale*0.1)
337  self.addVectorMarker(T*PyKDL.Vector(), T*PyKDL.Vector(0,0,scale), base_id+2, 0, 0, 1, 1, frame, namespace, scale*0.1)
338  return base_id+3
339 
340  @staticmethod
341  def createFrameMarker(T, base_id, scale=0.1, frame='torso_base', namespace='default'):
342  m1 = MarkerPublisher.createVectorMarker(T*PyKDL.Vector(), T*PyKDL.Vector(scale,0,0), base_id, 1, 0, 0, 1, frame, namespace, scale*0.1)
343  m2 = MarkerPublisher.createVectorMarker(T*PyKDL.Vector(), T*PyKDL.Vector(0,scale,0), base_id+1, 0, 1, 0, 1, frame, namespace, scale*0.1)
344  m3 = MarkerPublisher.createVectorMarker(T*PyKDL.Vector(), T*PyKDL.Vector(0,0,scale), base_id+2, 0, 0, 1, 1, frame, namespace, scale*0.1)
345  return [m1, m2, m3]
346 
347  def publishConstantMeshMarker(self, uri, base_id, r=1, g=0, b=0, scale=0.1, frame_id='torso_base', namespace='default', T=None):
348  if T == None:
349  T = PyKDL.Frame()
350  m = MarkerArray()
351  marker = Marker()
352  marker.header.frame_id = frame_id
353  marker.header.stamp = rospy.Time.now()
354  marker.ns = namespace
355  marker.id = base_id
356  marker.type = Marker.MESH_RESOURCE
357  marker.mesh_resource = uri # e.g. "package://pr2_description/meshes/base_v0/base.dae"
358  marker.action = Marker.ADD
359  point = T.p
360  q = T.M.GetQuaternion()
361  marker.pose = Pose( Point(point.x(),point.y(),point.z()), Quaternion(q[0],q[1],q[2],q[3]) )
362  marker.scale = Vector3(scale, scale, scale)
363  marker.color = ColorRGBA(r,g,b,0.5)
364  m.markers.append(marker)
365  self._pub_marker.publish(m)
366  return base_id+1
367 
368  def publishMeshMarker(self, mesh, base_id, r=1, g=0, b=0, scale=0.1, frame_id='torso_base', namespace='default', T=None):
369  m = MarkerArray()
370  marker = Marker()
371  marker.header.frame_id = frame_id
372  marker.header.stamp = rospy.Time.now()
373  marker.ns = namespace
374  marker.id = base_id
375  marker.type = Marker.TRIANGLE_LIST
376  marker.action = Marker.ADD
377  for f in mesh[1]:
378  marker.points.append(Point(mesh[0][f[0]][0], mesh[0][f[0]][1], mesh[0][f[0]][2]))
379  marker.points.append(Point(mesh[0][f[1]][0], mesh[0][f[1]][1], mesh[0][f[1]][2]))
380  marker.points.append(Point(mesh[0][f[2]][0], mesh[0][f[2]][1], mesh[0][f[2]][2]))
381  if T != None:
382  point = T.p
383  q = T.M.GetQuaternion()
384  marker.pose = Pose( Point(point.x(),point.y(),point.z()), Quaternion(q[0],q[1],q[2],q[3]) )
385  else:
386  marker.pose = Pose( Point(0,0,0), Quaternion(0,0,0,1) )
387  marker.scale = Vector3(1.0, 1.0, 1.0)
388  marker.color = ColorRGBA(r,g,b,0.5)
389  m.markers.append(marker)
390  self._pub_marker.publish(m)
391  return base_id+1
392 
def eraseMarkers(self, idx_from, idx_to, frame_id='torso_base', namespace='default')
def publishLineListMarker(self, pt, base_id, r=1, g=0, b=0, a=1, namespace='default', frame_id='torso_base', width=0.01, T=None)
def createSinglePointMarker(pt, i, r=1, g=0, b=0, a=1, namespace='default', frame_id='torso_base', m_type=Marker.CUBE, scale=Vector3(0.005, 0.005, 0.005), T=None)
def publishLineStripMarker(self, pt, base_id, r=1, g=0, b=0, a=1, namespace='default', frame_id='torso_base', width=0.01, T=None)
def publishTriangleListMarker(self, points_list, base_id, r=1, g=0, b=0, a=1.0, namespace='default', frame_id='torso_base', T=None)
def createVectorMarker(v1, v2, i, r, g, b, a=0.5, frame='torso_base', namespace='default', scale=0.001)
def addSinglePointMarker(self, pt, i, r=1, g=0, b=0, a=1, namespace='default', frame_id='torso_base', m_type=Marker.CUBE, scale=Vector3(0.005, 0.005, 0.005), T=None)
This class is an interface to ROS markers publisher.
def publishMeshMarker(self, mesh, base_id, r=1, g=0, b=0, scale=0.1, frame_id='torso_base', namespace='default', T=None)
def addVectorMarker(self, v1, v2, i, r, g, b, a=0.5, frame='torso_base', namespace='default', scale=0.001)
def publishSinglePointMarker(self, pt, i, r=1, g=0, b=0, a=1, namespace='default', frame_id='torso_base', m_type=Marker.CUBE, scale=Vector3(0.005, 0.005, 0.005), T=None)
def createFrameMarker(T, base_id, scale=0.1, frame='torso_base', namespace='default')
def addFrameMarker(self, T, base_id, scale=0.1, frame='torso_base', namespace='default')
def publishFrameMarker(self, T, base_id, scale=0.1, frame='torso_base', namespace='default')
def publishMultiPointsMarkerWithSize(self, pt, base_id, r=1, g=0, b=0, namespace='default', frame_id='torso_base', m_type=Marker.SPHERE, T=None)
def publishVectorMarker(self, v1, v2, i, r, g, b, a=0.5, frame='torso_base', namespace='default', scale=0.001)
def publishMultiPointsMarker(self, pt, base_id, r=1, g=0, b=0, a=1, namespace='default', frame_id='torso_base', m_type=Marker.CUBE, scale=Vector3(0.002, 0.002, 0.002), T=None)
def publishTextMarker(self, text, i, r=1, g=0, b=0, a=1, namespace='default', frame_id='torso_base', T=None, height=0.1)
def publishConstantMeshMarker(self, uri, base_id, r=1, g=0, b=0, scale=0.1, frame_id='torso_base', namespace='default', T=None)