Skip to content

Commit 65a6665

Browse files
✨ Enhance SignalProvider and GUI for custom arrow scaling functionality
1 parent 3838e2d commit 65a6665

File tree

4 files changed

+279
-106
lines changed

4 files changed

+279
-106
lines changed

robot_log_visualizer/file_reader/signal_provider.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@ def __init__(self, period: float):
5353

5454
self._3d_arrows = {}
5555
self._3d_arrows_path_lock = QMutex()
56-
self.max_arrow = 0
56+
57+
self._max_arrow = 0
58+
self._custom_max_arrow = 0
59+
self._is_custom_max_arrow_used = False
60+
self._max_arrow_mutex = QMutex()
5761

5862
self.period = period
5963

@@ -213,6 +217,14 @@ def robot_state_path(self):
213217
locker = QMutexLocker(self.robot_state_path_lock)
214218
value = self._robot_state_path
215219
return value
220+
221+
@property
222+
def max_arrow(self):
223+
locker = QMutexLocker(self._max_arrow_mutex)
224+
if self._is_custom_max_arrow_used:
225+
return self._custom_max_arrow
226+
else:
227+
return self._max_arrow
216228

217229
@robot_state_path.setter
218230
def robot_state_path(self, robot_state_path):
@@ -308,6 +320,14 @@ def get_robot_state_at_index(self, index):
308320

309321
return robot_state
310322

323+
def set_custom_max_arrow(self, use_custom_max_arrow: bool, max_arrow: float):
324+
_ = QMutexLocker(self._max_arrow_mutex)
325+
self._is_custom_max_arrow_used = use_custom_max_arrow
326+
if use_custom_max_arrow:
327+
self._custom_max_arrow = max_arrow
328+
else:
329+
self._custom_max_arrow = 0
330+
311331
def get_3d_point_at_index(self, index):
312332
points = {}
313333

@@ -378,7 +398,9 @@ def register_3d_arrow(self, key, arrow_path):
378398
for _, value in self._3d_arrows.items():
379399
data, _ = self.get_item_from_path(arrow_path)
380400
arrow = data[:, 3:]
381-
self.max_arrow = max(np.max(np.linalg.norm(arrow, axis=1)), self.max_arrow)
401+
self._max_arrow_mutex.lock()
402+
self._max_arrow = max(np.max(np.linalg.norm(arrow, axis=1)), self._max_arrow)
403+
self._max_arrow_mutex.unlock()
382404
self._3d_arrows_path_lock.unlock()
383405

384406
def unregister_3d_arrow(self, key):

robot_log_visualizer/ui/gui.py

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@ def __init__(self, meshcat_provider, parent=None, dataset_loaded=False):
7171
self.ui.robotModelToolButton.clicked.connect(self.open_urdf_file)
7272
self.ui.packageDirToolButton.clicked.connect(self.open_package_directory)
7373

74+
# Force the arrowScaling_lineEdit to be a positive float
75+
self.ui.arrowScaling_lineEdit.setValidator(QtGui.QDoubleValidator(0, 100, 2))
76+
77+
# connect the arrowScaling_checkBox to the handle_arrow_scaling method
78+
self.ui.arrowScaling_checkBox.toggled.connect(self.handle_arrow_scaling)
79+
80+
self.clicked_button = None
81+
self.std_button = None
82+
self.ui.buttonBox.clicked.connect(self.buttonBox_on_click)
83+
7484
if dataset_loaded:
7585
frames = meshcat_provider.robot_frames()
7686
self.ui.frameNameComboBox.addItems(frames)
@@ -93,7 +103,33 @@ def get_urdf_path(self):
93103

94104
def get_package_directory(self):
95105
return self.ui.packageDirLineEdit.text()
106+
107+
def buttonBox_on_click(self, button):
108+
self.clicked_button = button
109+
110+
self.std_button = self.ui.buttonBox.standardButton(button)
96111

112+
def get_clicked_button_role(self):
113+
if self.clicked_button is not None:
114+
return self.ui.buttonBox.buttonRole(self.clicked_button)
115+
return None
116+
117+
def get_clicked_button_text(self):
118+
if self.clicked_button is not None:
119+
return self.clicked_button.text()
120+
return None
121+
122+
def get_clicked_standard_button(self):
123+
return self.std_button
124+
125+
def handle_arrow_scaling(self):
126+
# if arrowScaling_checkBox is checked the lineEdit must be disabled else it must be enabled
127+
if self.ui.arrowScaling_checkBox.isChecked():
128+
self.ui.arrowScaling_lineEdit.setText("")
129+
self.ui.arrowScaling_lineEdit.setEnabled(False)
130+
else:
131+
self.ui.arrowScaling_lineEdit.setText("")
132+
self.ui.arrowScaling_lineEdit.setEnabled(True)
97133

98134
class About(QtWidgets.QMainWindow):
99135
def __init__(self):
@@ -682,9 +718,45 @@ def open_set_robot_model(self):
682718
)
683719
outcome = dlg.exec()
684720
if outcome == QDialog.Accepted:
685-
if not self.dataset_loaded:
686-
self.meshcat_provider.model_path = dlg.get_urdf_path()
687-
self.meshcat_provider.custom_package_dir = dlg.get_package_directory()
721+
722+
# check which button was clicked
723+
button_role = dlg.get_clicked_button_role()
724+
button_text = dlg.get_clicked_button_text()
725+
std_button = dlg.get_clicked_standard_button()
726+
727+
if std_button == QtWidgets.QDialogButtonBox.SaveAll:
728+
if not self.dataset_loaded:
729+
self.meshcat_provider.model_path = dlg.get_urdf_path()
730+
self.meshcat_provider.custom_package_dir = dlg.get_package_directory()
731+
732+
733+
arrow_scaling_value = dlg.ui.arrowScaling_lineEdit.text()
734+
if not arrow_scaling_value:
735+
arrow_scaling_value = "1.0"
736+
else:
737+
arrow_scaling_value = float(arrow_scaling_value)
738+
self.signal_provider.set_custom_max_arrow(
739+
not dlg.ui.arrowScaling_checkBox.isChecked(),
740+
arrow_scaling_value
741+
)
742+
if std_button == QtWidgets.QDialogButtonBox.Save:
743+
# we need to check which tab is selected in the dlg
744+
if dlg.ui.tabWidget.currentIndex() == 0:
745+
if not self.dataset_loaded:
746+
self.meshcat_provider.model_path = dlg.get_urdf_path()
747+
self.meshcat_provider.custom_package_dir = dlg.get_package_directory()
748+
else:
749+
arrow_scaling_value = dlg.ui.arrowScaling_lineEdit.text()
750+
# if it is empty we set it to 1.0
751+
if not arrow_scaling_value:
752+
arrow_scaling_value = "1.0"
753+
else:
754+
arrow_scaling_value = float(arrow_scaling_value)
755+
self.signal_provider.set_custom_max_arrow(
756+
not dlg.ui.arrowScaling_checkBox.isChecked(),
757+
arrow_scaling_value
758+
)
759+
688760
else:
689761
self.meshcat_provider.load_model(
690762
self.signal_provider.joints_name,

0 commit comments

Comments
 (0)