Commit 490d87a83a37a37b3544842d88e251fdb2869c20
Committed by
GitHub
Exists in
master
Merge pull request #369 from rmatsuda/Thread-for-coordinates
Creation of a new thread for coordinates acquisition
Showing
8 changed files
with
92 additions
and
51 deletions
Show diff stats
invesalius/constants.py
@@ -818,6 +818,7 @@ SEED_RADIUS = 1.5 | @@ -818,6 +818,7 @@ SEED_RADIUS = 1.5 | ||
818 | 818 | ||
819 | # Increased the default sleep parameter from 0.1 to 0.15 to decrease CPU load during navigation. | 819 | # Increased the default sleep parameter from 0.1 to 0.15 to decrease CPU load during navigation. |
820 | SLEEP_NAVIGATION = 0.15 | 820 | SLEEP_NAVIGATION = 0.15 |
821 | +SLEEP_COORDINATES = 0.05 | ||
821 | 822 | ||
822 | BRAIN_OPACITY = 0.5 | 823 | BRAIN_OPACITY = 0.5 |
823 | N_CPU = psutil.cpu_count() | 824 | N_CPU = psutil.cpu_count() |
invesalius/data/coordinates.py
@@ -19,6 +19,9 @@ | @@ -19,6 +19,9 @@ | ||
19 | 19 | ||
20 | from math import sin, cos | 20 | from math import sin, cos |
21 | import numpy as np | 21 | import numpy as np |
22 | +import queue | ||
23 | +import threading | ||
24 | +import wx | ||
22 | 25 | ||
23 | import invesalius.data.bases as db | 26 | import invesalius.data.bases as db |
24 | import invesalius.data.transformations as tr | 27 | import invesalius.data.transformations as tr |
@@ -28,9 +31,21 @@ from time import sleep | @@ -28,9 +31,21 @@ from time import sleep | ||
28 | from random import uniform | 31 | from random import uniform |
29 | from invesalius.pubsub import pub as Publisher | 32 | from invesalius.pubsub import pub as Publisher |
30 | 33 | ||
34 | +class TrackerCoordinates(): | ||
35 | + def __init__(self): | ||
36 | + self.coord = None | ||
37 | + self.markers_flag = [False, False, False] | ||
31 | 38 | ||
32 | -def GetCoordinates(trck_init, trck_id, ref_mode): | 39 | + def SetCoordinates(self, coord, markers_flag): |
40 | + self.coord = coord | ||
41 | + self.markers_flag = markers_flag | ||
42 | + wx.CallAfter(Publisher.sendMessage, 'Sensors ID', markers_flag=self.markers_flag) | ||
33 | 43 | ||
44 | + def GetCoordinates(self): | ||
45 | + return self.coord, self.markers_flag | ||
46 | + | ||
47 | + | ||
48 | +def GetCoordinatesForThread(trck_init, trck_id, ref_mode): | ||
34 | """ | 49 | """ |
35 | Read coordinates from spatial tracking devices using | 50 | Read coordinates from spatial tracking devices using |
36 | 51 | ||
@@ -52,11 +67,13 @@ def GetCoordinates(trck_init, trck_id, ref_mode): | @@ -52,11 +67,13 @@ def GetCoordinates(trck_init, trck_id, ref_mode): | ||
52 | const.OPTITRACK: OptitrackCoord, | 67 | const.OPTITRACK: OptitrackCoord, |
53 | const.DEBUGTRACKRANDOM: DebugCoordRandom, | 68 | const.DEBUGTRACKRANDOM: DebugCoordRandom, |
54 | const.DEBUGTRACKAPPROACH: DebugCoordRandom} | 69 | const.DEBUGTRACKAPPROACH: DebugCoordRandom} |
55 | - coord = getcoord[trck_id](trck_init, trck_id, ref_mode) | 70 | + |
71 | + coord, markers_flag = getcoord[trck_id](trck_init, trck_id, ref_mode) | ||
56 | else: | 72 | else: |
57 | print("Select Tracker") | 73 | print("Select Tracker") |
58 | 74 | ||
59 | - return coord | 75 | + return coord, markers_flag |
76 | + | ||
60 | 77 | ||
61 | def OptitrackCoord(trck_init, trck_id, ref_mode): | 78 | def OptitrackCoord(trck_init, trck_id, ref_mode): |
62 | """ | 79 | """ |
@@ -93,8 +110,10 @@ def OptitrackCoord(trck_init, trck_id, ref_mode): | @@ -93,8 +110,10 @@ def OptitrackCoord(trck_init, trck_id, ref_mode): | ||
93 | coord3 = np.array([float(trck.PositionCoilZ1) * scale[0], float(trck.PositionCoilX1) * scale[1], | 110 | coord3 = np.array([float(trck.PositionCoilZ1) * scale[0], float(trck.PositionCoilX1) * scale[1], |
94 | float(trck.PositionCoilY1) * scale[2]]) | 111 | float(trck.PositionCoilY1) * scale[2]]) |
95 | coord3 = np.hstack((coord3, angles_coil)) | 112 | coord3 = np.hstack((coord3, angles_coil)) |
113 | + | ||
96 | coord = np.vstack([coord1, coord2, coord3]) | 114 | coord = np.vstack([coord1, coord2, coord3]) |
97 | - return coord | 115 | + |
116 | + return coord, [trck.probeID, trck.HeadID, trck.coilID] | ||
98 | 117 | ||
99 | 118 | ||
100 | def PolarisCoord(trck_init, trck_id, ref_mode): | 119 | def PolarisCoord(trck_init, trck_id, ref_mode): |
@@ -117,9 +136,9 @@ def PolarisCoord(trck_init, trck_id, ref_mode): | @@ -117,9 +136,9 @@ def PolarisCoord(trck_init, trck_id, ref_mode): | ||
117 | coord3 = np.hstack((trans_obj, angles_obj)) | 136 | coord3 = np.hstack((trans_obj, angles_obj)) |
118 | 137 | ||
119 | coord = np.vstack([coord1, coord2, coord3]) | 138 | coord = np.vstack([coord1, coord2, coord3]) |
120 | - # Publisher.sendMessage('Sensors ID', probe_id=trck.probeID, ref_id=trck.refID, obj_id=trck.objID) | ||
121 | 139 | ||
122 | - return coord | 140 | + return coord, [trck.probeID, trck.refID, trck.objID] |
141 | + | ||
123 | 142 | ||
124 | def PolarisP4Coord(trck_init, trck_id, ref_mode): | 143 | def PolarisP4Coord(trck_init, trck_id, ref_mode): |
125 | trck = trck_init[0] | 144 | trck = trck_init[0] |
@@ -134,45 +153,41 @@ def PolarisP4Coord(trck_init, trck_id, ref_mode): | @@ -134,45 +153,41 @@ def PolarisP4Coord(trck_init, trck_id, ref_mode): | ||
134 | obj = obj[2:] | 153 | obj = obj[2:] |
135 | 154 | ||
136 | if probe[:7] == "MISSING": | 155 | if probe[:7] == "MISSING": |
137 | - if not "coord1" in locals(): | ||
138 | - coord1 = np.hstack(([0, 0, 0], [0, 0, 0])) | 156 | + coord1 = np.hstack(([0, 0, 0], [0, 0, 0])) |
139 | else: | 157 | else: |
140 | q = [int(probe[i:i + 6]) * 0.0001 for i in range(0, 24, 6)] | 158 | q = [int(probe[i:i + 6]) * 0.0001 for i in range(0, 24, 6)] |
141 | t = [int(probe[i:i + 7]) * 0.01 for i in range(24, 45, 7)] | 159 | t = [int(probe[i:i + 7]) * 0.01 for i in range(24, 45, 7)] |
142 | angles_probe = np.degrees(tr.euler_from_quaternion(q, axes='rzyx')) | 160 | angles_probe = np.degrees(tr.euler_from_quaternion(q, axes='rzyx')) |
143 | trans_probe = np.array(t).astype(float) | 161 | trans_probe = np.array(t).astype(float) |
144 | coord1 = np.hstack((trans_probe, angles_probe)) | 162 | coord1 = np.hstack((trans_probe, angles_probe)) |
145 | - | ||
146 | - if ref[:7] == "MISSING": | ||
147 | - if not "coord2" in locals(): | 163 | + if ref[:7] == "MISSING": |
148 | coord2 = np.hstack(([0, 0, 0], [0, 0, 0])) | 164 | coord2 = np.hstack(([0, 0, 0], [0, 0, 0])) |
149 | - else: | ||
150 | - q = [int(ref[i:i + 6]) * 0.0001 for i in range(0, 24, 6)] | ||
151 | - t = [int(ref[i:i + 7]) * 0.01 for i in range(24, 45, 7)] | ||
152 | - angles_ref = np.degrees(tr.euler_from_quaternion(q, axes='rzyx')) | ||
153 | - trans_ref = np.array(t).astype(float) | ||
154 | - coord2 = np.hstack((trans_ref, angles_ref)) | ||
155 | - | ||
156 | - if obj[:7] == "MISSING": | ||
157 | - if not "coord3" in locals(): | 165 | + else: |
166 | + q = [int(ref[i:i + 6]) * 0.0001 for i in range(0, 24, 6)] | ||
167 | + t = [int(ref[i:i + 7]) * 0.01 for i in range(24, 45, 7)] | ||
168 | + angles_ref = np.degrees(tr.euler_from_quaternion(q, axes='rzyx')) | ||
169 | + trans_ref = np.array(t).astype(float) | ||
170 | + coord2 = np.hstack((trans_ref, angles_ref)) | ||
171 | + | ||
172 | + if obj[:7] == "MISSING": | ||
158 | coord3 = np.hstack(([0, 0, 0], [0, 0, 0])) | 173 | coord3 = np.hstack(([0, 0, 0], [0, 0, 0])) |
159 | - else: | ||
160 | - q = [int(obj[i:i + 6]) * 0.0001 for i in range(0, 24, 6)] | ||
161 | - t = [int(obj[i:i + 7]) * 0.01 for i in range(24, 45, 7)] | ||
162 | - angles_obj = np.degrees(tr.euler_from_quaternion(q, axes='rzyx')) | ||
163 | - trans_obj = np.array(t).astype(float) | ||
164 | - coord3 = np.hstack((trans_obj, angles_obj)) | 174 | + else: |
175 | + q = [int(obj[i:i + 6]) * 0.0001 for i in range(0, 24, 6)] | ||
176 | + t = [int(obj[i:i + 7]) * 0.01 for i in range(24, 45, 7)] | ||
177 | + angles_obj = np.degrees(tr.euler_from_quaternion(q, axes='rzyx')) | ||
178 | + trans_obj = np.array(t).astype(float) | ||
179 | + coord3 = np.hstack((trans_obj, angles_obj)) | ||
165 | 180 | ||
166 | - Publisher.sendMessage('Sensors ID', probe_id=trck.probeID, ref_id=trck.refID, obj_id=trck.objID) | ||
167 | - coord = np.vstack([coord1, coord2, coord3]) | 181 | + coord = np.vstack([coord1, coord2, coord3]) |
182 | + | ||
183 | + return coord, [trck.probeID, trck.refID, trck.objID] | ||
168 | 184 | ||
169 | - return coord | ||
170 | 185 | ||
171 | def CameraCoord(trck_init, trck_id, ref_mode): | 186 | def CameraCoord(trck_init, trck_id, ref_mode): |
172 | trck = trck_init[0] | 187 | trck = trck_init[0] |
173 | - coord, probeID, refID = trck.Run() | ||
174 | - Publisher.sendMessage('Sensors ID', probe_id=probeID, ref_id=refID) | ||
175 | - return coord | 188 | + coord, probeID, refID, coilID = trck.Run() |
189 | + | ||
190 | + return coord, [probeID, refID, coilID] | ||
176 | 191 | ||
177 | def ClaronCoord(trck_init, trck_id, ref_mode): | 192 | def ClaronCoord(trck_init, trck_id, ref_mode): |
178 | trck = trck_init[0] | 193 | trck = trck_init[0] |
@@ -193,9 +208,7 @@ def ClaronCoord(trck_init, trck_id, ref_mode): | @@ -193,9 +208,7 @@ def ClaronCoord(trck_init, trck_id, ref_mode): | ||
193 | 208 | ||
194 | coord = np.vstack([coord1, coord2, coord3]) | 209 | coord = np.vstack([coord1, coord2, coord3]) |
195 | 210 | ||
196 | - Publisher.sendMessage('Sensors ID', probe_id=trck.probeID, ref_id=trck.refID) | ||
197 | - | ||
198 | - return coord | 211 | + return coord, [trck.probeID, trck.refID, trck.coilID] |
199 | 212 | ||
200 | 213 | ||
201 | def PolhemusCoord(trck, trck_id, ref_mode): | 214 | def PolhemusCoord(trck, trck_id, ref_mode): |
@@ -210,7 +223,7 @@ def PolhemusCoord(trck, trck_id, ref_mode): | @@ -210,7 +223,7 @@ def PolhemusCoord(trck, trck_id, ref_mode): | ||
210 | elif trck[1] == 'wrapper': | 223 | elif trck[1] == 'wrapper': |
211 | coord = PolhemusWrapperCoord(trck[0], trck_id, ref_mode) | 224 | coord = PolhemusWrapperCoord(trck[0], trck_id, ref_mode) |
212 | 225 | ||
213 | - return coord | 226 | + return coord, None |
214 | 227 | ||
215 | 228 | ||
216 | def PolhemusWrapperCoord(trck, trck_id, ref_mode): | 229 | def PolhemusWrapperCoord(trck, trck_id, ref_mode): |
@@ -362,16 +375,13 @@ def DebugCoordRandom(trk_init, trck_id, ref_mode): | @@ -362,16 +375,13 @@ def DebugCoordRandom(trk_init, trck_id, ref_mode): | ||
362 | # coord4 = np.array([uniform(1, 200), uniform(1, 200), uniform(1, 200), | 375 | # coord4 = np.array([uniform(1, 200), uniform(1, 200), uniform(1, 200), |
363 | # uniform(-180.0, 180.0), uniform(-180.0, 180.0), uniform(-180.0, 180.0)]) | 376 | # uniform(-180.0, 180.0), uniform(-180.0, 180.0), uniform(-180.0, 180.0)]) |
364 | 377 | ||
365 | - Publisher.sendMessage('Sensors ID', probe_id=int(uniform(0, 5)), ref_id=int(uniform(0, 5)), obj_id=int(uniform(0, 5))) | ||
366 | - | ||
367 | - return np.vstack([coord1, coord2, coord3, coord4]) | 378 | + return np.vstack([coord1, coord2, coord3, coord4]), [int(uniform(0, 5)), int(uniform(0, 5)), int(uniform(0, 5))] |
368 | 379 | ||
369 | 380 | ||
370 | def coordinates_to_transformation_matrix(position, orientation, axes='sxyz'): | 381 | def coordinates_to_transformation_matrix(position, orientation, axes='sxyz'): |
371 | """ | 382 | """ |
372 | Transform vectors consisting of position and orientation (in Euler angles) in 3d-space into a 4x4 | 383 | Transform vectors consisting of position and orientation (in Euler angles) in 3d-space into a 4x4 |
373 | transformation matrix that combines the rotation and translation. | 384 | transformation matrix that combines the rotation and translation. |
374 | - | ||
375 | :param position: A vector of three coordinates. | 385 | :param position: A vector of three coordinates. |
376 | :param orientation: A vector of three Euler angles in degrees. | 386 | :param orientation: A vector of three Euler angles in degrees. |
377 | :param axes: The order in which the rotations are done for the axes. See transformations.py for details. Defaults to 'sxyz'. | 387 | :param axes: The order in which the rotations are done for the axes. See transformations.py for details. Defaults to 'sxyz'. |
@@ -391,9 +401,7 @@ def transformation_matrix_to_coordinates(matrix, axes='sxyz'): | @@ -391,9 +401,7 @@ def transformation_matrix_to_coordinates(matrix, axes='sxyz'): | ||
391 | """ | 401 | """ |
392 | Given a matrix that combines the rotation and translation, return the position and the orientation | 402 | Given a matrix that combines the rotation and translation, return the position and the orientation |
393 | determined by the matrix. The orientation is given as three Euler angles. | 403 | determined by the matrix. The orientation is given as three Euler angles. |
394 | - | ||
395 | The inverse of coordinates_of_transformation_matrix when the parameter 'axes' matches. | 404 | The inverse of coordinates_of_transformation_matrix when the parameter 'axes' matches. |
396 | - | ||
397 | :param matrix: A 4x4 transformation matrix. | 405 | :param matrix: A 4x4 transformation matrix. |
398 | :param axes: The order in which the rotations are done for the axes. See transformations.py for details. Defaults to 'sxyz'. | 406 | :param axes: The order in which the rotations are done for the axes. See transformations.py for details. Defaults to 'sxyz'. |
399 | :return: The position (a vector of length 3) and Euler angles for the orientation in degrees (a vector of length 3). | 407 | :return: The position (a vector of length 3) and Euler angles for the orientation in degrees (a vector of length 3). |
@@ -479,6 +487,7 @@ def dynamic_reference_m2(probe, reference): | @@ -479,6 +487,7 @@ def dynamic_reference_m2(probe, reference): | ||
479 | :param reference: sensor two defined as reference | 487 | :param reference: sensor two defined as reference |
480 | :return: rotated and translated coordinates | 488 | :return: rotated and translated coordinates |
481 | """ | 489 | """ |
490 | + | ||
482 | M = coordinates_to_transformation_matrix( | 491 | M = coordinates_to_transformation_matrix( |
483 | position=reference[:3], | 492 | position=reference[:3], |
484 | orientation=reference[3:], | 493 | orientation=reference[3:], |
@@ -489,6 +498,7 @@ def dynamic_reference_m2(probe, reference): | @@ -489,6 +498,7 @@ def dynamic_reference_m2(probe, reference): | ||
489 | orientation=probe[3:], | 498 | orientation=probe[3:], |
490 | axes='rzyx', | 499 | axes='rzyx', |
491 | ) | 500 | ) |
501 | + | ||
492 | M_dyn = np.linalg.inv(M) @ M_p | 502 | M_dyn = np.linalg.inv(M) @ M_p |
493 | 503 | ||
494 | al, be, ga = tr.euler_from_matrix(M_dyn, 'rzyx') | 504 | al, be, ga = tr.euler_from_matrix(M_dyn, 'rzyx') |
@@ -529,3 +539,17 @@ def offset_coordinate(p_old, norm_vec, offset): | @@ -529,3 +539,17 @@ def offset_coordinate(p_old, norm_vec, offset): | ||
529 | """ | 539 | """ |
530 | p_offset = p_old - offset * norm_vec | 540 | p_offset = p_old - offset * norm_vec |
531 | return p_offset | 541 | return p_offset |
542 | + | ||
543 | +class ReceiveCoordinates(threading.Thread): | ||
544 | + def __init__(self, trck_init, trck_id, TrackerCoordinates, event): | ||
545 | + threading.Thread.__init__(self, name='ReceiveCoordinates') | ||
546 | + self.trck_init = trck_init | ||
547 | + self.trck_id = trck_id | ||
548 | + self.event = event | ||
549 | + self.TrackerCoordinates = TrackerCoordinates | ||
550 | + | ||
551 | + def run(self): | ||
552 | + while not self.event.is_set(): | ||
553 | + coord_raw, markers_flag = GetCoordinatesForThread(self.trck_init, self.trck_id, const.DEFAULT_REF_MODE) | ||
554 | + self.TrackerCoordinates.SetCoordinates(coord_raw, markers_flag) | ||
555 | + sleep(const.SLEEP_COORDINATES) | ||
532 | \ No newline at end of file | 556 | \ No newline at end of file |
invesalius/data/coregistration.py
@@ -219,7 +219,7 @@ class CoordinateCorregistrate(threading.Thread): | @@ -219,7 +219,7 @@ class CoordinateCorregistrate(threading.Thread): | ||
219 | else: | 219 | else: |
220 | self.icp, self.m_icp = self.icp_queue.get_nowait() | 220 | self.icp, self.m_icp = self.icp_queue.get_nowait() |
221 | # print(f"Set the coordinate") | 221 | # print(f"Set the coordinate") |
222 | - coord_raw = dco.GetCoordinates(trck_init, trck_id, self.ref_mode_id) | 222 | + coord_raw, markers_flag = self.tracker.TrackerCoordinates.GetCoordinates() |
223 | coord, m_img = corregistrate_object_dynamic(coreg_data, coord_raw, self.ref_mode_id, [self.icp, self.m_icp]) | 223 | coord, m_img = corregistrate_object_dynamic(coreg_data, coord_raw, self.ref_mode_id, [self.icp, self.m_icp]) |
224 | 224 | ||
225 | # XXX: This is not the best place to do the logic related to approaching the target when the | 225 | # XXX: This is not the best place to do the logic related to approaching the target when the |
@@ -294,7 +294,7 @@ class CoordinateCorregistrateNoObject(threading.Thread): | @@ -294,7 +294,7 @@ class CoordinateCorregistrateNoObject(threading.Thread): | ||
294 | self.icp, self.m_icp = self.icp_queue.get_nowait() | 294 | self.icp, self.m_icp = self.icp_queue.get_nowait() |
295 | # print(f"Set the coordinate") | 295 | # print(f"Set the coordinate") |
296 | #print(self.icp, self.m_icp) | 296 | #print(self.icp, self.m_icp) |
297 | - coord_raw = dco.GetCoordinates(trck_init, trck_id, self.ref_mode_id) | 297 | + coord_raw, markers_flag = self.tracker.TrackerCoordinates.GetCoordinates() |
298 | coord, m_img = corregistrate_dynamic(coreg_data, coord_raw, self.ref_mode_id, [self.icp, self.m_icp]) | 298 | coord, m_img = corregistrate_dynamic(coreg_data, coord_raw, self.ref_mode_id, [self.icp, self.m_icp]) |
299 | # print("Coord: ", coord) | 299 | # print("Coord: ", coord) |
300 | m_img_flip = m_img.copy() | 300 | m_img_flip = m_img.copy() |
invesalius/data/viewer_volume.py
@@ -368,7 +368,9 @@ class Viewer(wx.Panel): | @@ -368,7 +368,9 @@ class Viewer(wx.Panel): | ||
368 | 368 | ||
369 | self.interactor.Render() | 369 | self.interactor.Render() |
370 | 370 | ||
371 | - def OnSensors(self, probe_id, ref_id, obj_id=0): | 371 | + def OnSensors(self, markers_flag): |
372 | + probe_id, ref_id, obj_id = markers_flag | ||
373 | + | ||
372 | if not self.probe: | 374 | if not self.probe: |
373 | self.CreateSensorID() | 375 | self.CreateSensorID() |
374 | 376 |
invesalius/gui/dialogs.py
@@ -3648,8 +3648,7 @@ class ICPCorregistrationDialog(wx.Dialog): | @@ -3648,8 +3648,7 @@ class ICPCorregistrationDialog(wx.Dialog): | ||
3648 | import invesalius.project as prj | 3648 | import invesalius.project as prj |
3649 | 3649 | ||
3650 | self.m_change = nav_prop[0] | 3650 | self.m_change = nav_prop[0] |
3651 | - self.tracker_id = nav_prop[1] | ||
3652 | - self.trk_init = nav_prop[2] | 3651 | + self.tracker = nav_prop[1] |
3653 | self.obj_ref_id = 2 | 3652 | self.obj_ref_id = 2 |
3654 | self.obj_name = None | 3653 | self.obj_name = None |
3655 | self.obj_actor = None | 3654 | self.obj_actor = None |
@@ -3805,7 +3804,7 @@ class ICPCorregistrationDialog(wx.Dialog): | @@ -3805,7 +3804,7 @@ class ICPCorregistrationDialog(wx.Dialog): | ||
3805 | self.interactor.Render() | 3804 | self.interactor.Render() |
3806 | 3805 | ||
3807 | def GetCurrentCoord(self): | 3806 | def GetCurrentCoord(self): |
3808 | - coord_raw = dco.GetCoordinates(self.trk_init, self.tracker_id, const.DYNAMIC_REF) | 3807 | + coord_raw, markers_flag = self.tracker.TrackerCoordinates.GetCoordinates() |
3809 | coord, _ = dcr.corregistrate_dynamic((self.m_change, 0), coord_raw, const.DEFAULT_REF_MODE, [None, None]) | 3808 | coord, _ = dcr.corregistrate_dynamic((self.m_change, 0), coord_raw, const.DEFAULT_REF_MODE, [None, None]) |
3810 | return coord[:3] | 3809 | return coord[:3] |
3811 | 3810 |
invesalius/navigation/icp.py
@@ -48,7 +48,7 @@ class ICP(): | @@ -48,7 +48,7 @@ class ICP(): | ||
48 | def OnICP(self, navigation, tracker, m_change): | 48 | def OnICP(self, navigation, tracker, m_change): |
49 | ref_mode_id = navigation.GetReferenceMode() | 49 | ref_mode_id = navigation.GetReferenceMode() |
50 | 50 | ||
51 | - dialog = dlg.ICPCorregistrationDialog(nav_prop=(m_change, tracker.tracker_id, tracker.trk_init, ref_mode_id)) | 51 | + dialog = dlg.ICPCorregistrationDialog(nav_prop=(m_change, tracker, ref_mode_id)) |
52 | 52 | ||
53 | if dialog.ShowModal() == wx.ID_OK: | 53 | if dialog.ShowModal() == wx.ID_OK: |
54 | m_icp, point_coord, transformed_points, prev_error, final_error = dialog.GetValue() | 54 | m_icp, point_coord, transformed_points, prev_error, final_error = dialog.GetValue() |
invesalius/navigation/navigation.py
@@ -255,7 +255,7 @@ class Navigation(): | @@ -255,7 +255,7 @@ class Navigation(): | ||
255 | coreg_data = [m_change, obj_ref_mode] | 255 | coreg_data = [m_change, obj_ref_mode] |
256 | 256 | ||
257 | if self.ref_mode_id: | 257 | if self.ref_mode_id: |
258 | - coord_raw = dco.GetCoordinates(tracker.trk_init, tracker.tracker_id, self.ref_mode_id) | 258 | + coord_raw, markers_flag = tracker.TrackerCoordinates.GetCoordinates() |
259 | else: | 259 | else: |
260 | coord_raw = np.array([None]) | 260 | coord_raw = np.array([None]) |
261 | 261 |
invesalius/navigation/tracker.py
@@ -18,6 +18,7 @@ | @@ -18,6 +18,7 @@ | ||
18 | #-------------------------------------------------------------------------- | 18 | #-------------------------------------------------------------------------- |
19 | 19 | ||
20 | import numpy as np | 20 | import numpy as np |
21 | +import threading | ||
21 | 22 | ||
22 | import invesalius.constants as const | 23 | import invesalius.constants as const |
23 | import invesalius.data.coordinates as dco | 24 | import invesalius.data.coordinates as dco |
@@ -36,6 +37,12 @@ class Tracker(): | @@ -36,6 +37,12 @@ class Tracker(): | ||
36 | 37 | ||
37 | self.tracker_connected = False | 38 | self.tracker_connected = False |
38 | 39 | ||
40 | + self.thread_coord = None | ||
41 | + | ||
42 | + self.event_coord = threading.Event() | ||
43 | + | ||
44 | + self.TrackerCoordinates = dco.TrackerCoordinates() | ||
45 | + | ||
39 | def SetTracker(self, new_tracker): | 46 | def SetTracker(self, new_tracker): |
40 | if new_tracker: | 47 | if new_tracker: |
41 | self.DisconnectTracker() | 48 | self.DisconnectTracker() |
@@ -49,6 +56,9 @@ class Tracker(): | @@ -49,6 +56,9 @@ class Tracker(): | ||
49 | else: | 56 | else: |
50 | self.tracker_id = new_tracker | 57 | self.tracker_id = new_tracker |
51 | self.tracker_connected = True | 58 | self.tracker_connected = True |
59 | + self.thread_coord = dco.ReceiveCoordinates(self.trk_init, self.tracker_id, self.TrackerCoordinates, | ||
60 | + self.event_coord) | ||
61 | + self.thread_coord.start() | ||
52 | 62 | ||
53 | def DisconnectTracker(self): | 63 | def DisconnectTracker(self): |
54 | if self.tracker_connected: | 64 | if self.tracker_connected: |
@@ -62,6 +72,11 @@ class Tracker(): | @@ -62,6 +72,11 @@ class Tracker(): | ||
62 | self.tracker_connected = False | 72 | self.tracker_connected = False |
63 | self.tracker_id = 0 | 73 | self.tracker_id = 0 |
64 | 74 | ||
75 | + if self.thread_coord: | ||
76 | + self.event_coord.set() | ||
77 | + self.thread_coord.join() | ||
78 | + self.event_coord.clear() | ||
79 | + | ||
65 | Publisher.sendMessage('Update status text in GUI', | 80 | Publisher.sendMessage('Update status text in GUI', |
66 | label=_("Tracker disconnected")) | 81 | label=_("Tracker disconnected")) |
67 | print("Tracker disconnected!") | 82 | print("Tracker disconnected!") |
@@ -81,7 +96,7 @@ class Tracker(): | @@ -81,7 +96,7 @@ class Tracker(): | ||
81 | coord_samples = {} | 96 | coord_samples = {} |
82 | 97 | ||
83 | for i in range(n_samples): | 98 | for i in range(n_samples): |
84 | - coord_raw = dco.GetCoordinates(self.trk_init, self.tracker_id, ref_mode_id) | 99 | + coord_raw, markers_flag = self.TrackerCoordinates.GetCoordinates() |
85 | 100 | ||
86 | if ref_mode_id == const.DYNAMIC_REF: | 101 | if ref_mode_id == const.DYNAMIC_REF: |
87 | coord = dco.dynamic_reference_m(coord_raw[0, :], coord_raw[1, :]) | 102 | coord = dco.dynamic_reference_m(coord_raw[0, :], coord_raw[1, :]) |