Commit d133ced30f965e07402c3c96120888cdd616b02c
Committed by
GitHub
1 parent
db47444c
Exists in
master
MOD: Allow selecting COM port when enabling serial port communication (#325)
* CLP: Clean up naming in task_navigator.py Namely, be more specific about the type of trigger input (in this case, the serial port), as nowadays the MIDI input can be used for triggering, as well. * CLP: Remove unused variable 'trigger' from Navigation class * CLP: More clean-up related to serial port communication - Change invesalius.data.trigger to invesalius.data.serial_port_connection - Rename the class TriggerNew to SerialPortConnection - Remove the old, unused Trigger class - Rename a couple of variables in SerialPortConnection class - Replace the incorrect docstring for SerialPortConnection class with a brief but more accurate docstring. * CLP: More clean-up in SerialPortConnection - Remove commented out code - Remove some blank lines from function definitions - Do not import sleep from time library, but instead use time.sleep * MOD: Allow selecting COM port when enabling serial port communication
Showing
3 changed files
with
140 additions
and
204 deletions
Show diff stats
@@ -0,0 +1,79 @@ | @@ -0,0 +1,79 @@ | ||
1 | +#-------------------------------------------------------------------------- | ||
2 | +# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas | ||
3 | +# Copyright: (C) 2001 Centro de Pesquisas Renato Archer | ||
4 | +# Homepage: http://www.softwarepublico.gov.br | ||
5 | +# Contact: invesalius@cti.gov.br | ||
6 | +# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) | ||
7 | +#-------------------------------------------------------------------------- | ||
8 | +# Este programa e software livre; voce pode redistribui-lo e/ou | ||
9 | +# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme | ||
10 | +# publicada pela Free Software Foundation; de acordo com a versao 2 | ||
11 | +# da Licenca. | ||
12 | +# | ||
13 | +# Este programa eh distribuido na expectativa de ser util, mas SEM | ||
14 | +# QUALQUER GARANTIA; sem mesmo a garantia implicita de | ||
15 | +# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM | ||
16 | +# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais | ||
17 | +# detalhes. | ||
18 | +#-------------------------------------------------------------------------- | ||
19 | + | ||
20 | +import threading | ||
21 | +import time | ||
22 | + | ||
23 | +import wx | ||
24 | +from invesalius.pubsub import pub as Publisher | ||
25 | + | ||
26 | + | ||
27 | +class SerialPortConnection(threading.Thread): | ||
28 | + | ||
29 | + def __init__(self, port, serial_port_queue, event, sleep_nav): | ||
30 | + """ | ||
31 | + Thread created to communicate using the serial port to interact with software during neuronavigation. | ||
32 | + """ | ||
33 | + threading.Thread.__init__(self, name='Serial port') | ||
34 | + | ||
35 | + self.connection = None | ||
36 | + self.stylusplh = False | ||
37 | + | ||
38 | + self.port = port | ||
39 | + self.serial_port_queue = serial_port_queue | ||
40 | + self.event = event | ||
41 | + self.sleep_nav = sleep_nav | ||
42 | + | ||
43 | + def Enabled(self): | ||
44 | + return self.port is not None | ||
45 | + | ||
46 | + def Connect(self): | ||
47 | + if self.port is None: | ||
48 | + print("Serial port init error: COM port is unset.") | ||
49 | + return | ||
50 | + try: | ||
51 | + import serial | ||
52 | + self.connection = serial.Serial(self.port, baudrate=115200, timeout=0) | ||
53 | + print("Connection to port {} opened.".format(self.port)) | ||
54 | + except: | ||
55 | + print("Serial port init error: Connecting to port {} failed.".format(self.port)) | ||
56 | + | ||
57 | + def run(self): | ||
58 | + while not self.event.is_set(): | ||
59 | + trigger_on = False | ||
60 | + try: | ||
61 | + self.connection.write(b'0') | ||
62 | + time.sleep(0.3) | ||
63 | + | ||
64 | + lines = self.connection.readlines() | ||
65 | + if lines: | ||
66 | + trigger_on = True | ||
67 | + | ||
68 | + if self.stylusplh: | ||
69 | + trigger_on = True | ||
70 | + self.stylusplh = False | ||
71 | + | ||
72 | + self.serial_port_queue.put_nowait(trigger_on) | ||
73 | + time.sleep(self.sleep_nav) | ||
74 | + except: | ||
75 | + print("Trigger not read, error") | ||
76 | + else: | ||
77 | + if self.connection: | ||
78 | + self.connection.close() | ||
79 | + print("Connection to port {} closed.".format(self.port)) |
invesalius/data/trigger.py
@@ -1,168 +0,0 @@ | @@ -1,168 +0,0 @@ | ||
1 | -#-------------------------------------------------------------------------- | ||
2 | -# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas | ||
3 | -# Copyright: (C) 2001 Centro de Pesquisas Renato Archer | ||
4 | -# Homepage: http://www.softwarepublico.gov.br | ||
5 | -# Contact: invesalius@cti.gov.br | ||
6 | -# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) | ||
7 | -#-------------------------------------------------------------------------- | ||
8 | -# Este programa e software livre; voce pode redistribui-lo e/ou | ||
9 | -# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme | ||
10 | -# publicada pela Free Software Foundation; de acordo com a versao 2 | ||
11 | -# da Licenca. | ||
12 | -# | ||
13 | -# Este programa eh distribuido na expectativa de ser util, mas SEM | ||
14 | -# QUALQUER GARANTIA; sem mesmo a garantia implicita de | ||
15 | -# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM | ||
16 | -# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais | ||
17 | -# detalhes. | ||
18 | -#-------------------------------------------------------------------------- | ||
19 | - | ||
20 | -import threading | ||
21 | -from time import sleep | ||
22 | - | ||
23 | -import wx | ||
24 | -from invesalius.pubsub import pub as Publisher | ||
25 | - | ||
26 | - | ||
27 | -class Trigger(threading.Thread): | ||
28 | - """ | ||
29 | - Thread created to use external trigger to interact with software during neuronavigation | ||
30 | - """ | ||
31 | - | ||
32 | - def __init__(self, nav_id): | ||
33 | - threading.Thread.__init__(self) | ||
34 | - self.trigger_init = None | ||
35 | - self.stylusplh = False | ||
36 | - self.COM = False | ||
37 | - self.nav_id = nav_id | ||
38 | - self.__bind_events() | ||
39 | - try: | ||
40 | - import serial | ||
41 | - | ||
42 | - self.trigger_init = serial.Serial('COM5', baudrate=115200, timeout=0) | ||
43 | - self.COM = True | ||
44 | - | ||
45 | - except: | ||
46 | - #wx.MessageBox(_('Connection with port COM1 failed'), _('Communication error'), wx.OK | wx.ICON_ERROR) | ||
47 | - print("Trigger init error: Connection with port COM1 failed") | ||
48 | - self.COM = False | ||
49 | - | ||
50 | - self._pause_ = False | ||
51 | - self.start() | ||
52 | - | ||
53 | - def __bind_events(self): | ||
54 | - Publisher.subscribe(self.OnStylusPLH, 'PLH Stylus Button On') | ||
55 | - | ||
56 | - def OnStylusPLH(self): | ||
57 | - self.stylusplh = True | ||
58 | - | ||
59 | - def stop(self): | ||
60 | - self._pause_ = True | ||
61 | - | ||
62 | - def run(self): | ||
63 | - while self.nav_id: | ||
64 | - if self.COM: | ||
65 | - self.trigger_init.write(b'0') | ||
66 | - sleep(0.3) | ||
67 | - lines = self.trigger_init.readlines() | ||
68 | - # Following lines can simulate a trigger in 3 sec repetitions | ||
69 | - # sleep(3) | ||
70 | - # lines = True | ||
71 | - if lines: | ||
72 | - wx.CallAfter(Publisher.sendMessage, 'Create marker') | ||
73 | - sleep(0.5) | ||
74 | - | ||
75 | - if self.stylusplh: | ||
76 | - wx.CallAfter(Publisher.sendMessage, 'Create marker') | ||
77 | - sleep(0.5) | ||
78 | - self.stylusplh = False | ||
79 | - | ||
80 | - sleep(0.175) | ||
81 | - if self._pause_: | ||
82 | - if self.trigger_init: | ||
83 | - self.trigger_init.close() | ||
84 | - return | ||
85 | - | ||
86 | - | ||
87 | -class TriggerNew(threading.Thread): | ||
88 | - | ||
89 | - def __init__(self, trigger_queue, event, sle): | ||
90 | - """Class (threading) to compute real time tractography data for visualization in a single loop. | ||
91 | - | ||
92 | - Different than ComputeTractsThread because it does not keep adding tracts to the bundle until maximum, | ||
93 | - is reached. It actually compute all requested tracts at once. (Might be deleted in the future)! | ||
94 | - Tracts are computed using the Trekker library by Baran Aydogan (https://dmritrekker.github.io/) | ||
95 | - For VTK visualization, each tract (fiber) is a constructed as a tube and many tubes combined in one | ||
96 | - vtkMultiBlockDataSet named as a branch. Several branches are combined in another vtkMultiBlockDataSet named as | ||
97 | - bundle, to obtain fast computation and visualization. The bundle dataset is mapped to a single vtkActor. | ||
98 | - Mapper and Actor are computer in the data/viewer_volume.py module for easier handling in the invesalius 3D scene. | ||
99 | - | ||
100 | - Sleep function in run method is used to avoid blocking GUI and more fluent, real-time navigation | ||
101 | - | ||
102 | - :param inp: List of inputs: trekker instance, affine numpy array, seed_offset, seed_radius, n_threads | ||
103 | - :type inp: list | ||
104 | - :param affine_vtk: Affine matrix in vtkMatrix4x4 instance to update objects position in 3D scene | ||
105 | - :type affine_vtk: vtkMatrix4x4 | ||
106 | - :param coord_queue: Queue instance that manage coordinates read from tracking device and coregistered | ||
107 | - :type coord_queue: queue.Queue | ||
108 | - :param visualization_queue: Queue instance that manage coordinates to be visualized | ||
109 | - :type visualization_queue: queue.Queue | ||
110 | - :param event: Threading event to coordinate when tasks as done and allow UI release | ||
111 | - :type event: threading.Event | ||
112 | - :param sle: Sleep pause in seconds | ||
113 | - :type sle: float | ||
114 | - """ | ||
115 | - | ||
116 | - threading.Thread.__init__(self, name='Trigger') | ||
117 | - | ||
118 | - self.trigger_init = None | ||
119 | - self.stylusplh = False | ||
120 | - # self.COM = False | ||
121 | - # self.__bind_events() | ||
122 | - try: | ||
123 | - import serial | ||
124 | - | ||
125 | - self.trigger_init = serial.Serial('COM5', baudrate=115200, timeout=0) | ||
126 | - # self.COM = True | ||
127 | - | ||
128 | - except: | ||
129 | - #wx.MessageBox(_('Connection with port COM1 failed'), _('Communication error'), wx.OK | wx.ICON_ERROR) | ||
130 | - print("Trigger init error: Connection with port COM failed") | ||
131 | - # self.COM = False | ||
132 | - pass | ||
133 | - | ||
134 | - # self.coord_queue = coord_queue | ||
135 | - self.trigger_queue = trigger_queue | ||
136 | - self.event = event | ||
137 | - self.sle = sle | ||
138 | - | ||
139 | - def run(self): | ||
140 | - | ||
141 | - while not self.event.is_set(): | ||
142 | - trigger_on = False | ||
143 | - try: | ||
144 | - self.trigger_init.write(b'0') | ||
145 | - sleep(0.3) | ||
146 | - lines = self.trigger_init.readlines() | ||
147 | - # Following lines can simulate a trigger in 3 sec repetitions | ||
148 | - # sleep(3) | ||
149 | - # lines = True | ||
150 | - if lines: | ||
151 | - trigger_on = True | ||
152 | - # wx.CallAfter(Publisher.sendMessage, 'Create marker') | ||
153 | - | ||
154 | - if self.stylusplh: | ||
155 | - trigger_on = True | ||
156 | - # wx.CallAfter(Publisher.sendMessage, 'Create marker') | ||
157 | - self.stylusplh = False | ||
158 | - | ||
159 | - self.trigger_queue.put_nowait(trigger_on) | ||
160 | - sleep(self.sle) | ||
161 | - | ||
162 | - except: | ||
163 | - print("Trigger not read, error") | ||
164 | - pass | ||
165 | - | ||
166 | - else: | ||
167 | - if self.trigger_init: | ||
168 | - self.trigger_init.close() |
invesalius/gui/task_navigator.py
@@ -54,11 +54,11 @@ if has_trekker: | @@ -54,11 +54,11 @@ if has_trekker: | ||
54 | 54 | ||
55 | import invesalius.data.coordinates as dco | 55 | import invesalius.data.coordinates as dco |
56 | import invesalius.data.coregistration as dcr | 56 | import invesalius.data.coregistration as dcr |
57 | +import invesalius.data.serial_port_connection as spc | ||
57 | import invesalius.data.slice_ as sl | 58 | import invesalius.data.slice_ as sl |
58 | import invesalius.data.trackers as dt | 59 | import invesalius.data.trackers as dt |
59 | import invesalius.data.tractography as dti | 60 | import invesalius.data.tractography as dti |
60 | import invesalius.data.transformations as tr | 61 | import invesalius.data.transformations as tr |
61 | -import invesalius.data.trigger as trig | ||
62 | import invesalius.data.record_coords as rec | 62 | 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 |
@@ -215,13 +215,13 @@ class InnerFoldPanel(wx.Panel): | @@ -215,13 +215,13 @@ class InnerFoldPanel(wx.Panel): | ||
215 | checkcamera.Bind(wx.EVT_CHECKBOX, self.OnVolumeCamera) | 215 | checkcamera.Bind(wx.EVT_CHECKBOX, self.OnVolumeCamera) |
216 | self.checkcamera = checkcamera | 216 | self.checkcamera = checkcamera |
217 | 217 | ||
218 | - # Check box for trigger monitoring to create markers from serial port | ||
219 | - tooltip = wx.ToolTip(_("Enable external trigger for creating markers")) | ||
220 | - checktrigger = wx.CheckBox(self, -1, _('Ext. trigger')) | ||
221 | - checktrigger.SetToolTip(tooltip) | ||
222 | - checktrigger.SetValue(False) | ||
223 | - checktrigger.Bind(wx.EVT_CHECKBOX, partial(self.OnExternalTrigger, ctrl=checktrigger)) | ||
224 | - self.checktrigger = checktrigger | 218 | + # Check box to create markers from serial port |
219 | + tooltip = wx.ToolTip(_("Enable serial port communication for creating markers")) | ||
220 | + checkbox_serial_port = wx.CheckBox(self, -1, _('Serial port')) | ||
221 | + checkbox_serial_port.SetToolTip(tooltip) | ||
222 | + checkbox_serial_port.SetValue(False) | ||
223 | + checkbox_serial_port.Bind(wx.EVT_CHECKBOX, partial(self.OnEnableSerialPort, ctrl=checkbox_serial_port)) | ||
224 | + self.checkbox_serial_port = checkbox_serial_port | ||
225 | 225 | ||
226 | # Check box for object position and orientation update in volume rendering during navigation | 226 | # Check box for object position and orientation update in volume rendering during navigation |
227 | tooltip = wx.ToolTip(_("Show and track TMS coil")) | 227 | tooltip = wx.ToolTip(_("Show and track TMS coil")) |
@@ -234,12 +234,12 @@ class InnerFoldPanel(wx.Panel): | @@ -234,12 +234,12 @@ class InnerFoldPanel(wx.Panel): | ||
234 | 234 | ||
235 | # if sys.platform != 'win32': | 235 | # if sys.platform != 'win32': |
236 | self.checkcamera.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) | 236 | self.checkcamera.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) |
237 | - checktrigger.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) | 237 | + checkbox_serial_port.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) |
238 | checkobj.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) | 238 | checkobj.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) |
239 | 239 | ||
240 | line_sizer = wx.BoxSizer(wx.HORIZONTAL) | 240 | line_sizer = wx.BoxSizer(wx.HORIZONTAL) |
241 | line_sizer.Add(checkcamera, 0, wx.ALIGN_LEFT | wx.RIGHT | wx.LEFT, 5) | 241 | line_sizer.Add(checkcamera, 0, wx.ALIGN_LEFT | wx.RIGHT | wx.LEFT, 5) |
242 | - line_sizer.Add(checktrigger, 0, wx.ALIGN_CENTER) | 242 | + line_sizer.Add(checkbox_serial_port, 0, wx.ALIGN_CENTER) |
243 | line_sizer.Add(checkobj, 0, wx.RIGHT | wx.LEFT, 5) | 243 | line_sizer.Add(checkobj, 0, wx.RIGHT | wx.LEFT, 5) |
244 | line_sizer.Fit(self) | 244 | line_sizer.Fit(self) |
245 | 245 | ||
@@ -270,15 +270,22 @@ class InnerFoldPanel(wx.Panel): | @@ -270,15 +270,22 @@ class InnerFoldPanel(wx.Panel): | ||
270 | 270 | ||
271 | def OnCheckStatus(self, nav_status, vis_status): | 271 | def OnCheckStatus(self, nav_status, vis_status): |
272 | if nav_status: | 272 | if nav_status: |
273 | - self.checktrigger.Enable(False) | 273 | + self.checkbox_serial_port.Enable(False) |
274 | self.checkobj.Enable(False) | 274 | self.checkobj.Enable(False) |
275 | else: | 275 | else: |
276 | - self.checktrigger.Enable(True) | 276 | + self.checkbox_serial_port.Enable(True) |
277 | if self.track_obj: | 277 | if self.track_obj: |
278 | self.checkobj.Enable(True) | 278 | self.checkobj.Enable(True) |
279 | 279 | ||
280 | - def OnExternalTrigger(self, evt, ctrl): | ||
281 | - Publisher.sendMessage('Update trigger state', trigger_state=ctrl.GetValue()) | 280 | + def OnEnableSerialPort(self, evt, ctrl): |
281 | + com_port = None | ||
282 | + if ctrl.GetValue(): | ||
283 | + from wx import ID_OK | ||
284 | + dlg_port = dlg.SetCOMport() | ||
285 | + if dlg_port.ShowModal() == ID_OK: | ||
286 | + com_port = dlg_port.GetValue() | ||
287 | + | ||
288 | + Publisher.sendMessage('Update serial port', serial_port=com_port) | ||
282 | 289 | ||
283 | def OnShowObject(self, evt=None, flag=None, obj_name=None, polydata=None): | 290 | def OnShowObject(self, evt=None, flag=None, obj_name=None, polydata=None): |
284 | if not evt: | 291 | if not evt: |
@@ -307,8 +314,6 @@ class Navigation(): | @@ -307,8 +314,6 @@ class Navigation(): | ||
307 | self.correg = None | 314 | self.correg = None |
308 | self.current_coord = 0, 0, 0 | 315 | self.current_coord = 0, 0, 0 |
309 | self.target = None | 316 | self.target = None |
310 | - self.trigger = None | ||
311 | - self.trigger_state = False | ||
312 | self.obj_reg = None | 317 | self.obj_reg = None |
313 | self.track_obj = False | 318 | self.track_obj = False |
314 | self.m_change = None | 319 | self.m_change = None |
@@ -318,7 +323,7 @@ class Navigation(): | @@ -318,7 +323,7 @@ class Navigation(): | ||
318 | self.coord_queue = QueueCustom(maxsize=1) | 323 | self.coord_queue = QueueCustom(maxsize=1) |
319 | self.icp_queue = QueueCustom(maxsize=1) | 324 | self.icp_queue = QueueCustom(maxsize=1) |
320 | # self.visualization_queue = QueueCustom(maxsize=1) | 325 | # self.visualization_queue = QueueCustom(maxsize=1) |
321 | - self.trigger_queue = QueueCustom(maxsize=1) | 326 | + self.serial_port_queue = QueueCustom(maxsize=1) |
322 | self.coord_tracts_queue = QueueCustom(maxsize=1) | 327 | self.coord_tracts_queue = QueueCustom(maxsize=1) |
323 | self.tracts_queue = QueueCustom(maxsize=1) | 328 | self.tracts_queue = QueueCustom(maxsize=1) |
324 | 329 | ||
@@ -335,6 +340,17 @@ class Navigation(): | @@ -335,6 +340,17 @@ class Navigation(): | ||
335 | self.seed_radius = const.SEED_RADIUS | 340 | self.seed_radius = const.SEED_RADIUS |
336 | self.sleep_nav = const.SLEEP_NAVIGATION | 341 | self.sleep_nav = const.SLEEP_NAVIGATION |
337 | 342 | ||
343 | + # Serial port | ||
344 | + self.serial_port = None | ||
345 | + self.serial_port_connection = None | ||
346 | + | ||
347 | + def UpdateSleep(self, sleep): | ||
348 | + self.sleep_nav = sleep | ||
349 | + self.serial_port_connection.sleep_nav = sleep | ||
350 | + | ||
351 | + def SerialPortEnabled(self): | ||
352 | + return self.serial_port is not None | ||
353 | + | ||
338 | def SetImageFiducial(self, fiducial_index, coord): | 354 | def SetImageFiducial(self, fiducial_index, coord): |
339 | self.image_fiducials[fiducial_index, :] = coord | 355 | self.image_fiducials[fiducial_index, :] = coord |
340 | 356 | ||
@@ -365,8 +381,8 @@ class Navigation(): | @@ -365,8 +381,8 @@ class Navigation(): | ||
365 | if self.event.is_set(): | 381 | if self.event.is_set(): |
366 | self.event.clear() | 382 | self.event.clear() |
367 | 383 | ||
368 | - vis_components = [self.trigger_state, self.view_tracts, self.peel_loaded] | ||
369 | - vis_queues = [self.coord_queue, self.trigger_queue, self.tracts_queue, self.icp_queue] | 384 | + vis_components = [self.SerialPortEnabled(), self.view_tracts, self.peel_loaded] |
385 | + vis_queues = [self.coord_queue, self.serial_port_queue, self.tracts_queue, self.icp_queue] | ||
370 | 386 | ||
371 | Publisher.sendMessage("Navigation status", nav_status=True, vis_status=vis_components) | 387 | Publisher.sendMessage("Navigation status", nav_status=True, vis_status=vis_components) |
372 | 388 | ||
@@ -413,10 +429,16 @@ class Navigation(): | @@ -413,10 +429,16 @@ class Navigation(): | ||
413 | self.event, self.sleep_nav)) | 429 | self.event, self.sleep_nav)) |
414 | 430 | ||
415 | if not errors: | 431 | if not errors: |
416 | - #TODO: Test the trigger thread | ||
417 | - if self.trigger_state: | ||
418 | - # self.trigger = trig.Trigger(nav_id) | ||
419 | - jobs_list.append(trig.TriggerNew(self.trigger_queue, self.event, self.sleep_nav)) | 432 | + #TODO: Test the serial port thread |
433 | + if self.SerialPortEnabled(): | ||
434 | + self.serial_port_connection = spc.SerialPortConnection( | ||
435 | + self.serial_port, | ||
436 | + self.serial_port_queue, | ||
437 | + self.event, | ||
438 | + self.sleep_nav, | ||
439 | + ) | ||
440 | + self.serial_port_connection.Connect() | ||
441 | + jobs_list.append(self.serial_port_connection) | ||
420 | 442 | ||
421 | if self.view_tracts: | 443 | if self.view_tracts: |
422 | # initialize Trekker parameters | 444 | # initialize Trekker parameters |
@@ -450,9 +472,12 @@ class Navigation(): | @@ -450,9 +472,12 @@ class Navigation(): | ||
450 | self.coord_queue.clear() | 472 | self.coord_queue.clear() |
451 | self.coord_queue.join() | 473 | self.coord_queue.join() |
452 | 474 | ||
453 | - if self.trigger_state: | ||
454 | - self.trigger_queue.clear() | ||
455 | - self.trigger_queue.join() | 475 | + if self.SerialPortEnabled(): |
476 | + self.serial_port_connection.join() | ||
477 | + | ||
478 | + self.serial_port_queue.clear() | ||
479 | + self.serial_port_queue.join() | ||
480 | + | ||
456 | if self.view_tracts: | 481 | if self.view_tracts: |
457 | self.coord_tracts_queue.clear() | 482 | self.coord_tracts_queue.clear() |
458 | self.coord_tracts_queue.join() | 483 | self.coord_tracts_queue.join() |
@@ -460,7 +485,7 @@ class Navigation(): | @@ -460,7 +485,7 @@ class Navigation(): | ||
460 | self.tracts_queue.clear() | 485 | self.tracts_queue.clear() |
461 | self.tracts_queue.join() | 486 | self.tracts_queue.join() |
462 | 487 | ||
463 | - vis_components = [self.trigger_state, self.view_tracts, self.peel_loaded] | 488 | + vis_components = [self.serial_port_connection.Enabled(), self.view_tracts, self.peel_loaded] |
464 | Publisher.sendMessage("Navigation status", nav_status=False, vis_status=vis_components) | 489 | Publisher.sendMessage("Navigation status", nav_status=False, vis_status=vis_components) |
465 | 490 | ||
466 | 491 | ||
@@ -800,7 +825,7 @@ class NeuronavigationPanel(wx.Panel): | @@ -800,7 +825,7 @@ class NeuronavigationPanel(wx.Panel): | ||
800 | Publisher.subscribe(self.LoadImageFiducials, 'Load image fiducials') | 825 | Publisher.subscribe(self.LoadImageFiducials, 'Load image fiducials') |
801 | Publisher.subscribe(self.SetImageFiducial, 'Set image fiducial') | 826 | Publisher.subscribe(self.SetImageFiducial, 'Set image fiducial') |
802 | Publisher.subscribe(self.SetTrackerFiducial, 'Set tracker fiducial') | 827 | Publisher.subscribe(self.SetTrackerFiducial, 'Set tracker fiducial') |
803 | - Publisher.subscribe(self.UpdateTriggerState, 'Update trigger state') | 828 | + Publisher.subscribe(self.UpdateSerialPort, 'Update serial port') |
804 | Publisher.subscribe(self.UpdateTrackObjectState, 'Update track object state') | 829 | Publisher.subscribe(self.UpdateTrackObjectState, 'Update track object state') |
805 | Publisher.subscribe(self.UpdateImageCoordinates, 'Set cross focal point') | 830 | Publisher.subscribe(self.UpdateImageCoordinates, 'Set cross focal point') |
806 | Publisher.subscribe(self.OnDisconnectTracker, 'Disconnect tracker') | 831 | Publisher.subscribe(self.OnDisconnectTracker, 'Disconnect tracker') |
@@ -887,7 +912,7 @@ class NeuronavigationPanel(wx.Panel): | @@ -887,7 +912,7 @@ class NeuronavigationPanel(wx.Panel): | ||
887 | self.navigation.seed_radius = data | 912 | self.navigation.seed_radius = data |
888 | 913 | ||
889 | def UpdateSleep(self, data): | 914 | def UpdateSleep(self, data): |
890 | - self.navigation.sleep_nav = data | 915 | + self.navigation.UpdateSleep(data) |
891 | 916 | ||
892 | def UpdateNumberThreads(self, data): | 917 | def UpdateNumberThreads(self, data): |
893 | self.navigation.n_threads = data | 918 | self.navigation.n_threads = data |
@@ -919,8 +944,8 @@ class NeuronavigationPanel(wx.Panel): | @@ -919,8 +944,8 @@ class NeuronavigationPanel(wx.Panel): | ||
919 | def UpdateTrackObjectState(self, evt=None, flag=None, obj_name=None, polydata=None): | 944 | def UpdateTrackObjectState(self, evt=None, flag=None, obj_name=None, polydata=None): |
920 | self.navigation.track_obj = flag | 945 | self.navigation.track_obj = flag |
921 | 946 | ||
922 | - def UpdateTriggerState(self, trigger_state): | ||
923 | - self.navigation.trigger_state = trigger_state | 947 | + def UpdateSerialPort(self, serial_port): |
948 | + self.navigation.serial_port = serial_port | ||
924 | 949 | ||
925 | def ResetICP(self): | 950 | def ResetICP(self): |
926 | self.icp.ResetICP() | 951 | self.icp.ResetICP() |
@@ -2281,8 +2306,8 @@ class UpdateNavigationScene(threading.Thread): | @@ -2281,8 +2306,8 @@ class UpdateNavigationScene(threading.Thread): | ||
2281 | """ | 2306 | """ |
2282 | 2307 | ||
2283 | threading.Thread.__init__(self, name='UpdateScene') | 2308 | threading.Thread.__init__(self, name='UpdateScene') |
2284 | - self.trigger_state, self.view_tracts, self.peel_loaded = vis_components | ||
2285 | - self.coord_queue, self.trigger_queue, self.tracts_queue, self.icp_queue = vis_queues | 2309 | + self.serial_port_enabled, self.view_tracts, self.peel_loaded = vis_components |
2310 | + self.coord_queue, self.serial_port_queue, self.tracts_queue, self.icp_queue = vis_queues | ||
2286 | self.sle = sle | 2311 | self.sle = sle |
2287 | self.event = event | 2312 | self.event = event |
2288 | 2313 | ||
@@ -2306,11 +2331,11 @@ class UpdateNavigationScene(threading.Thread): | @@ -2306,11 +2331,11 @@ class UpdateNavigationScene(threading.Thread): | ||
2306 | # wx.CallAfter(Publisher.sendMessage, 'Update marker offset', coord_offset=coord_offset) | 2331 | # wx.CallAfter(Publisher.sendMessage, 'Update marker offset', coord_offset=coord_offset) |
2307 | self.tracts_queue.task_done() | 2332 | self.tracts_queue.task_done() |
2308 | 2333 | ||
2309 | - if self.trigger_state: | ||
2310 | - trigger_on = self.trigger_queue.get_nowait() | 2334 | + if self.serial_port_enabled: |
2335 | + trigger_on = self.serial_port_queue.get_nowait() | ||
2311 | if trigger_on: | 2336 | if trigger_on: |
2312 | wx.CallAfter(Publisher.sendMessage, 'Create marker') | 2337 | wx.CallAfter(Publisher.sendMessage, 'Create marker') |
2313 | - self.trigger_queue.task_done() | 2338 | + self.serial_port_queue.task_done() |
2314 | 2339 | ||
2315 | #TODO: If using the view_tracts substitute the raw coord from the offset coordinate, so the user | 2340 | #TODO: If using the view_tracts substitute the raw coord from the offset coordinate, so the user |
2316 | # see the red cross in the position of the offset marker | 2341 | # see the red cross in the position of the offset marker |