Reputation: 1
I am currently working on developing a utility for visualizing data collection. I have created a PyQt5 GUI, and I am using the vtk library to visualize live data from an external source. My current organizational structure is as follows:
initialize the GUI and all widgets, layouts, etc. The central widget of this GUI is a QVTKRenderWindowInteractor. I then add all of the necessary VTK actors, mappers, etc. to the renderer.
After the GUI has been initialized, I create an instance of a QThread called ContinuousDataThread, connect it to the slot function in the GUI, and start the thread. This thread is responsible for continuously pulling data from an external source, and updating the main GUI with processed data via a signal/slot relationship.
As the data is sent back to the GUI, the VTK render window is updated via the slot function to reflect the live data.
This approach works perfectly for the vast majority of the time that the GUI is being used. However, in certain instances, interacting with other GUI elements seems to break the connection between the thread and the GUI. This leads to a laggy VTK render window and live data is no longer being continuously transmitted. The GUI does not freeze up or quit, and no errors are thrown anywhere in the process. This issue is not repeatable for any singular GUI element interaction, but rather seemingly random. I believe this may be due to a timing/synchronization issue, but I am not quite sure how to solve this. Below is the code for the thread:
class ContinuousDataThread(QThread):
angle_signal = pyqtSignal(list)
def __init__(self, neok, kdl_packet):
super().__init__()
self.nc = neok
self.tracker_kdl = kdl_packet[0]
self.schunk_kdl = kdl_packet[1]
self.data_packet = None
def run(self):
# pull data continuously from source
while True:
data = self.nc.data
pt_angles, ga_angles = self.get_angles(data)
pt_coords, ga_coords = self.calculate_new_joint_locations(pt_angles, ga_angles)
self.data_packet = [pt_coords, ga_coords]
self.report_angles()
time.sleep(0.025)
def get_angles(self, task):
api_data = task
while api_data is None:
api_data = task
pt_angles = []
ga_angles = []
for i in getattr(api_data, 'tracker_angles'):
pt_angles.append(i)
for i in getattr(api_data, 'guidearm_angles'):
ga_angles.append(i)
return pt_angles, ga_angles
def calculate_new_joint_locations(self, pt_angles, ga_angles):
pt_matrices = Kinematics.FW_Kinematics_Matrices(self.tracker_kdl, pt_angles)
ga_matrices = Kinematics.FW_Kinematics_Matrices(self.schunk_kdl, ga_angles)
pt_joint_coordinates = []
ga_joint_coordinates = []
# update the coordinates of each pt joint
for matrix in pt_matrices:
pt_joint_coordinates.append(matrix[0:3, 3])
# update the coordinates of each ga joint
for matrix in ga_matrices:
ga_joint_coordinates.append(matrix[0:3, 3])
return pt_joint_coordinates, ga_joint_coordinates
def report_angles(self):
self.angle_signal.emit(self.data_packet)
I have tried offloading the majority of the data processing to the QThread to prevent delays in the main GUI that could lead to another signal being sent before processing is done. I have also increased the time.sleep() time inside the run() function of the QThread, and although this seems to decrease the likliness of this issue, it does not prevent it entirely, and also leads to a slower refresh rate on the VTK render window. I have also tried to keep track of the status of the ContinuousDataThread, but even after experiencing the lack of communication and VTK window glitches, .isrunning() still reports True.
Upvotes: 0
Views: 204