Skip to content

Commit

Permalink
Add the possibility to draw 3d arrows
Browse files Browse the repository at this point in the history
  • Loading branch information
GiulioRomualdi committed Sep 26, 2024
1 parent 5d3df3d commit 5ad8e4e
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 2 deletions.
30 changes: 30 additions & 0 deletions robot_log_visualizer/file_reader/signal_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ def __init__(self, period: float):
self._3d_trajectories_path = {}
self._3d_trajectories_path_lock = QMutex()

self._3d_arrows = {}
self._3d_arrows_path_lock = QMutex()
self.max_arrow = 0

self.period = period

self.data = {}
Expand Down Expand Up @@ -319,6 +323,18 @@ def get_3d_point_at_index(self, index):

return points

def get_3d_arrow_at_index(self, index):
arrows = {}

self._3d_arrows_path_lock.lock()

for key, value in self._3d_arrows.items():
arrows[key] = self.get_item_from_path_at_index(value, index)

self._3d_arrows_path_lock.unlock()

return arrows

def get_3d_trajectory_at_index(self, index):
trajectories = {}

Expand Down Expand Up @@ -354,6 +370,20 @@ def unregister_3d_point(self, key):
del self._3d_points_path[key]
self._3d_points_path_lock.unlock()

def register_3d_arrow(self, key, arrow_path):
self._3d_arrows_path_lock.lock()
self._3d_arrows[key] = arrow_path
for _, value in self._3d_arrows.items():
data, _ = self.get_item_from_path(arrow_path)
arrow = data[:, 3:]
self.max_arrow = max(np.max(np.linalg.norm(arrow, axis=1)), self.max_arrow)
self._3d_arrows_path_lock.unlock()

def unregister_3d_arrow(self, key):
self._3d_arrows_path_lock.lock()
del self._3d_arrows[key]
self._3d_arrows_path_lock.unlock()

def register_3d_trajectory(self, key, trajectory_path):
self._3d_trajectories_path_lock.lock()
self._3d_trajectories_path[key] = trajectory_path
Expand Down
27 changes: 27 additions & 0 deletions robot_log_visualizer/robot_visualizer/meshcat_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def __init__(self, signal_provider, period):
self.env_list = ["GAZEBO_MODEL_PATH", "ROS_PACKAGE_PATH", "AMENT_PREFIX_PATH"]
self._registered_3d_points = set()
self._registered_3d_trajectories = dict()
self._register_3d_arrow = set()

@property
def state(self):
Expand All @@ -56,6 +57,14 @@ def register_3d_point(self, point_path, color):
radius=radius, color=color, shape_name=point_path
)

def register_3d_arrow(self, arrow_path, color):
radius = 0.02
locker = QMutexLocker(self.meshcat_visualizer_mutex)
self._register_3d_arrow.add(arrow_path)
self._meshcat_visualizer.load_arrow(
radius=radius, color=color, shape_name=arrow_path
)

def register_3d_trajectory(self, trajectory_path, color):
locker = QMutexLocker(self.meshcat_visualizer_mutex)
self._registered_3d_trajectories[trajectory_path] = (False, color)
Expand All @@ -70,6 +79,11 @@ def unregister_3d_trajectory(self, trajectory_path):
self._registered_3d_trajectories.pop(trajectory_path, None)
self._meshcat_visualizer.delete(shape_name=trajectory_path)

def unregister_3d_arrow(self, arrow_path):
locker = QMutexLocker(self.meshcat_visualizer_mutex)
self._register_3d_arrow.remove(arrow_path)
self._meshcat_visualizer.delete(shape_name=arrow_path)

def load_model(self, considered_joints, model_name):
def get_model_path_from_envs(env_list):
return [
Expand Down Expand Up @@ -216,6 +230,19 @@ def run(self):
color=self._registered_3d_trajectories[trajectory_path][1],
)

for (
arrow_path,
arrow,
) in self._signal_provider.get_3d_arrow_at_index(index).items():
if arrow_path not in self._register_3d_arrow:
continue

self._meshcat_visualizer.set_arrow_transform(
origin=arrow[0:3],
vector=arrow[3:6] / self._signal_provider.max_arrow,
shape_name=arrow_path,
)

self.meshcat_visualizer_mutex.unlock()

sleep_time = self._period - (time.time() - start)
Expand Down
31 changes: 29 additions & 2 deletions robot_log_visualizer/ui/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ def __init__(self, signal_provider, meshcat_provider, animation_period):
self.video_items = []
self.visualized_3d_points = set()
self.visualized_3d_trajectories = set()
self.visualized_3d_arrows = set()
self.visualized_3d_points_colors_palette = ColorPalette()

self.toolButton_on_click()
Expand Down Expand Up @@ -731,8 +732,10 @@ def variableTreeWidget_on_right_click(self, item_position):

add_3d_point_str = "Show as a 3D point"
add_3d_trajectory_str = "Show as a 3D trajectory"
add_3d_arrow_str = "Show as a 3D arrow"
remove_3d_point_str = "Remove the 3D point"
remove_3d_trajectory_str = "Remove the 3D trajectory"
remove_3d_arrow_str = "Remove the 3D arrow"
use_as_base_position_str = "Use as base position"
use_as_base_orientation_str = "Use as base orientation"
dont_use_as_base_position_str = "Don't use as base position"
Expand Down Expand Up @@ -784,14 +787,24 @@ def variableTreeWidget_on_right_click(self, item_position):
else:
menu.addAction(use_as_base_orientation_str + " (xyzw Quaternion)")

if item_size == 6:
if item_key in self.visualized_3d_arrows:
menu.addAction(remove_3d_arrow_str)
else:
menu.addAction(add_3d_arrow_str)

# show the menu
action = menu.exec_(self.ui.variableTreeWidget.mapToGlobal(item_position))
if action is None:
return

item_path = self.get_item_path(item)

if action.text() == add_3d_point_str or action.text() == add_3d_trajectory_str:
if (
action.text() == add_3d_point_str
or action.text() == add_3d_trajectory_str
or action.text() == add_3d_arrow_str
):
color = next(self.visualized_3d_points_colors_palette)

item.setForeground(0, QtGui.QBrush(QtGui.QColor(color.as_hex())))
Expand All @@ -802,12 +815,20 @@ def variableTreeWidget_on_right_click(self, item_position):
)
self.signal_provider.register_3d_point(item_key, item_path)
self.visualized_3d_points.add(item_key)
else:
elif action.text() == add_3d_trajectory_str:
self.meshcat_provider.register_3d_trajectory(
item_key, list(color.as_normalized_rgb())
)
self.signal_provider.register_3d_trajectory(item_key, item_path)
self.visualized_3d_trajectories.add(item_key)
elif action.text() == add_3d_arrow_str:
self.meshcat_provider.register_3d_arrow(
item_key, list(color.as_normalized_rgb())
)
self.signal_provider.register_3d_arrow(item_key, item_path)
self.visualized_3d_arrows.add(item_key)
else:
raise ValueError("Unknown action")

if action.text() == remove_3d_point_str:
self.meshcat_provider.unregister_3d_point(item_key)
Expand All @@ -821,6 +842,12 @@ def variableTreeWidget_on_right_click(self, item_position):
self.visualized_3d_trajectories.remove(item_key)
item.setForeground(0, QtGui.QBrush(QtGui.QColor(0, 0, 0)))

if action.text() == remove_3d_arrow_str:
self.meshcat_provider.unregister_3d_arrow(item_key)
self.signal_provider.unregister_3d_arrow(item_key)
self.visualized_3d_arrows.remove(item_key)
item.setForeground(0, QtGui.QBrush(QtGui.QColor(0, 0, 0)))

if (
use_as_base_orientation_str in action.text()
or action.text() == use_as_base_position_str
Expand Down

0 comments on commit 5ad8e4e

Please sign in to comment.