rviz_visualizer.py
Go to the documentation of this file.
1 from .. import pinocchio_pywrap as pin
2 from ..utils import npToTuple
3 
4 from . import BaseVisualizer
5 
6 import warnings
7 
8 try:
9  import hppfcl
10  WITH_HPP_FCL_BINDINGS = True
11 except ImportError:
12  WITH_HPP_FCL_BINDINGS = False
13 
14 def create_capsule_markers(marker_ref, oMg, d, l):
15  """ Make capsule using two sphere and one cylinder"""
16  from copy import deepcopy
17  from visualization_msgs.msg import Marker
18  from geometry_msgs.msg import Point
19  displacment = pin.SE3.Identity()
20 
21  displacment.translation[2] = l/2.
22  oMsphere_1 = oMg * displacment
23  displacment.translation[2] = -l/2.
24  oMsphere_2 = oMg * displacment
25 
26  marker_cylinder = marker_ref
27  marker_cylinder.type = Marker.CYLINDER
28  marker_cylinder.scale = Point(d,d,l)
29  marker_cylinder.pose = SE3ToROSPose(oMg)
30 
31  marker_sphere_1 = deepcopy(marker_ref)
32  marker_sphere_1.id += 10000 # How to ensure this id is not taken ?
33  marker_sphere_1.type = Marker.SPHERE
34  marker_sphere_1.scale = Point(d,d,d)
35  marker_sphere_1.pose = SE3ToROSPose(oMsphere_1)
36 
37  marker_sphere_2 = deepcopy(marker_ref)
38  marker_sphere_2.id += 20000 # How to ensure this id is not taken ?
39  marker_sphere_2.type = Marker.SPHERE
40  marker_sphere_2.scale = Point(d,d,d)
41  marker_sphere_2.pose = SE3ToROSPose(oMsphere_2)
42 
43  return [marker_cylinder, marker_sphere_1, marker_sphere_2]
44 
45 def SE3ToROSPose(oMg):
46  """Converts SE3 matrix to ROS geometry_msgs/Pose format"""
47  from geometry_msgs.msg import Pose, Point, Quaternion
48 
49  xyz_quat = pin.SE3ToXYZQUATtuple(oMg)
50  return Pose(position=Point(*xyz_quat[:3]), orientation=Quaternion(*xyz_quat[3:]))
51 
52 class RVizVisualizer(BaseVisualizer):
53  """A Pinocchio display using RViz"""
54  class Viewer:
55  app = None
56  viz = None
57  viz_manager = None
58 
59  def initViewer(self, viewer=None, windowName="python-pinocchio", loadModel=False, initRosNode=True):
60  """Init RVizViewer by starting a ros node (or not) and creating an RViz window."""
61  from rospy import init_node, WARN
62  from rosgraph import is_master_online
63  from rviz import bindings as rviz
64  from python_qt_binding.QtWidgets import QApplication
65 
66  if not is_master_online(): # Checks the master uri
67  # ROS Master is offline
68  warnings.warn("Error while importing the viz client.\n"
69  "Check whether ROS master (roscore) is properly started",
70  category=UserWarning, stacklevel=2)
71  return None
72 
73  if initRosNode:
74  init_node('pinocchio_viewer', anonymous=True, log_level=WARN)
75 
76  if viewer == None:
78  self.viewer.app = QApplication([])
79  self.viewer.viz= rviz.VisualizationFrame()
80  self.viewer.viz.setSplashPath( "" )
81  self.viewer.viz.initialize()
82  self.viewer.viz.setWindowTitle(windowName+"[*]")
83  self.viewer.viz_manager = self.viewer.viz.getManager()
84  self.viewer.viz.show()
85  else:
86  self.viewer = viewer
87 
88  if loadModel:
89  self.loadViewerModel()
90 
91  return self.viewer
92 
93  def loadViewerModel(self, rootNodeName="pinocchio"):
94  """Create the displays in RViz and create publishers for the MarkerArray"""
95  from rospy import Publisher
96  from visualization_msgs.msg import MarkerArray
97 
98  # Visuals
99  self.visuals_publisher = Publisher(rootNodeName+ "_visuals", MarkerArray, queue_size=1, latch=True)
100  self.visual_Display = self.viewer.viz_manager.createDisplay("rviz/MarkerArray", rootNodeName + "_visuals", True)
101  self.visual_Display.subProp("Marker Topic").setValue(rootNodeName + "_visuals")
102  self.visual_ids = []
103 
104  # Collisions
105  self.collisions_publisher = Publisher(rootNodeName + "_collisions", MarkerArray, queue_size=1, latch=True)
106  self.collision_Display = self.viewer.viz_manager.createDisplay("rviz/MarkerArray", rootNodeName + "_collisions", True)
107  self.collision_Display.subProp("Marker Topic").setValue(rootNodeName + "_collisions")
108  self.collision_ids = []
109 
110  # Group
111  root_group = self.viewer.viz_manager.getRootDisplayGroup()
112  self.group_Display = self.viewer.viz_manager.createDisplay("rviz/Group", rootNodeName, True)
113  self.group_Display.addChild(root_group.takeChild(self.visual_Display)) # Remove display from root group and add it to robot group
114  self.group_Display.addChild(root_group.takeChild(self.collision_Display)) # Remove display from root group and add it to robot group
115 
116  self.seq = 0
117  self.display()
118 
119  def clean(self):
120  """Delete all the objects from the whole scene """
121  if hasattr(self, 'collisions_publisher'):
122  self._clean(self.collisions_publisher)
123  self.collision_ids = []
124 
125  if hasattr(self, 'visuals_publisher'):
126  self._clean(self.visuals_publisher)
127  self.visual_ids = []
128 
129  def display(self, q = None):
130  """Display the robot at configuration q in the viz by placing all the bodies."""
131  # Update the robot kinematics and geometry.
132  if q is not None:
133  pin.forwardKinematics(self.model,self.data,q)
134 
135  if self.collision_model is not None and hasattr(self, 'collisions_publisher'):
136  pin.updateGeometryPlacements(self.model, self.data, self.collision_model, self.collision_data)
137  self.collision_ids = self._plot(self.collisions_publisher, self.collision_model, self.collision_data, self.collision_ids)
138 
139  if self.visual_model is not None and hasattr(self, 'visuals_publisher'):
140  pin.updateGeometryPlacements(self.model, self.data, self.visual_model, self.visual_data)
141  self.visual_ids = self._plot(self.visuals_publisher, self.visual_model, self.visual_data, self.visual_ids)
142 
143  def _plot(self, publisher, model, data, previous_ids=()):
144  """Create markers for each object of the model and publish it as MarkerArray (also delete unused previously created markers)"""
145  from rospy import get_rostime
146  from std_msgs.msg import Header, ColorRGBA
147  from geometry_msgs.msg import Point
148  from visualization_msgs.msg import MarkerArray, Marker
149 
150  self.seq +=1
151  header = Header(frame_id='map', seq=self.seq, stamp=get_rostime()) # Common header for every marker
152 
153  marker_array = MarkerArray()
154  for obj in model.geometryObjects:
155  obj_id = model.getGeometryId(obj.name)
156 
157  # Prepare marker
158  marker = Marker()
159  marker.id = obj_id
160  marker.header = header
161  marker.action = Marker.ADD # same as Marker.MODIFY
162  marker.pose = SE3ToROSPose(data.oMg[obj_id])
163  marker.color = ColorRGBA(*obj.meshColor)
164 
165  if obj.meshTexturePath != "":
166  warnings.warn("Textures are not supported in RVizVisualizer (for " + obj.name + ")", category=UserWarning, stacklevel=2)
167 
168  # Create geometry
169  geom = obj.geometry
170  if WITH_HPP_FCL_BINDINGS and isinstance(geom, hppfcl.ShapeBase):
171  # append a primitive geometry
172  if isinstance(geom, hppfcl.Cylinder):
173  d, l = 2*geom.radius, 2*geom.halfLength
174  marker.type = Marker.CYLINDER
175  marker.scale = Point(d,d,l)
176  marker_array.markers.append(marker)
177  elif isinstance(geom, hppfcl.Box):
178  size = npToTuple(2.*geom.halfSide)
179  marker.type = Marker.CUBE
180  marker.scale = Point(*size)
181  marker_array.markers.append(marker)
182  elif isinstance(geom, hppfcl.Sphere):
183  d = 2*geom.radius
184  marker.type = Marker.SPHERE
185  marker.scale = Point(d, d, d)
186  marker_array.markers.append(marker)
187  elif isinstance(geom, hppfcl.Capsule):
188  d, l = 2*geom.radius, 2 * geom.halfLength
189  marker_array.markers.extend(create_capsule_markers(marker, data.oMg[obj_id], d, l))
190  else:
191  msg = "Unsupported geometry type for %s (%s)" % (obj.name, type(geom))
192  warnings.warn(msg, category=UserWarning, stacklevel=2)
193  continue
194  else:
195  # append a mesh
196  marker.type = Marker.MESH_RESOURCE # Custom mesh
197  marker.scale = Point(*npToTuple(obj.meshScale))
198  marker.mesh_resource = 'file://' + obj.meshPath
199  marker_array.markers.append(marker)
200 
201  # Remove unused markers
202  new_ids = [marker.id for marker in marker_array.markers]
203  for old_id in previous_ids:
204  if not old_id in new_ids:
205  marker_remove = Marker()
206  marker_remove.header = header
207  marker_remove.id = old_id
208  marker_remove.action = Marker.DELETE
209  marker_array.markers.append(marker_remove)
210 
211  # Publish markers
212  publisher.publish(marker_array)
213 
214  # Return list of markers id
215  return new_ids
216 
217  def _clean(self, publisher):
218  """Delete all the markers from a topic (use one marker with action DELETEALL)"""
219  from rospy import get_rostime
220  from std_msgs.msg import Header
221  from visualization_msgs.msg import MarkerArray, Marker
222 
223  # Increment seq number
224  self.seq +=1
225 
226  # Prepare a clean_all marker
227  marker = Marker()
228  marker.header = Header(frame_id='map', seq=self.seq, stamp=get_rostime())
229  marker.action = Marker.DELETEALL
230 
231  # Add the marker to a MarkerArray
232  marker_array = MarkerArray(markers = [marker])
233 
234  # Publish marker
235  publisher.publish(marker_array)
236 
237  def displayCollisions(self,visibility):
238  """Set whether to display collision objects or not"""
239  self.collision_Display.setEnabled(visibility)
240 
241  def displayVisuals(self,visibility):
242  """Set whether to display visual objects or not"""
243  self.visual_Display.setEnabled(visibility)
244 
245  def sleep(self, dt):
246  from python_qt_binding.QtTest import QTest
247  QTest.qWait(1e3*dt)
248 
249 
250 __all__ = ['RVizVisualizer']
def loadViewerModel(self, rootNodeName="pinocchio")
def create_capsule_markers(marker_ref, oMg, d, l)
def _plot(self, publisher, model, data, previous_ids=())
def initViewer(self, viewer=None, windowName="python-pinocchio", loadModel=False, initRosNode=True)


pinocchio
Author(s):
autogenerated on Fri Jun 23 2023 02:38:32