Commit 430847f0fc632ecae5c3c9ab13be35f36b78b0b2
1 parent
8c526577
Exists in
master
MOD: separated robot target from markers
Showing
2 changed files
with
54 additions
and
57 deletions
Show diff stats
invesalius/data/bases.py
@@ -245,6 +245,31 @@ def object_registration(fiducials, orients, coord_raw, m_change): | @@ -245,6 +245,31 @@ def object_registration(fiducials, orients, coord_raw, m_change): | ||
245 | 245 | ||
246 | return t_obj_raw, s0_raw, r_s0_raw, s0_dyn, m_obj_raw, r_obj_img | 246 | return t_obj_raw, s0_raw, r_s0_raw, s0_dyn, m_obj_raw, r_obj_img |
247 | 247 | ||
248 | +def compute_robot_target_matrix(head, robot): | ||
249 | + """ | ||
250 | + :param head: nx6 array of head coordinates from tracking device in robot space | ||
251 | + :param robot: nx6 array of robot coordinates | ||
252 | + | ||
253 | + :return: target_robot_matrix: 3x3 array representing change of basis from robot to head in robot system | ||
254 | + """ | ||
255 | + # compute head target matrix | ||
256 | + m_head_target = dco.coordinates_to_transformation_matrix( | ||
257 | + position=head[:3], | ||
258 | + orientation=head[3:], | ||
259 | + axes='rzyx', | ||
260 | + ) | ||
261 | + | ||
262 | + # compute robot target matrix | ||
263 | + m_robot_target = dco.coordinates_to_transformation_matrix( | ||
264 | + position=robot[:3], | ||
265 | + orientation=robot[3:], | ||
266 | + axes='rzyx', | ||
267 | + ) | ||
268 | + target_robot_matrix = np.linalg.inv(m_head_target) @ m_robot_target | ||
269 | + | ||
270 | + return target_robot_matrix | ||
271 | + | ||
272 | + | ||
248 | class transform_tracker_to_robot(object): | 273 | class transform_tracker_to_robot(object): |
249 | M_tracker_to_robot = np.array([]) | 274 | M_tracker_to_robot = np.array([]) |
250 | def transformation_tracker_to_robot(self, tracker_coord): | 275 | def transformation_tracker_to_robot(self, tracker_coord): |
invesalius/gui/task_navigator.py
@@ -63,13 +63,13 @@ import invesalius.data.record_coords as rec | @@ -63,13 +63,13 @@ import invesalius.data.record_coords as rec | ||
63 | import invesalius.data.vtk_utils as vtk_utils | 63 | import invesalius.data.vtk_utils as vtk_utils |
64 | import invesalius.gui.dialogs as dlg | 64 | import invesalius.gui.dialogs as dlg |
65 | import invesalius.project as prj | 65 | import invesalius.project as prj |
66 | +import invesalius.data.bases as db | ||
66 | from invesalius import utils | 67 | from invesalius import utils |
67 | from invesalius.gui import utils as gui_utils | 68 | from invesalius.gui import utils as gui_utils |
68 | from invesalius.navigation.icp import ICP | 69 | from invesalius.navigation.icp import ICP |
69 | from invesalius.navigation.navigation import Navigation | 70 | from invesalius.navigation.navigation import Navigation |
70 | from invesalius.navigation.tracker import Tracker | 71 | from invesalius.navigation.tracker import Tracker |
71 | from invesalius.navigation.robot import Robot | 72 | from invesalius.navigation.robot import Robot |
72 | -import invesalius.data.transformations as tr | ||
73 | 73 | ||
74 | HAS_PEDAL_CONNECTION = True | 74 | HAS_PEDAL_CONNECTION = True |
75 | try: | 75 | try: |
@@ -690,11 +690,9 @@ class NeuronavigationPanel(wx.Panel): | @@ -690,11 +690,9 @@ class NeuronavigationPanel(wx.Panel): | ||
690 | colour = (0., 1., 0.) | 690 | colour = (0., 1., 0.) |
691 | size = 2 | 691 | size = 2 |
692 | seed = 3 * [0.] | 692 | seed = 3 * [0.] |
693 | - head = 6 * [0.] | ||
694 | - robot = 6 * [0.] | ||
695 | 693 | ||
696 | - Publisher.sendMessage('Create marker', coord=coord, colour=colour, size=size, | ||
697 | - label=label, seed=seed, head=head, robot=robot) | 694 | + Publisher.sendMessage('Create marker', coord=coord, colour=colour, size=size, label=label, seed=seed) |
695 | + | ||
698 | else: | 696 | else: |
699 | for m in [0, 1, 2]: | 697 | for m in [0, 1, 2]: |
700 | self.numctrls_fiducial[n][m].SetValue(float(self.current_coord[m])) | 698 | self.numctrls_fiducial[n][m].SetValue(float(self.current_coord[m])) |
@@ -1136,18 +1134,6 @@ class MarkersPanel(wx.Panel): | @@ -1136,18 +1134,6 @@ class MarkersPanel(wx.Panel): | ||
1136 | x_seed : float = 0 | 1134 | x_seed : float = 0 |
1137 | y_seed : float = 0 | 1135 | y_seed : float = 0 |
1138 | z_seed : float = 0 | 1136 | z_seed : float = 0 |
1139 | - x_head : float = 0 | ||
1140 | - y_head : float = 0 | ||
1141 | - z_head : float = 0 | ||
1142 | - alpha_head : float = 0 | ||
1143 | - beta_head : float = 0 | ||
1144 | - gamma_head : float = 0 | ||
1145 | - x_robot : float = 0 | ||
1146 | - y_robot : float = 0 | ||
1147 | - z_robot : float = 0 | ||
1148 | - alpha_robot : float = 0 | ||
1149 | - beta_robot: float = 0 | ||
1150 | - gamma_robot : float = 0 | ||
1151 | is_target : bool = False | 1137 | is_target : bool = False |
1152 | session_id : int = 1 | 1138 | session_id : int = 1 |
1153 | 1139 | ||
@@ -1178,24 +1164,6 @@ class MarkersPanel(wx.Panel): | @@ -1178,24 +1164,6 @@ class MarkersPanel(wx.Panel): | ||
1178 | def seed(self, new_seed): | 1164 | def seed(self, new_seed): |
1179 | self.x_seed, self.y_seed, self.z_seed = new_seed | 1165 | self.x_seed, self.y_seed, self.z_seed = new_seed |
1180 | 1166 | ||
1181 | - # x_head, y_head, z_head, alpha_head, beta_head, gamma_head can be jointly accessed as robot | ||
1182 | - @property | ||
1183 | - def head(self): | ||
1184 | - return list((self.x_head, self.y_head, self.z_head, self.alpha_head, self.beta_head, self.gamma_head),) | ||
1185 | - | ||
1186 | - @head.setter | ||
1187 | - def head(self, new_head): | ||
1188 | - self.x_head, self.y_head, self.z_head, self.alpha_head, self.beta_head, self.gamma_head = new_head | ||
1189 | - | ||
1190 | - # x_robot, y_robot, z_robot, alpha_robot, beta_robot, gamma_robot can be jointly accessed as robot | ||
1191 | - @property | ||
1192 | - def robot(self): | ||
1193 | - return list((self.x_robot, self.y_robot, self.z_robot, self.alpha_robot, self.beta_robot, self.gamma_robot),) | ||
1194 | - | ||
1195 | - @robot.setter | ||
1196 | - def robot(self, new_robot): | ||
1197 | - self.x_robot, self.y_robot, self.z_robot, self.alpha_robot, self.beta_robot, self.gamma_robot = new_robot | ||
1198 | - | ||
1199 | @classmethod | 1167 | @classmethod |
1200 | def to_string_headers(cls): | 1168 | def to_string_headers(cls): |
1201 | """Return the string containing tab-separated list of field names (headers).""" | 1169 | """Return the string containing tab-separated list of field names (headers).""" |
@@ -1235,6 +1203,19 @@ class MarkersPanel(wx.Panel): | @@ -1235,6 +1203,19 @@ class MarkersPanel(wx.Panel): | ||
1235 | if field.type is bool: | 1203 | if field.type is bool: |
1236 | setattr(self, field.name, str_val=='True') | 1204 | setattr(self, field.name, str_val=='True') |
1237 | 1205 | ||
1206 | + @dataclasses.dataclass | ||
1207 | + class Robot_Marker: | ||
1208 | + """Class for storing robot target.""" | ||
1209 | + m_robot_target : list = None | ||
1210 | + | ||
1211 | + @property | ||
1212 | + def robot_target_matrix(self): | ||
1213 | + return self.m_robot_target | ||
1214 | + | ||
1215 | + @robot_target_matrix.setter | ||
1216 | + def robot_target_matrix(self, new_m_robot_target): | ||
1217 | + self.m_robot_target = new_m_robot_target | ||
1218 | + | ||
1238 | def __init__(self, parent, tracker): | 1219 | def __init__(self, parent, tracker): |
1239 | wx.Panel.__init__(self, parent) | 1220 | wx.Panel.__init__(self, parent) |
1240 | try: | 1221 | try: |
@@ -1252,9 +1233,9 @@ class MarkersPanel(wx.Panel): | @@ -1252,9 +1233,9 @@ class MarkersPanel(wx.Panel): | ||
1252 | self.current_coord = 0, 0, 0, 0, 0, 0 | 1233 | self.current_coord = 0, 0, 0, 0, 0, 0 |
1253 | self.current_angle = 0, 0, 0 | 1234 | self.current_angle = 0, 0, 0 |
1254 | self.current_seed = 0, 0, 0 | 1235 | self.current_seed = 0, 0, 0 |
1236 | + self.current_robot_target_matrix = [None] * 9 | ||
1255 | self.markers = [] | 1237 | self.markers = [] |
1256 | - self.current_head = 0, 0, 0, 0, 0, 0 | ||
1257 | - self.current_robot = 0, 0, 0, 0, 0, 0 | 1238 | + self.robot_markers = [] |
1258 | self.nav_status = False | 1239 | self.nav_status = False |
1259 | 1240 | ||
1260 | self.marker_colour = const.MARKER_COLOUR | 1241 | self.marker_colour = const.MARKER_COLOUR |
@@ -1379,6 +1360,7 @@ class MarkersPanel(wx.Panel): | @@ -1379,6 +1360,7 @@ class MarkersPanel(wx.Panel): | ||
1379 | """ | 1360 | """ |
1380 | for i in reversed(index): | 1361 | for i in reversed(index): |
1381 | del self.markers[i] | 1362 | del self.markers[i] |
1363 | + del self.robot_markers[i] | ||
1382 | self.lc.DeleteItem(i) | 1364 | self.lc.DeleteItem(i) |
1383 | for n in range(0, self.lc.GetItemCount()): | 1365 | for n in range(0, self.lc.GetItemCount()): |
1384 | self.lc.SetItem(n, 0, str(n+1)) | 1366 | self.lc.SetItem(n, 0, str(n+1)) |
@@ -1430,8 +1412,9 @@ class MarkersPanel(wx.Panel): | @@ -1430,8 +1412,9 @@ class MarkersPanel(wx.Panel): | ||
1430 | self.current_seed = coord_offset | 1412 | self.current_seed = coord_offset |
1431 | 1413 | ||
1432 | def UpdateRobotCoordinates(self, coordinates_raw, markers_flag): | 1414 | def UpdateRobotCoordinates(self, coordinates_raw, markers_flag): |
1433 | - self.current_head = coordinates_raw[1] | ||
1434 | - self.current_robot = coordinates_raw[2] | 1415 | + head = coordinates_raw[1] |
1416 | + robot = coordinates_raw[2] | ||
1417 | + self.current_robot_target_matrix = db.compute_robot_target_matrix(head, robot) | ||
1435 | 1418 | ||
1436 | def OnMouseRightDown(self, evt): | 1419 | def OnMouseRightDown(self, evt): |
1437 | # TODO: Enable the "Set as target" only when target is created with registered object | 1420 | # TODO: Enable the "Set as target" only when target is created with registered object |
@@ -1504,22 +1487,9 @@ class MarkersPanel(wx.Panel): | @@ -1504,22 +1487,9 @@ class MarkersPanel(wx.Panel): | ||
1504 | if isinstance(evt, int): | 1487 | if isinstance(evt, int): |
1505 | self.lc.Focus(evt) | 1488 | self.lc.Focus(evt) |
1506 | 1489 | ||
1507 | - robot = self.markers[self.lc.GetFocusedItem()].robot | ||
1508 | - head = self.markers[self.lc.GetFocusedItem()].head | ||
1509 | - | ||
1510 | - trans = tr.translation_matrix(robot[:3]) | ||
1511 | - a, b, g = np.radians(robot[3:]) | ||
1512 | - rot = tr.euler_matrix(a, b, g, 'rzyx') | ||
1513 | - m_robot_target = tr.concatenate_matrices(trans, rot) | ||
1514 | - | ||
1515 | - trans = tr.translation_matrix(head[:3]) | ||
1516 | - a, b, g = np.radians(head[3:]) | ||
1517 | - rot = tr.euler_matrix(a, b, g, 'rzyx') | ||
1518 | - m_ref_target = tr.concatenate_matrices(trans, rot) | ||
1519 | - | ||
1520 | - m_change_robot_to_head = np.linalg.inv(m_ref_target) @ m_robot_target | 1490 | + m_target_robot = self.robot_markers[self.lc.GetFocusedItem()].robot_target_matrix |
1521 | 1491 | ||
1522 | - Publisher.sendMessage('Robot target matrix', robot_tracker_flag=True, m_change_robot_to_head=m_change_robot_to_head) | 1492 | + Publisher.sendMessage('Robot target matrix', robot_tracker_flag=True, m_change_robot_to_head=m_target_robot) |
1523 | 1493 | ||
1524 | def OnDeleteAllMarkers(self, evt=None): | 1494 | def OnDeleteAllMarkers(self, evt=None): |
1525 | if evt is None: | 1495 | if evt is None: |
@@ -1536,6 +1506,7 @@ class MarkersPanel(wx.Panel): | @@ -1536,6 +1506,7 @@ class MarkersPanel(wx.Panel): | ||
1536 | wx.MessageBox(_("Target deleted."), _("InVesalius 3")) | 1506 | wx.MessageBox(_("Target deleted."), _("InVesalius 3")) |
1537 | 1507 | ||
1538 | self.markers = [] | 1508 | self.markers = [] |
1509 | + self.robot_markers = [] | ||
1539 | Publisher.sendMessage('Remove all markers', indexes=self.lc.GetItemCount()) | 1510 | Publisher.sendMessage('Remove all markers', indexes=self.lc.GetItemCount()) |
1540 | self.lc.DeleteAllItems() | 1511 | self.lc.DeleteAllItems() |
1541 | Publisher.sendMessage('Stop Blink Marker', index='DeleteAll') | 1512 | Publisher.sendMessage('Stop Blink Marker', index='DeleteAll') |
@@ -1656,7 +1627,7 @@ class MarkersPanel(wx.Panel): | @@ -1656,7 +1627,7 @@ class MarkersPanel(wx.Panel): | ||
1656 | def OnChangeCurrentSession(self, new_session_id): | 1627 | def OnChangeCurrentSession(self, new_session_id): |
1657 | self.current_session = new_session_id | 1628 | self.current_session = new_session_id |
1658 | 1629 | ||
1659 | - def CreateMarker(self, coord=None, colour=None, size=None, label='*', is_target=False, seed=None, head=None, robot=None, session_id=None): | 1630 | + def CreateMarker(self, coord=None, colour=None, size=None, label='*', is_target=False, seed=None, session_id=None): |
1660 | new_marker = self.Marker() | 1631 | new_marker = self.Marker() |
1661 | new_marker.coord = coord or self.current_coord | 1632 | new_marker.coord = coord or self.current_coord |
1662 | new_marker.colour = colour or self.marker_colour | 1633 | new_marker.colour = colour or self.marker_colour |
@@ -1664,9 +1635,9 @@ class MarkersPanel(wx.Panel): | @@ -1664,9 +1635,9 @@ class MarkersPanel(wx.Panel): | ||
1664 | new_marker.label = label | 1635 | new_marker.label = label |
1665 | new_marker.is_target = is_target | 1636 | new_marker.is_target = is_target |
1666 | new_marker.seed = seed or self.current_seed | 1637 | new_marker.seed = seed or self.current_seed |
1667 | - new_marker.head = head or self.current_head | ||
1668 | - new_marker.robot = robot or self.current_robot | ||
1669 | new_marker.session_id = session_id or self.current_session | 1638 | new_marker.session_id = session_id or self.current_session |
1639 | + new_robot_marker = self.Robot_Marker() | ||
1640 | + new_robot_marker.robot_target_matrix = self.current_robot_target_matrix | ||
1670 | 1641 | ||
1671 | # Note that ball_id is zero-based, so we assign it len(self.markers) before the new marker is added | 1642 | # Note that ball_id is zero-based, so we assign it len(self.markers) before the new marker is added |
1672 | Publisher.sendMessage('Add marker', ball_id=len(self.markers), | 1643 | Publisher.sendMessage('Add marker', ball_id=len(self.markers), |
@@ -1674,6 +1645,7 @@ class MarkersPanel(wx.Panel): | @@ -1674,6 +1645,7 @@ class MarkersPanel(wx.Panel): | ||
1674 | colour=new_marker.colour, | 1645 | colour=new_marker.colour, |
1675 | coord=new_marker.coord[:3]) | 1646 | coord=new_marker.coord[:3]) |
1676 | self.markers.append(new_marker) | 1647 | self.markers.append(new_marker) |
1648 | + self.robot_markers.append(new_robot_marker) | ||
1677 | 1649 | ||
1678 | # Add item to list control in panel | 1650 | # Add item to list control in panel |
1679 | num_items = self.lc.GetItemCount() | 1651 | num_items = self.lc.GetItemCount() |