def _enable_tools(self): if not self._device: raise ValueError('enable tools called with no NDI device') if not self._tracker_type == "dummy": ndicapy.ndiCommand(self._device, "PHSR:03") number_of_tools = ndicapy.ndiGetPHSRNumberOfHandles(self._device) for tool_index in range(number_of_tools): port_handle = ndicapy.ndiGetPHSRHandle(self._device, tool_index) port_handle_already_present = False for tool in self._tool_descriptors: if tool.get("port handle") == port_handle: port_handle_already_present = True break if not port_handle_already_present: self._tool_descriptors.append({ "description": tool_index, "port handle": port_handle, "c_str port handle": int2byte(port_handle) }) mode = 'D' ndicapy.ndiCommand(self._device, "PENA:{0:02x}{1}".format(port_handle, mode)) self._check_for_errors( 'Enabling port handle {}.'.format(port_handle))
def stop_tracking(self): """ Tells the NDI devices to stop tracking. :raises Exception: ValueError """ ndicapy.ndiCommand(self._device, 'TSTOP:') self._check_for_errors('stopping tracking.') self._state = 'ready'
def start_tracking(self): """ Tells the NDI devices to start tracking. :raises Exception: ValueError """ if self._state != 'ready': raise ValueError("""Called start tracking before device ready, try calling connect first""") ndicapy.ndiCommand(self._device, 'TSTART:') self._check_for_errors('starting tracking.') self._state = 'tracking'
def _initialise_ports(self): """Initialises each port in the list of tool descriptors""" if not self._device: raise ValueError('init ports called with no NDI device') if not self._tracker_type == "dummy": ndicapy.ndiCommand(self._device, 'PHSR:02') for tool in self._tool_descriptors: ndicapy.ndiCommand( self._device, "PINIT:{0:02x}".format(tool.get("port handle"))) self._check_for_errors( 'Initialising port handle {0:02x}.'.format( tool.get("port handle")))
def _read_sroms_from_file(self): if not self._device: raise ValueError('read srom called with no NDI device') if self._state == "tracking": self.stop_tracking() #free ports that are waiting to be freed ndicapy.ndiCommand(self._device, 'PHSR:01') number_of_tools = ndicapy.ndiGetPHSRNumberOfHandles(self._device) for tool_index in range(number_of_tools): port_handle = ndicapy.ndiGetPHRQHandle(self._device, tool_index) ndicapy.ndiCommand(self._device, "PHF:{0:02x}".format(port_handle)) self._check_for_errors( 'freeing port handle {0:02x}.'.format(tool_index)) for tool in self._tool_descriptors: ndicapy.ndiCommand(self._device, 'PHRQ:*********1****') port_handle = ndicapy.ndiGetPHRQHandle(self._device) tool.update({"port handle": port_handle}) if self._tracker_type == "aurora": tool.update({"c_str port handle": str(port_handle).encode()}) else: tool.update({"c_str port handle": int2byte(port_handle)}) self._check_for_errors( 'getting srom file port handle {}.'.format(port_handle)) ndicapy.ndiPVWRFromFile(self._device, port_handle, tool.get("description")) self._check_for_errors( 'setting srom file port handle {}.'.format(port_handle)) ndicapy.ndiCommand(self._device, 'PHSR:01')
def _connect_network(self, configuration): #try and ping first to save time with timeouts param = '-n' if system().lower() == 'windows' else '-c' ip_address = configuration.get("ip address") port = configuration.get("port") if call(['ping', param, '1', ip_address]) == 0: self._device = ndicapy.ndiOpenNetwork(ip_address, port) else: raise IOError('Could not find a device at {}'.format(ip_address)) if not self._device: raise IOError( 'Could not connect to network NDI device at {}'.format( ip_address)) ndicapy.ndiCommand(self._device, 'INIT:') self._check_for_errors('Sending INIT command')
def _connect_serial(self, name): """ Attempts to open the serial port with name name :raises: IOError if connection fails """ self._device = ndicapy.ndiOpen(name) if not self._device: raise IOError( 'Could not connect to serial NDI device at {}'.format(name)) ndicapy.ndiCommand(self._device, 'INIT:') self._check_for_errors('Sending INIT command') ndicapy.ndiCommand( self._device, 'COMM:{:d}{:03d}{:d}'.format(ndicapy.NDI_115200, ndicapy.NDI_8N1, ndicapy.NDI_NOHANDSHAKE))
def _find_wired_ports(self): """For systems with wired tools, gets the number of tools plugged in and sticks them in the tool descriptors list""" if not self._device: raise ValueError('find wired ports called with no NDI device') ndicapy.ndiCommand(self._device, 'PHSR:02') number_of_tools = ndicapy.ndiGetPHSRNumberOfHandles(self._device) while number_of_tools > 0: for ndi_tool_index in range(number_of_tools): port_handle = ndicapy.ndiGetPHSRHandle(self._device, ndi_tool_index) self._tool_descriptors.append({ "description": ndi_tool_index, "port handle": port_handle, "c_str port handle": int2byte(port_handle) }) ndicapy.ndiCommand(self._device, "PINIT:{0:02x}".format(port_handle)) ndicapy.ndiCommand(self._device, 'PHSR:02') number_of_tools = ndicapy.ndiGetPHSRNumberOfHandles(self._device)
def _connect_serial(self, configuration): serial_port = configuration.get("serial port") ports_to_probe = configuration.get("ports to probe") if serial_port == -1: for port_no in range(ports_to_probe): name = ndicapy.ndiDeviceName(port_no) if not name: continue result = ndicapy.ndiProbe(name) if result == ndicapy.NDI_OKAY: break else: name = ndicapy.ndiDeviceName(serial_port) result = ndicapy.ndiProbe(name) if result != ndicapy.NDI_OKAY: raise IOError( 'Could not find any NDI device in ' '{} serial port candidates checked. ' 'Please check the following:\n' '\t1) Is an NDI device connected to your computer?\n' '\t2) Is the NDI device switched on?\n' '\t3) Do you have sufficient privilege to connect to ' 'the device? (e.g. on Linux are you part of the "dialout" ' 'group?)'.format(ports_to_probe)) self._device = ndicapy.ndiOpen(name) if not self._device: raise IOError( 'Could not connect to serial NDI device at {}'.format(name)) ndicapy.ndiCommand(self._device, 'INIT:') self._check_for_errors('Sending INIT command') ndicapy.ndiCommand( self._device, 'COMM:{:d}{:03d}{:d}'.format(ndicapy.NDI_115200, ndicapy.NDI_8N1, ndicapy.NDI_NOHANDSHAKE))
def get_frame(self): """Gets a frame of tracking data from the NDI device. :return: port_numbers : list of port handles, one per tool time_stamps : list of timestamps (cpu clock), one per tool frame_numbers : list of framenumbers (tracker clock) one per tool tracking : list of 4x4 tracking matrices, rotation and position, or if use_quaternions is true, a list of tracking quaternions, column 0-2 is x,y,z column 3-6 is the rotation as a quaternion. tracking_quality : list the tracking quality, one per tool. Note: The time stamp is based on the host computer clock. Read the following extract from NDI's API Guide for advice on what to use: "Use the frame number, and not the host computer clock, to identify when data was collected. The frame number is incremented by 1 at a constant rate of 60 Hz. Associating a time from the host computer clock to replies from the system assumes that the duration of time between raw data collection and when the reply is received by the host computer is constant. This is not necessarily the case." """ port_handles = [] time_stamps = [] frame_numbers = [] tracking = [] tracking_quality = [] timestamp = time() if not self._tracker_type == "dummy": ndicapy.ndiCommand(self._device, self._capture_string) for i in range(len(self._tool_descriptors)): port_handles.append( self._tool_descriptors[i].get("port handle")) time_stamps.append(timestamp) frame_numbers.append( self._get_frame( self._device, self._tool_descriptors[i].get("c_str port handle"))) qtransform = self._get_transform( self._device, self._tool_descriptors[i].get("c_str port handle")) if not qtransform == "MISSING" and not qtransform == "DISABLED": tracking_quality.append(qtransform[7]) if not self._use_quaternions: transform = transpose( reshape(ndicapy.ndiTransformToMatrixd(qtransform), [4, 4])) else: transform = reshape(qtransform[0:7], [1, 7]) else: tracking_quality.append(nan) if not self._use_quaternions: transform = full((4, 4), nan) else: transform = full((1, 7), nan) tracking.append(transform) else: for i in range(len(self._tool_descriptors)): port_handles.append( self._tool_descriptors[i].get("port handle")) time_stamps.append(timestamp) frame_numbers.append(0) tracking_quality.append(0.0) if not self._use_quaternions: tracking.append(full((4, 4), nan)) else: tracking.append(full((1, 7), nan)) return port_handles, time_stamps, frame_numbers, tracking, \ tracking_quality
break if result != NDI_OKAY: raise IOError( 'Could not find any NDI device in ' '{} serial port candidates checked. ' 'Please check the following:\n' '\t1) Is an NDI device connected to your computer?\n' '\t2) Is the NDI device switched on?\n' '\t3) Do you have sufficient privilege to connect to ' 'the device? (e.g. on Linux are you part of the "dialout" ' 'group?)'.format(MAX_SERIAL_PORTS)) device = ndiOpen(name) if not device: raise IOError('Could not connect to NDI device found on ' '{}'.format(name)) reply = ndiCommand(device, 'INIT:') error = ndiGetError(device) if reply.startswith('ERROR') or error != NDI_OKAY: raise IOError('Error when sending command: ' '{}'.format(ndiErrorString(error))) reply = ndiCommand( device, 'COMM:{:d}{:03d}{:d}'.format(NDI_115200, NDI_8N1, NDI_NOHANDSHAKE)) # Add your own commands here!!! ndiClose(device)