| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- """ Class used to create and control vrpn devices """
- from PandaObject import *
- from DirectGeometry import CLAMP
- ANALOG_MIN = -0.95
- ANALOG_MAX = 0.95
- ANALOG_RANGE = ANALOG_MAX - ANALOG_MIN
- ANALOG_DEADBAND = 0.075
- class DirectDeviceManager(VrpnClient, PandaObject):
- def __init__(self, server = None):
- # Determine which server to use
- if server != None:
- # One give as constructor argument
- self.server = server
- else:
- # Check config file, if that fails, use default
- self.server = base.config.GetString('vrpn-server', 'spacedyne')
-
- # Create a vrpn client
- VrpnClient.__init__(self, self.server)
-
- def createButtons(self, device):
- return DirectButtons(self, device)
-
- def createAnalogs(self, device):
- return DirectAnalogs(self, device)
- def createDials(self, device):
- return DirectDials(self, device)
- def createTimecodeReader(self, device):
- return DirectTimecodeReader(self, device)
- class DirectButtons(ButtonNode, PandaObject):
- buttonCount = 0
- def __init__(self, vrpnClient, device):
- # Keep track of number of buttons created
- DirectButtons.buttonCount += 1
- # Create a unique name for this button object
- self.name = 'DirectButtons-' + `DirectButtons.buttonCount`
- # Create a new button node for the given device
- ButtonNode.__init__(self, vrpnClient, device)
- # Attach node to data graph
- self.nodePath = base.dataRoot.attachNewNode(self)
-
- def __getitem__(self, index):
- if (index < 0) or (index > self.getNumButtons()):
- raise IndexError
- return self.getButtonState(index)
-
- def __len__(self):
- return self.getNumButtons()
-
- def enable(self):
- self.nodePath.reparentTo(base.dataRoot)
-
- def disable(self):
- self.nodePath.reparentTo(base.dataUnused)
-
- def getName(self):
- return self.name
-
- def getNodePath(self):
- return self.nodePath
-
- def __repr__(self):
- str = self.name + ': '
- for val in self:
- str = str + '%d' % val + ' '
- return str
- class DirectAnalogs(AnalogNode, PandaObject):
- analogCount = 0
- def __init__(self, vrpnClient, device):
- # Keep track of number of analogs created
- DirectAnalogs.analogCount += 1
- # Create a unique name for this analog object
- self.name = 'DirectAnalogs-' + `DirectAnalogs.analogCount`
- # Create a new analog node for the given device
- AnalogNode.__init__(self, vrpnClient, device)
- # Attach node to data graph
- self.nodePath = base.dataRoot.attachNewNode(self)
-
- def __getitem__(self, index):
- if (index < 0) or (index > self.getNumControls()):
- raise IndexError
- return self.getControlState(index)
-
- def __len__(self):
- return self.getNumControls()
-
- def enable(self):
- self.nodePath.reparentTo(base.dataRoot)
-
- def disable(self):
- self.nodePath.reparentTo(base.dataUnused)
-
- def normalize(self, val, minVal = -1, maxVal = -1):
- # First record sign
- if val < 0:
- sign = -1
- else:
- sign = 1
- # Zero out values in deadband
- val = sign * max(abs(val) - ANALOG_DEADBAND, 0.0)
- # Now clamp value between minVal and maxVal
- val = CLAMP(val, ANALOG_MIN, ANALOG_MAX)
- return (((maxVal - minVal) * ((val - ANALOG_MIN) / ANALOG_RANGE))
- + minVal)
-
- def normalizeChannel(self, chan, minVal = -1, maxVal = 1):
- try:
- if (chan == 2) or (chan == 6):
- # These channels have reduced range
- return self.normalize(self[chan] * 3.0, minVal, maxVal)
- else:
- return self.normalize(self[chan], minVal, maxVal)
- except IndexError:
- return 0.0
- def getName(self):
- return self.name
-
- def getNodePath(self):
- return self.nodePath
-
- def __repr__(self):
- str = self.name + ': '
- for val in self:
- str = str + '%.3f' % val + ' '
- return str
- class DirectDials(DialNode, PandaObject):
- dialCount = 0
- def __init__(self, vrpnClient, device):
- # Keep track of number of dials created
- DirectDials.dialCount += 1
- # Create a unique name for this dial object
- self.name = 'DirectDials-' + `DirectDials.dialCount`
- # Create a new dial node for the given device
- DialNode.__init__(self, vrpnClient, device)
- # Attach node to data graph
- self.nodePath = base.dataRoot.attachNewNode(self)
-
- def __getitem__(self, index):
- if (index < 0) or (index > self.getNumDials()):
- raise IndexError
- return self.readDial(index)
-
- def __len__(self):
- return self.getNumDials()
-
- def enable(self):
- self.nodePath.reparentTo(base.dataRoot)
-
- def disable(self):
- self.nodePath.reparentTo(base.dataUnused)
-
- def getName(self):
- return self.name
-
- def getNodePath(self):
- return self.nodePath
-
- def __repr__(self):
- str = self.name + ': '
- for val in self:
- str = str + '%.3f' % val + ' '
- return str
- class DirectTimecodeReader(AnalogNode, PandaObject):
- timecodeReaderCount = 0
- def __init__(self, vrpnClient, device):
- # Keep track of number of timecodeReader created
- DirectTimecodeReader.timecodeReaderCount += 1
- # Create a unique name for this dial object
- self.name = ('DirectTimecodeReader-' +
- `DirectTimecodeReader.timecodeReaderCount`)
- # Initialize components of timecode
- self.frames = 0
- self.seconds = 0
- self.minutes = 0
- self.hours = 0
- # Create a new dial node for the given device
- AnalogNode.__init__(self, vrpnClient, device)
- # Attach node to data graph
- self.nodePath = base.dataRoot.attachNewNode(self)
-
- def enable(self):
- self.nodePath.reparentTo(base.dataRoot)
-
- def disable(self):
- self.nodePath.reparentTo(base.dataUnused)
-
- def getName(self):
- return self.name
-
- def getNodePath(self):
- return self.nodePath
-
- def getTime(self):
- # Assume only one card, use channel 0
- timeBits = int(self.getControlState(0))
- self.frames = ((timeBits & 0xF) +
- (((timeBits & 0xF0) >> 4) * 10))
- self.seconds = (((timeBits & 0x0F00) >> 8) +
- (((timeBits & 0xF000) >> 12) * 10))
- self.minutes = (((timeBits & 0x0F0000) >> 16) +
- (((timeBits & 0xF00000) >> 20) * 10))
- self.hours = (((timeBits & 0xF0000000) >> 24) +
- (((timeBits & 0xF0000000) >> 28) * 10))
- self.totalSeconds = ((self.hours * 3600) +
- (self.minutes * 60) +
- self.seconds +
- (self.frames / 30.0))
- return (self.hours, self.minutes, self.seconds, self.frames,
- self.totalSeconds)
-
- def __repr__(self):
- str = ('%s: %d:%d:%d:%d' % ((self.name,) + self.getTime()[:-1]))
- return str
|