Beispiel #1
0
    def getSearchTerms(self, interfaceType):
        '''returns the likely prefix for a serial port based on the operating system and device type'''
        #define search strings in format {'OperatingSystem':'SearchString'}
        ftdi = {'Darwin': 'tty.usbserial-'}
        lufa = {'Darwin': 'tty.usbmodem'}
        genericSerial = {'Darwin': 'tty.'}

        searchStrings = {
            'ftdi': ftdi,
            'lufa': lufa,
            'genericSerial': genericSerial
        }

        opSys = platform.system()  #nominally detects the system

        if interfaceType in searchStrings:
            if opSys in searchStrings[interfaceType]:
                return searchStrings[interfaceType][opSys]
            else:
                notice(
                    'getSearchTerm',
                    'operating system support not found for interface type ' +
                    interfaceType)
                return False
        else:
            notice(
                'getSearchTerm',
                'interface support not found for interface type ' +
                interfaceType)
            return False
Beispiel #2
0
 def transmit(self, data):
     '''Sends request for data to be transmitted over the serial port. Format is as a list.'''
     if self.isConnected:
         self.transmitQueue.put(
             data)  #converts to list in case data comes in as a string.
     else:
         notice(self, 'serialInterface is not connected.')
			def init(self, axesSteps, accelSteps = 0, decelSteps = 0, accelRate = 0, external = False, sync = False, majorSteps = None):
				# axesSteps: a list containing the number of steps which each axis of the node should take in synchrony.
				# accelSteps: number of virtual major axis steps during which acceleration should occur.
				# deccelSteps: number of virtual major axis steps during which deceleration should occur.
				# accelRate: accel/decel rate in steps/sec^2 
				# external: indicates whether the actionObject will be commited to its interface externally.
				#			When False, the actionObject will self commit and release.
				#			When True, the actionObject will prepare a packet but will need to be commited and release externally.
				# sync: indicates that this actionObject will be synchronized externally and that parameters might change. This will prevent it from spawning.
				# majorSteps: this parameter is only called internally when a request calls for too many steps for one actionObject and the actionObject needs to spawn.
				if type(axesSteps) != list and type(axesSteps) != tuple: axesSteps = [axesSteps]
				self.axesSteps = [int(axis) for axis in axesSteps]	#list of steps to take in each axis e.g. [x, y, z]. May be provided as a tuple.
				self.accelSteps = accelSteps
				self.decelSteps = decelSteps
				self.accelRate = accelRate
				self.external = external
				self.sync = sync
				self.actionSequence = False #start out with no action sequence
				self.sequenceMajorSteps = None	#if this actionObject becomes an actionSequence parent, this will store the list of major axes
				
				#calculate virtual major axis
				if majorSteps:	#if provided externally, use that.
					self.majorSteps = majorSteps
				else:	#generate majorSteps from provided axes.
					self.majorSteps = max([abs(axis) for axis in self.axesSteps])
				
				if self.majorSteps > self.virtualNode.maxSteps:	#check if step request exceeds maximum length
					if not sync:	#no other anticipated recalculations, so go ahead and generate actionSequence
						#need to generate an actionSequence with multiple new actionObjects
						self.actionSequence = self.actionSequenceGen()
						return self.actionSequence
					else:	#the majorSteps has not yet been synchronized, so cannot generate an action sequence yet.
						return self
					
				else: #step request is executable by this action object. Either initial request met this criteria, or this actionObject was initialized by actionSequence().
					#calculate directions
					directions = [1 if axis>0 else 0 for axis in self.axesSteps]
					directionMultiplexer = [2**b for b in range(self.virtualNode.numberOfAxes-1, -1, -1)] #generates [2^n, 2^n-1,...,2^0]
					self.directionByte = sum(map(lambda x,y: x*y, directionMultiplexer, directions))	#directionByte is each term of directionMultiplexer multiplied by the directions and then summed.					

					if external or sync:	#actionObject is being managed by an external function and shouldn't auto-commit
						return self
					else:
						#set packet
						accelRate = self.tbAccelRate(self.accelRate)	#convert accel rate into timebase
						self.setPacket({'majorSteps':self.majorSteps, 'directions':self.directionByte, 'steps':abs(self.axesSteps[0]), 'accel':accelRate, 
									'accelSteps':accelSteps, 'decelSteps':decelSteps})
						
						self.commitAndRelease()
						self.waitForChannelAccess()
						moveQueued = False
						while not moveQueued:
							if self.transmitPersistent():
								responsePacket = self.getPacket()
								moveQueued = bool(responsePacket['statusCode'])	#False if move was not queued
								time.sleep(0.02)
							else: 
								notice(self.virtualNode, "got no response to spin request")
								return False
						return responsePacket
Beispiel #4
0
 def __init__(self, elements):
     if type(elements) == list: self.init(transformation=elements)
     else:
         notice(
             self, 'expected input of type list but instead got ' +
             str(type(elements)))
         return None
Beispiel #5
0
		def __init__(self, inputMatrices):
			if type(inputMatrices) != list:	#make sure that input is a list
				notice(self, 'expected input of type list but instead got type ' + str(list))
				return False
			self.arrays = inputMatrices
			self.lengths = [array.length for array in inputMatrices]	#stores lengths of each array
			self.length = sum(self.lengths)
Beispiel #6
0
	def transmitPersistent(self, tries = 10, timeout = 0.2):
		'''Transmit a packet until a response is received.'''
		for i in range(tries):
			self.transmit()
			if self.waitForResponse(timeout): return True
			notice(self.virtualNode, 'Could not reach virtual node. Retrying (#' + str(i+2) + ')')	#i starts at 0, and when this gets called already tried once.
		return False
Beispiel #7
0
	def __init__(self, *args, **kwargs):
		
		if 'name' in kwargs: #set name as provided
			self.name = kwargs['name']
		else: #set name to filename for generating proper notice commands
			self.name = inspect.getfile(self.__class__)
		
		if 'persistenceFile' in kwargs:	#set persistence file as provided
			self.persistenceFilename = kwargs['persistenceFile']
			if 'name' not in kwargs:	#If no name is provided, and multiple machines share the persistence file, this can result in a namespace conflict.
				notice(self, 'Warning: setting persistence without providing a name to the virtual machine can result in a conflict in multi-machine persistence files.')
		else:
			self.persistenceFilename = None
			
		self.persistence = utilities.persistenceManager(filename = self.persistenceFilename, namespace = self.name)
				
		if 'interface' in kwargs:
			self.providedInterface = kwargs['interface']	#interface provided on instantiation of virtual machine.
		else:
			self.providedInterface = None
		
		self.publishEnabled = True	#this should get set explicitly to false in user init by calling disablePublishing
		
		#run user initialization
		self.init(*args, **kwargs)	#calls child class init function
		self.initInterfaces()
		self.initControllers()
		self.initCoordinates()
		self.initKinematics()
		self.initFunctions()
		self.initPublish()
		self.initLast()
		self.publish()
Beispiel #8
0
 def __new__(cls, *args, **kwargs):
     """Intantiation routine for actionObject base class.
     
     When a call is made to the action object class, this "magic" function creates the instance.
     Any arguments are passed along to the subclass's init() function, which may either return a value or None.
     If nothing is returned, as is the case in typical __init__ methods, then we return the actionObject. But
     if a return value is provided by the user (i.e. the interpreted reply of a real node), this is passed along.
     
     Note that if a call is made to the actionObject before it is bound to a port, a notice will be issued and
     a None object will be returned.
     """
     if cls.virtualNode == None: #check to make sure the actionObject is bound
         notice(cls.__name__, "Can not instantiate actionObject because it isn't bound to a port on a virtual node!")   #not bound! give notice
         return None #not bound, return None
     
     newActionObject = object.__new__(cls)   #creates the new actionObject
     newActionObject._init_()    #runs the actionObject base class's initialization. Note that
                                 #__init__ is intentionally not used, because otherwise it would get called twice.
     returnValue = newActionObject.init(*args, **kwargs) # calls the user-defined initialization routine, this time 
                                                         # with any provided arguments.
     
     if returnValue == None:     #if the user initialization doesn't return anything, then return the actionObject
         return newActionObject
     else:                       #otherwise pass along whatever the user has provided
         return returnValue
Beispiel #9
0
	def transmit(self):
		'''Sends a packet over the interface to the matching physical node.
		Note that this method will only be called within the interface channelAccess thread, which guarantees that the channel is avaliable.'''
		if self.channelAccessGranted.is_set():
			self.interface.transmit(virtualNode = self.virtualNode, port = self.port, packetSet = self.packetSet, mode = self.mode)
		else:
			notice(self.virtualNode, 'tried to transmit without channel access!')
Beispiel #10
0
	def  __getattr__(self, attribute):
		'''	Forwards all unsupported calls to the parent actionObject.'''
		if hasattr(self.parent, attribute):	#parent actionObject contains requested attribute
			return getattr(self.parent, attribute)
		else:
			notice(self, "ActionObject DOESN'T HAVE REQUESTED ATTRIBUTE")
			raise AttributeError(attribute)
Beispiel #11
0
            def channelAccess(self):
                '''This gets called when channel access is granted. 
				To prevent double-transmission, only transmit if external is True.'''
                if self.external:
                    #set packet
                    accelRate = self.tbAccelRate(
                        self.accelRate)  #convert accel rate into timebase
                    self.setPacket({
                        'majorSteps': self.majorSteps,
                        'directions': self.directionByte,
                        'steps': abs(self.axesSteps[0]),
                        'accel': accelRate,
                        'accelSteps': self.accelSteps,
                        'decelSteps': self.decelSteps,
                        'sync': int(bool(self.sync))
                    })
                    #since this node was instantiated under external control, it did not auto-transmit.
                    moveQueued = False
                    while not moveQueued:
                        if self.transmitPersistent():
                            responsePacket = self.getPacket()
                            print responsePacket
                            moveQueued = bool(
                                responsePacket['statusCode']
                            )  #False if move was not queued, meaning buffer is full
                            if not moveQueued:
                                time.sleep(0.02)  #wait before retransmitting
                        else:
                            notice(self.virtualNode,
                                   "got no response to spin request")
Beispiel #12
0
 def transmit(self, mode = 'unicast', releaseChannelOnTransmit = True):
     """Transmits packet on the virtualNode's interface.
     
     mode -- the transmission mode, either 'unicast to direct at a single node, or 'multicast' to direct at all nodes.
     releaseChannelOnTransmit -- If True (default), will automatically release the actionObject's channel lock after transmission
     """
     
     if self.channelAccessIsGranted():   #very likely that transmit has been called from within an onChannelAccess function, since access is avaliable immediately
         self._putActionObjectIntoInboundPacketFlagQueue_(self)  #put a reference to self in the inbound packet flag queue
         self.virtualNode._interface_.transmit(actionObject = self, mode = mode)  #pass actionObject to interface for transmission
         if releaseChannelOnTransmit:  #check if should release the channel lock after transmission
             self._releaseChannelAccessLock_()  #release the channel access lock
         return True
     else:   #transmit was called before actionObject was granted channel access, take node thru to channel access
         if not self._isCommitted_():    #check if actionObject is already committed
             self.commit()   #commit actionObject to channel priority queue
         if not self._isClearForRelease_():   #check if actionObject is cleared for release from the channel priority queue
             self.clearForRelease()  #clear actionObject for release from the channel priority queue
         if self.waitForChannelAccess(): #wait for channel access
             self._putActionObjectIntoInboundPacketFlagQueue_(self)  #put a reference to self in the inbound packet flag queue
             self.virtualNode._interface_.transmit(actionObject = self, mode = mode) #transmit on interface
             if releaseChannelOnTransmit:    #check if should release the channel access lock
                 self._releaseChannelAccessLock_()   #release the channel access lock
         else:
             notice(self, "timed out waiting for channel access")    #timed out!
             return False
     return True        
Beispiel #13
0
	def setTimeout(self, timeout):
		'''Sets timeout for receiving on port.'''
		if self.port:
			try:
				self.port.timeout = timeout
			except:
				notice(self, "could not set timeout: " + sys.exc_info()[0])
Beispiel #14
0
    def acquirePort(self, interfaceType=None):
        '''Discovers and connects to a port by waiting for a new device to be plugged in.'''
        #get search terms
        if interfaceType:
            searchTerm = self.getSearchTerms(interfaceType)
        else:
            searchTerm = self.getSearchTerms('genericSerial')

        #try to find a single port that's open. This is good for when only a single device is attached.
        availablePorts = self.getAvailablePorts(self.deviceScan(searchTerm))
        if len(availablePorts) == 1:
            self.portName = availablePorts[0]
            return self.connect()
        else:
            notice(self.owner, "trying to acquire. Please plug me in.")
            newPorts = self.waitForNewPort(searchTerm, 10)  #wait for new port
            if newPorts:
                if len(newPorts) > 1:
                    notice(
                        self.owner,
                        'Could not acquire. Multiple ports plugged in simultaneously.'
                    )
                    return False
                else:
                    self.portName = newPorts[0]
                    return self.connect()
            else:
                return False
Beispiel #15
0
 def nodeFunctionCall(self, node, attribute, args, kwargs):
     if hasattr(node, attribute):
         return getattr(node, attribute)(*list(args), **kwargs)
     else:
         notice(self.compoundNode,
                "NODE DOESN'T HAVE REQUESTED ATTRIBUTE")
         raise AttributeError(attribute)
Beispiel #16
0
		def nodeFunctionCall(self, node, attribute, args, kwargs):
			if hasattr(node, attribute):
				return getattr(node, attribute)(*list(args), **kwargs)
			else:
				notice(self.compoundNode, "NODE DOESN'T HAVE REQUESTED ATTRIBUTE")
				raise AttributeError(attribute)
				
Beispiel #17
0
 def setTimeout(self, timeout):
     '''Sets timeout for receiving on port.'''
     if self.port:
         try:
             self.port.timeout = timeout
         except:
             notice(self, "could not set timeout: " + sys.exc_info()[0])
Beispiel #18
0
 def init(self):
     self.setPacket({})
     self.commitAndRelease()
     self.waitForChannelAccess()
     if self.transmitPersistent():
         return self.getPacket()
     else:
         notice(self.virtualNode, 'unable to get status from node.')
Beispiel #19
0
def functionCall(callObject, attribute, args, kwargs):
	'''Calls callObject.attribute(*args, **kwargs)'''
	
	if hasattr(callObject, attribute):
		return getattr(callObject, attribute)(*list(args), **kwargs)
	else:
		notice(callObject, "actionObject DOESN'T HAVE REQUESTED ATTRIBUTE")
		raise AttributeError(attribute)		
			def init(self):
				self.setPacket({})
				self.commitAndRelease()
				self.waitForChannelAccess()
				if self.transmitPersistent():
					return self.getPacket()
				else:
					notice(self.virtualNode, 'unable to get status from node.')	
Beispiel #21
0
 def init(self):
     self.commitAndRelease()  #commit self immediately
     self.waitForChannelAccess()
     if self.transmitPersistent():
         return self.getPacket()['URL']
     else:
         notice(self.virtualNode, 'NO URL RECEIVED')
         return False
Beispiel #22
0
			def init(self):
				self.commitAndRelease()	#commit self immediately
				self.waitForChannelAccess()
				if self.transmitPersistent():
					return self.getPacket()['URL']
				else:
					notice(self.virtualNode, 'NO URL RECEIVED')
					return False
Beispiel #23
0
		def run(self):
			'''Code run by the transmit thread.'''
			while True:
				transmitState, transmitPacket = self.getTransmitPacket()
				if transmitState:
					if self.port:
						self.port.write(serialize(transmitPacket))
					else: notice(self, 'Cannot Transmit - No Serial Port Initialized')
				time.sleep(0.0005)
Beispiel #24
0
		def set(self, valueArray):
			if len(valueArray) != len(self.baseList):
				notice(self, 'input array length must match coordinate length.')
				return False
			else:
				for index, item in enumerate(valueArray):
					#any None input will not modify value
					self.baseList[index] = coordinates.uFloat(item, self.baseList[index].units) if item != None else self.baseList[index]
				return True
Beispiel #25
0
			def init(self, IP):
				self.setPacket({'setAddress':IP}, mode = 'multicast')
				self.commitAndRelease()	#commit self immediately
				self.waitForChannelAccess(5)
				if self.transmitPersistent(timeout = 15):
					time.sleep(1)	#debounce for button press
					return self.getPacket()['URL']
				else:
					notice(self.virtualNode, 'TIMEOUT WAITING FOR BUTTON PRESS')
Beispiel #26
0
 def initAfterSet(self):  #gets called once interface is set into shell.
     self.receiveSocket = socket.socket(
         socket.AF_INET,
         socket.SOCK_DGRAM)  #UDP, would be socket.SOCK_STREAM for TCP
     self.receiveSocket.bind(
         (self.receiveIPAddress, self.receiveIPPort))  #bind to socket
     notice(
         self, "opened socket on " + str(self.receiveIPAddress) + " port " +
         str(self.receiveIPPort))
     self.transmitSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
Beispiel #27
0
 def init(self, IP):
     self.setPacket({'setAddress': IP}, mode='multicast')
     self.commitAndRelease()  #commit self immediately
     self.waitForChannelAccess(5)
     if self.transmitPersistent(timeout=15):
         time.sleep(1)  #debounce for button press
         return self.getPacket()['URL']
     else:
         notice(self.virtualNode,
                'TIMEOUT WAITING FOR BUTTON PRESS')
Beispiel #28
0
	def __init__(self, *nodes):
		self.nodes = nodes
		self.nodeCount = len(self.nodes)
		self.name = "[" + ''.join([str(node.name) + "," for node in nodes])[:-1] + "]"
		interfaces = [node.interface.Interface for node in nodes]	#nodes have an interface shell
		if all(interface == interfaces[0] for interface in interfaces):
			self.commonInterface = True
		else:
			self.commonInterface = False
			notice(self, "warning: not all members of compound node share a common interface!")
			def init(self):
				self.setPacket({})
				self.commitAndRelease()
				self.waitForChannelAccess()
				if self.transmitPersistent(): 
					notice(self.virtualNode, "Stepper motor disabled.")
					return True
				else: 
					notice(self.virtualNode, "Stepper motor could not be disabled.")
					return False
Beispiel #30
0
 def __init__(self, inputMatrices):
     if type(inputMatrices) != list:  #make sure that input is a list
         notice(
             self, 'expected input of type list but instead got type ' +
             str(list))
         return False
     self.arrays = inputMatrices
     self.lengths = [array.length for array in inputMatrices
                     ]  #stores lengths of each array
     self.length = sum(self.lengths)
Beispiel #31
0
 def run(self):
     '''Code run by the transmit thread.'''
     while True:
         transmitState, transmitPacket = self.getTransmitPacket()
         if transmitState:
             if self.port:
                 self.port.write(serialize(transmitPacket))
             else:
                 notice(self,
                        'Cannot Transmit - No Serial Port Initialized')
         time.sleep(0.0005)
Beispiel #32
0
 def init(self):
     self.setPacket({})
     self.commitAndRelease()
     self.waitForChannelAccess()
     if self.transmitPersistent():
         notice(self.virtualNode, "Stepper motor disabled.")
         return True
     else:
         notice(self.virtualNode,
                "Stepper motor could not be disabled.")
         return False
Beispiel #33
0
	def  __getattr__(self, attribute):
		'''	Forwards any unsupported calls to the shell onto the node.'''
		if self.hasNode():	#Shell contains a node.
			if hasattr(self.node, attribute):	#node contains requested attribute
				return getattr(self.node, attribute)
			else:
				notice(self, "NODE DOESN'T HAVE REQUESTED ATTRIBUTE")
				raise AttributeError(attribute)
		else:
			notice(self, "NODE IS NOT INITIALIZED")
			raise AttributeError(attribute)
Beispiel #34
0
    def loadNodeFromFile(self, filename, **kwargs):
        ''' Loads a node into the node shell from a provided filename.
		
			Assumes that this is called from a node shell that has defined self.name'''
        try:
            self.setNode(imp.load_source('', filename).virtualNode(**kwargs))
            notice(self, "loaded node from:  " + filename)
            return True
        except IOError, error:
            notice(self, "error loading file.")
            print error
            return False
Beispiel #35
0
	def loadNodeFromFile(self, filename, **kwargs):
		''' Loads a node into the node shell from a provided filename.
		
			Assumes that this is called from a node shell that has defined self.name'''
		try: 
			self.setNode(imp.load_source('', filename).virtualNode(**kwargs))
			notice(self, "loaded node from:  " + filename)
			return True
		except IOError, error:
			notice(self, "error loading file.")
			print error
			return False
Beispiel #36
0
 def set(self, valueArray):
     if len(valueArray) != len(self.baseList):
         notice(self,
                'input array length must match coordinate length.')
         return False
     else:
         for index, item in enumerate(valueArray):
             #any None input will not modify value
             self.baseList[index] = coordinates.uFloat(
                 item, self.baseList[index].units
             ) if item != None else self.baseList[index]
         return True
Beispiel #37
0
 def __getattr__(self, attribute):
     '''	Forwards any unsupported calls to the shell onto the node.'''
     if self.hasNode():  #Shell contains a node.
         if hasattr(self.node,
                    attribute):  #node contains requested attribute
             return getattr(self.node, attribute)
         else:
             notice(self, "NODE DOESN'T HAVE REQUESTED ATTRIBUTE")
             raise AttributeError(attribute)
     else:
         notice(self, "NODE IS NOT INITIALIZED")
         raise AttributeError(attribute)
			def init(self, velocity):
				#velocity is in steps/sec
				velocity = int(round((velocity * self.virtualNode.uStepsPerStep * self.virtualNode.timeBasePeriod)/16.0,0)) #convert into 16*uSteps/timebase
				print velocity
				self.setPacket({'velocity': velocity})
				self.commitAndRelease()
				self.waitForChannelAccess()
				if self.transmitPersistent():
					return True
				else:
					notice(self.virtualNode, 'unable to set velocity.')
					return False
Beispiel #39
0
    def loadNodeFromModule(self, module, **kwargs):
        '''Loads a node into the node shell from the provided class.
		
		Note that class itself should be provided, NOT a class instance.'''
        try:
            if hasattr(module, 'virtualNode'):
                self.setNode(module.virtualNode(**kwargs))
            else:
                self.setNode(module(**kwargs))
            notice(self, "loaded module " + str(module.__name__))
            return True
        except AttributeError, err:
            notice(self, "unable to load module: " + str(err))
            return False
Beispiel #40
0
	def connectToPort(self, portName):
		'''Actually connects the interface to the port'''
		try:
			self.port = serial.Serial(portName, self.baudRate, timeout = self.timeOut)
			self.port.flushInput()
			self.port.flushOutput()
			notice(self, "port " + str(portName) + " connected succesfully.")
			time.sleep(2)	#some serial ports require a brief amount of time between opening and transmission
			self.isConnected = True
			self.startTransmitter()
			return True
		except:
			notice(self, "error opening serial port "+ str(portName))
			return False
Beispiel #41
0
	def loadNodeFromModule(self, module, **kwargs):
		'''Loads a node into the node shell from the provided class.
		
		Note that class itself should be provided, NOT a class instance.'''
		try:
			if hasattr(module, 'virtualNode'):
				self.setNode(module.virtualNode(**kwargs))
			else:
				self.setNode(module(**kwargs))
			notice(self, "loaded module " + str(module.__name__))
			return True
		except AttributeError, err:
			notice(self, "unable to load module: " + str(err))
			return False
Beispiel #42
0
 def reverse(self, reverseState):
     """Tranforms in the reverse direction from an output state of the tranformer to the corresponding input state.
     
     inputState -- the input state of the transformer. MUST be provided as a units.dFloat type.
     
     Note that this function over-rides its base class transformer.forward() function.
     """
     
     if type(reverseState) == units.dFloat:
         convertedReverseState = units.convertToUnits(reverseState, self.outputUnits, strict = True) #convert to input units, don't allow reciprocals
         return self.reverseTransform*convertedReverseState
     else:
         utilities.notice(self, "Input to singleAxisElement transformer must be of type units.dFloat!")
         raise errors.MechanismError("Incorrect input type to singleAxisElement.reverse()")
Beispiel #43
0
 def init(self, velocity):
     #velocity is in steps/sec
     velocity = int(
         round((velocity * self.virtualNode.uStepsPerStep *
                self.virtualNode.timeBasePeriod) / 16.0,
               0))  #convert into 16*uSteps/timebase
     print velocity
     self.setPacket({'velocity': velocity})
     self.commitAndRelease()
     self.waitForChannelAccess()
     if self.transmitPersistent():
         return True
     else:
         notice(self.virtualNode, 'unable to set velocity.')
         return False
Beispiel #44
0
 def __init__(self, *nodes):
     self.nodes = nodes
     self.nodeCount = len(self.nodes)
     self.name = "[" + ''.join([str(node.name) + ","
                                for node in nodes])[:-1] + "]"
     interfaces = [node.interface.Interface
                   for node in nodes]  #nodes have an interface shell
     if all(interface == interfaces[0] for interface in interfaces):
         self.commonInterface = True
     else:
         self.commonInterface = False
         notice(
             self,
             "warning: not all members of compound node share a common interface!"
         )
Beispiel #45
0
	def connect(self, portName = None):
		'''Locates port for interface on host machine.'''
			
		#check if port has been provided explicitly to connect function
		if portName:
			self.connectToPort(portName)
			return True
		
		#port hasn't been provided to connect function, check if assigned on instantiation
		elif self.portName:
			self.connectToPort(self.portName)
			return True
			
		#no port name provided
		else:
			notice(self, 'no port name provided.')
			return False
Beispiel #46
0
    def connect(self, portName=None):
        '''Locates port for interface on host machine.'''

        #check if port has been provided explicitly to connect function
        if portName:
            self.connectToPort(portName)
            return True

        #port hasn't been provided to connect function, check if assigned on instantiation
        elif self.portName:
            self.connectToPort(self.portName)
            return True

        #no port name provided
        else:
            notice(self, 'no port name provided.')
            return False
			def channelAccess(self):
				'''This gets called when channel access is granted. 
				To prevent double-transmission, only transmit if external is True.'''				
				if self.external:
						#set packet
					accelRate = self.tbAccelRate(self.accelRate)	#convert accel rate into timebase
					self.setPacket({'majorSteps':self.majorSteps, 'directions':self.directionByte, 'steps':abs(self.axesSteps[0]), 'accel':accelRate, 
								'accelSteps':self.accelSteps, 'decelSteps':self.decelSteps, 'sync':int(bool(self.sync))})
					#since this node was instantiated under external control, it did not auto-transmit.
					moveQueued = False
					while not moveQueued:
						if self.transmitPersistent():
							responsePacket = self.getPacket()
							print responsePacket
							moveQueued = bool(responsePacket['statusCode']) #False if move was not queued, meaning buffer is full
							if not moveQueued: time.sleep(0.02)	#wait before retransmitting
						else:
							notice(self.virtualNode, "got no response to spin request")
Beispiel #48
0
 def connectToPort(self, portName):
     '''Actually connects the interface to the port'''
     try:
         self.port = serial.Serial(portName,
                                   self.baudRate,
                                   timeout=self.timeOut)
         self.port.flushInput()
         self.port.flushOutput()
         notice(self, "port " + str(portName) + " connected succesfully.")
         time.sleep(
             2
         )  #some serial ports require a brief amount of time between opening and transmission
         self.isConnected = True
         self.startTransmitter()
         return True
     except:
         notice(self, "error opening serial port " + str(portName))
         return False
Beispiel #49
0
    def __init__(self,
                 name=None,
                 interface=None,
                 filename=None,
                 URL=None,
                 module=None,
                 **kwargs):
        '''	Initialization procedure for Solo/Independent Node Shell.
			
			name:		a unique name assigned by the user. This is used by the persistence algorithm to re-acquire the node.
			interface: 	the object thru which the virtual node communicates with its physical counterpart.
			**kwargs:	any additional arguments to be passed to the node during initialization
			
			Methods of Loading Virtual Node:
				filename: an import-able module containing the virtual node.
				URL: a URL pointing to a module as a resource containing the virtual node.
				module: a python module name containing the virtual node.
		'''

        #call base class __init__ method
        super(soloIndependentNode, self).__init__()

        #assign parameters to variables
        self.name = name
        self.filename = filename
        self.URL = URL
        self.module = module
        self.interface.set(
            interface,
            self)  #interface isn't shared with other nodes, so owner is self.

        #acquire node. For an SI node, some method of acquisition MUST be provided, as it has no protocol for auto-loading.
        #load via filename
        if filename:
            self.loadNodeFromFile(filename, **kwargs)
        #load via URL
        elif URL:
            self.loadNodeFromURL(URL, **kwargs)
        #load via module
        elif module:
            self.loadNodeFromModule(module, **kwargs)
        else:
            notice(self, "no node source was provided.")
            notice(self, "please provide a filename, URL, or class")
Beispiel #50
0
        def transformReverse(
            self, value
        ):  #NOTE: THIS GETS REASSIGNED TO THE NAME "reverse" ON INSTANTIATION BY CLASSMETHOD "reverse"
            if type(self.transformation
                    ) == list:  #transformation is a list of elements
                reverseTransformation = copy.copy(self.transformation)
                reverseTransformation.reverse()
                for element in reverseTransformation:  #transform value thru elements in forwards direction
                    value = element.reverse(value)
                return value

            elif type(
                    value
            ) == coordinates.uFloat:  #input value is a uFloat, transform directly
                if value.units == self.outputUnits:  #output units match (going in reverse!)
                    return coordinates.uFloat(
                        value / float(self.transformation), self.inputUnits
                    )  #return a transformed uFloat in input units
                elif self.inputUnits:  #input units are specified for this element, enforce match
                    newValue = value.convertUnits(
                        self.outputUnits
                    )  #try to convert to input units. i.e. mm to inch
                    if newValue:
                        return coordinates.uFloat(
                            newValue / float(self.transformation),
                            self.inputUnits
                        )  #conversion successful, return a transformed uFloat in output units
                    else:
                        notice(
                            self, 'provided units ' + str(value.units) +
                            ' but this element works in units of ' +
                            str(self.outputUnits) +
                            ' in the reverse direction.')
                        return False
                else:  #no input units specified, transform anyways
                    return coordinates.uFloat(
                        value / float(self.transformation), value.units
                    )  #return a transformed uFloat in same units as input value
            else:
                notice(
                    self, 'expected an input of type uFloat but instead got ' +
                    str(type(value)))
                return False
Beispiel #51
0
	def getSearchTerms(self, interfaceType):
		'''returns the likely prefix for a serial port based on the operating system and device type'''
		#define search strings in format {'OperatingSystem':'SearchString'}
		ftdi = {'Darwin':'tty.usbserial-'}
		lufa = {'Darwin':'tty.usbmodem'}
		genericSerial = {'Darwin': 'tty.'}
		
		searchStrings = {'ftdi':ftdi, 'lufa':lufa, 'genericSerial':genericSerial}	
		
		opSys = platform.system()	#nominally detects the system
		
		if interfaceType in searchStrings:
			if opSys in searchStrings[interfaceType]:
				return searchStrings[interfaceType][opSys]
			else:
				notice('getSearchTerm', 'operating system support not found for interface type '+ interfaceType)
				return False
		else:
			notice('getSearchTerm', 'interface support not found for interface type ' + interfaceType)
			return False	
Beispiel #52
0
		def transformForward(self, value):	#NOTE: THIS GETS REASSIGNED TO THE NAME "forward" ON INSTANTIATION BY CLASSMETHOD "forward"
			if type(self.transformation) == list: #transformation is a list of elements
				for element in self.transformation:	#transform value thru elements in forwards direction
					value = element.forward(value)
				return value
			
			elif type(value) == coordinates.uFloat:	#input value is a uFloat, transform directly
				if value.units == self.inputUnits:	#input units match
					return coordinates.uFloat(value*self.transformation, self.outputUnits)	#return a transformed uFloat in output units
				elif self.inputUnits:	#input units are specified for this element, enforce match
					newValue = value.convertUnits(self.inputUnits)	#try to convert to input units. i.e. mm to inch
					if newValue: return coordinates.uFloat(newValue*self.transformation, self.outputUnits)	#conversion successful, return a transformed uFloat in output units
					else:
						notice(self, 'provided units ' + str(value.units) + ' but this element works in units of ' + str(self.inputUnits) + ' in the forward direction.')
						return False
				else:	#no input units specified, transform anyways
					return coordinates.uFloat(value*self.transformation, value.units)	#return a transformed uFloat in same units as input value
		
			else:
				notice(self, 'expected an input of type uFloat but instead got ' + str(type(value)))
				return False
Beispiel #53
0
	def waitForNewPort(self, searchTerms = '', timeout = 10):
		'''Scans for a new port to appear in /dev/ and returns the name of the port.
		
		Search terms is a list that can contain several terms. For now only implemented for one term.'''
		timerCount = 0
		devPorts = self.deviceScan(searchTerms)
		numDevPorts = len(devPorts)
		while True:
			time.sleep(0.25)
			timerCount += 0.25
			if timerCount > timeout:
				notice(self.owner, 'TIMOUT in acquiring a port.')
				return False
			currentDevPorts = self.deviceScan(searchTerms)
			numCurrentDevPorts = len(currentDevPorts)
			
			#port has been unplugged... update number of ports
			if numCurrentDevPorts < numDevPorts:
				devPorts = list(currentDevPorts)
				numDevPorts = numCurrentDevPorts
			elif numCurrentDevPorts > numDevPorts:
				return list(set(currentDevPorts) - set(devPorts))	#returns all ports that just appeared
	def setMotorCurrent(self, setCurrent):
		if setCurrent < 0 or setCurrent > 2.0:
			notice(self, "Motor current must be between 0 and 2.0 amps. " + str(setCurrent) + " was requested.")
		setCurrent = round(float(setCurrent), 1)
		while True:
			motorVoltage = self.getReferenceVoltage()
			motorCurrent = round(motorVoltage /(8.0*self.motorSenseResistor),2)	#amps
			if round(motorCurrent,1) > setCurrent:
				notice(self, "Motor current: " + str(motorCurrent) + "A / " + "Desired: " + str(setCurrent) + "A. Turn trimmer CW.")
			elif round(motorCurrent,1) < setCurrent:
				notice(self, "Motor current: " + str(motorCurrent) + "A / " + "Desired: " + str(setCurrent) + "A. Turn trimmer CCW.")
			else:
				notice(self, "Motor current set to: " + str(motorCurrent) + "A")
				break;
			time.sleep(0.5)
Beispiel #55
0
    def __init__(self, *args, **kwargs):

        if 'name' in kwargs:  #set name as provided
            self.name = kwargs['name']
        else:  #set name to filename for generating proper notice commands
            self.name = inspect.getfile(self.__class__)

        if 'persistenceFile' in kwargs:  #set persistence file as provided
            self.persistenceFilename = kwargs['persistenceFile']
            if 'name' not in kwargs:  #If no name is provided, and multiple machines share the persistence file, this can result in a namespace conflict.
                notice(
                    self,
                    'Warning: setting persistence without providing a name to the virtual machine can result in a conflict in multi-machine persistence files.'
                )
        else:
            self.persistenceFilename = None

        self.persistence = utilities.persistenceManager(
            filename=self.persistenceFilename, namespace=self.name)

        if 'interface' in kwargs:
            self.providedInterface = kwargs[
                'interface']  #interface provided on instantiation of virtual machine.
        else:
            self.providedInterface = None

        self.publishEnabled = True  #this should get set explicitly to false in user init by calling disablePublishing

        #run user initialization
        self.init(*args, **kwargs)  #calls child class init function
        self.initInterfaces()
        self.initControllers()
        self.initCoordinates()
        self.initKinematics()
        self.initFunctions()
        self.initPublish()
        self.initLast()
        self.publish()
Beispiel #56
0
    def waitForNewPort(self, searchTerms='', timeout=10):
        '''Scans for a new port to appear in /dev/ and returns the name of the port.
		
		Search terms is a list that can contain several terms. For now only implemented for one term.'''
        timerCount = 0
        devPorts = self.deviceScan(searchTerms)
        numDevPorts = len(devPorts)
        while True:
            time.sleep(0.25)
            timerCount += 0.25
            if timerCount > timeout:
                notice(self.owner, 'TIMOUT in acquiring a port.')
                return False
            currentDevPorts = self.deviceScan(searchTerms)
            numCurrentDevPorts = len(currentDevPorts)

            #port has been unplugged... update number of ports
            if numCurrentDevPorts < numDevPorts:
                devPorts = list(currentDevPorts)
                numDevPorts = numCurrentDevPorts
            elif numCurrentDevPorts > numDevPorts:
                return list(
                    set(currentDevPorts) -
                    set(devPorts))  #returns all ports that just appeared