Joystick::Joystick(VRDevice::Factory* sFactory,VRDeviceManager* sDeviceManager,Misc::ConfigurationFile& configFile) :VRDevice(sFactory,sDeviceManager,configFile), joystickDeviceFd(open(configFile.retrieveString("./joystickDeviceFile").c_str(),O_RDONLY)), axisGains(0), reportEvents(false), buttonStates(0),valuatorStates(0) { /* Check if the joystick device port was properly opened: */ if(joystickDeviceFd<0) Misc::throwStdErr("Joystick: Unable to open joystick device port"); /* Query the joystick's geometry: */ char cNumButtons,cNumAxes; ioctl(joystickDeviceFd,JSIOCGBUTTONS,&cNumButtons); ioctl(joystickDeviceFd,JSIOCGAXES,&cNumAxes); #ifdef VERBOSE /* Query the joystick's name: */ char joystickName[256]; if(ioctl(joystickDeviceFd,JSIOCGNAME(sizeof(joystickName)),joystickName)>=0) { joystickName[sizeof(joystickName)-1]='\0'; printf("Joystick: %s with %d buttons and %d axes found\n",joystickName,int(cNumButtons),int(cNumAxes)); } else printf("Joystick: Unknown joystick with %d buttons and %d axes found\n",int(cNumButtons),int(cNumAxes)); #endif /* Set device configuration: */ setNumTrackers(0,configFile); setNumButtons(cNumButtons,configFile); setNumValuators(cNumAxes,configFile); /* Initialize gain arrays: */ axisGains=new float[getNumValuators()]; for(int i=0; i<getNumValuators(); ++i) { char axisGainTag[40]; snprintf(axisGainTag,sizeof(axisGainTag),"./axisGain%d",i); axisGains[i]=configFile.retrieveValue<float>(axisGainTag,1.0f); } /* Initialize state arrays: */ buttonStates=new bool[getNumButtons()]; for(int i=0; i<getNumButtons(); ++i) buttonStates[i]=false; valuatorStates=new float[getNumValuators()]; for(int i=0; i<getNumValuators(); ++i) valuatorStates[i]=0.0f; /* Start device thread (joystick device cannot be disabled): */ startDeviceThread(); }
void HIDDevice::start(void) { /* Set device manager's button and valuator states to current states: */ { Threads::Mutex::Lock stateLock(stateMutex); for(int i=0;i<getNumButtons();++i) setButtonState(i,buttonStates[i]); for(int i=0;i<getNumValuators();++i) setValuatorState(i,valuatorStates[i]); /* Start reporting events to the device manager: */ reportEvents=true; } }
VRPNClient::VRPNClient(VRDevice::Factory* sFactory,VRDeviceManager* sDeviceManager,Misc::ConfigurationFile& configFile) :VRDevice(sFactory,sDeviceManager,configFile), VRPNConnection(configFile.retrieveString("./serverName").c_str(),configFile.retrieveValue<int>("./serverPort",3883)), reportEvents(false), trackerStates(0),trackerFlags(0),buttonStates(0),valuatorStates(0) { #ifdef VERBOSE printf("VRPNClient: Initializing senders..."); fflush(stdout); #endif /* Check if the z axis if incoming position data needs to be flipped: */ setFlipZAxis(configFile.retrieveValue<bool>("./flipZAxis",false)); /* Retrieve list of sender names: */ typedef std::vector<std::string> StringList; StringList senderNames=configFile.retrieveValue<StringList>("./senderNames"); /* Process all senders: */ int totalNumTrackers=0; int totalNumButtons=0; int totalNumValuators=0; for(StringList::const_iterator snIt=senderNames.begin();snIt!=senderNames.end();++snIt) { /* Go to the sender's section: */ configFile.setCurrentSection(snIt->c_str()); /* Read the number of trackers, buttons, and valuators for this sender: */ int numTrackers=configFile.retrieveValue<int>("./numTrackers",0); if(numTrackers>0) { requestTrackers(snIt->c_str(),totalNumTrackers,numTrackers); totalNumTrackers+=numTrackers; } int numButtons=configFile.retrieveValue<int>("./numButtons",0); if(numButtons>0) { requestButtons(snIt->c_str(),totalNumButtons,numButtons); totalNumButtons+=numButtons; } int numValuators=configFile.retrieveValue<int>("./numValuators",0); if(numValuators>0) { requestValuators(snIt->c_str(),totalNumValuators,numValuators); totalNumValuators+=numValuators; } /* Go back to device's section: */ configFile.setCurrentSection(".."); } #ifdef VERBOSE printf(" done\n"); fflush(stdout); #endif /* Set number of trackers, buttons, and valuators: */ setNumTrackers(totalNumTrackers,configFile); setNumButtons(totalNumButtons,configFile); setNumValuators(totalNumValuators,configFile); /* Read the initial position/orientation for all trackers: */ PositionOrientation defaultPosition=configFile.retrieveValue<PositionOrientation>("./defaultPosition",PositionOrientation::identity); /* Initialize the local state arrays: */ trackerStates=new TrackerState[getNumTrackers()]; trackerFlags=new int[getNumTrackers()]; for(int i=0;i<getNumTrackers();++i) { trackerStates[i].positionOrientation=defaultPosition; trackerStates[i].linearVelocity=LinearVelocity::zero; trackerStates[i].angularVelocity=AngularVelocity::zero; trackerFlags[i]=0x0; } buttonStates=new ButtonState[getNumButtons()]; for(int i=0;i<getNumButtons();++i) buttonStates[i]=false; valuatorStates=new ValuatorState[getNumValuators()]; for(int i=0;i<getNumValuators();++i) valuatorStates[i]=ValuatorState(0); /* Start device communication thread: */ startDeviceThread(); }
HIDDevice::HIDDevice(VRDevice::Factory* sFactory,VRDeviceManager* sDeviceManager,Misc::ConfigurationFile& configFile) :VRDevice(sFactory,sDeviceManager,configFile), deviceFd(-1), keyMap(0), absAxisMap(0),relAxisMap(0),axisConverters(0), reportEvents(false), buttonStates(0),valuatorStates(0) { /* First option: Open device by explicit event device file name: */ if(deviceFd<0) { std::string deviceFileName=configFile.retrieveString("./deviceFileName",""); if(deviceFileName!="") { #ifdef VERBOSE printf("HIDDevice: Opening device %s\n",deviceFileName.c_str()); fflush(stdout); #endif deviceFd=open(deviceFileName.c_str(),O_RDONLY); if(deviceFd<0) Misc::throwStdErr("HIDDevice: Unable to open device file \"%s\"",deviceFileName.c_str()); } } /* Second option: Open device by vendor ID / product ID: */ if(deviceFd<0) { std::string deviceVendorProductId=configFile.retrieveString("./deviceVendorProductId",""); if(deviceVendorProductId!="") { /* Split ID string into vendor ID / product ID: */ char* colonPtr; int vendorId=strtol(deviceVendorProductId.c_str(),&colonPtr,16); char* endPtr; int productId=strtol(colonPtr+1,&endPtr,16); if(*colonPtr!=':'||*endPtr!='\0'||vendorId<0||productId<0) Misc::throwStdErr("HIDDevice: Malformed vendorId:productId string \"%s\"",deviceVendorProductId.c_str()); #ifdef VERBOSE printf("HIDDevice: Searching device %04x:%04x\n",vendorId,productId); fflush(stdout); #endif deviceFd=findDevice(vendorId,productId); if(deviceFd<0) Misc::throwStdErr("HIDDevice: No device with vendorId:productId %04x:%04x found",vendorId,productId); } } /* Third option: Open device by device name: */ if(deviceFd<0) { std::string deviceName=configFile.retrieveString("./deviceName",""); if(deviceName!="") { #ifdef VERBOSE printf("HIDDevice: Searching device %s\n",deviceName.c_str()); fflush(stdout); #endif deviceFd=findDevice(deviceName.c_str()); if(deviceFd<0) Misc::throwStdErr("HIDDevice: No device with name \"%s\" found",deviceName.c_str()); } } /* Bail out if no device was found: */ if(deviceFd<0) Misc::throwStdErr("HIDDevice: No device specified"); /* Set number of trackers on device: */ setNumTrackers(0,configFile); /* Query all feature types of the device: */ unsigned char featureTypeBits[EV_MAX/8+1]; memset(featureTypeBits,0,EV_MAX/8+1); if(ioctl(deviceFd,EVIOCGBIT(0,sizeof(featureTypeBits)),featureTypeBits)<0) Misc::throwStdErr("HIDDevice: Unable to query device feature types"); /* Query the number of keys on the device: */ if(featureTypeBits[EV_KEY/8]&(1<<(EV_KEY%8))) { #ifdef VERBOSE printf("HIDDevice: Initializing buttons...\n"); fflush(stdout); #endif /* Query key features: */ unsigned char keyBits[KEY_MAX/8+1]; memset(keyBits,0,KEY_MAX/8+1); if(ioctl(deviceFd,EVIOCGBIT(EV_KEY,sizeof(keyBits)),keyBits)<0) Misc::throwStdErr("HIDDevice: Unable to query device key features"); /* Initialize the key translation array: */ keyMap=new int[KEY_MAX+1]; int numKeys=0; for(int i=0;i<=KEY_MAX;++i) { if(keyBits[i/8]&(1<<(i%8))) { keyMap[i]=numKeys; ++numKeys; } else keyMap[i]=-1; } /* Set number of buttons on device: */ #ifdef VERBOSE printf("HIDDevice: %d buttons found\n",numKeys); fflush(stdout); #endif setNumButtons(numKeys,configFile); } else setNumButtons(0,configFile); /* Count the number of absolute and relative axes: */ int numAxes=0; /* Query the number of absolute axes on the device: */ if(featureTypeBits[EV_ABS/8]&(1<<(EV_ABS%8))) { #ifdef VERBOSE printf("HIDDevice: Initializing absolute axes...\n"); fflush(stdout); #endif /* Query absolute axis features: */ unsigned char absAxisBits[ABS_MAX/8+1]; memset(absAxisBits,0,ABS_MAX/8+1); if(ioctl(deviceFd,EVIOCGBIT(EV_ABS,sizeof(absAxisBits)),absAxisBits)<0) Misc::throwStdErr("HIDDevice: Unable to query device absolute axis features"); /* Initialize the axis translation array: */ absAxisMap=new int[ABS_MAX+1]; int numAbsAxes=0; for(int i=0;i<=ABS_MAX;++i) { if(absAxisBits[i/8]&(1<<(i%8))) { absAxisMap[i]=numAxes; ++numAxes; ++numAbsAxes; } else absAxisMap[i]=-1; } #ifdef VERBOSE printf("HIDDevice: %d absolute axes found\n",numAbsAxes); fflush(stdout); #endif } /* Query the number of relative axes on the device: */ if(featureTypeBits[EV_REL/8]&(1<<(EV_REL%8))) { #ifdef VERBOSE printf("HIDDevice: Initializing relative axes...\n"); fflush(stdout); #endif /* Query relative axis features: */ unsigned char relAxisBits[REL_MAX/8+1]; memset(relAxisBits,0,REL_MAX/8+1); if(ioctl(deviceFd,EVIOCGBIT(EV_REL,sizeof(relAxisBits)),relAxisBits)<0) Misc::throwStdErr("HIDDevice: Unable to query device relative axis features"); /* Initialize the axis translation array: */ relAxisMap=new int[REL_MAX+1]; int numRelAxes=0; for(int i=0;i<=REL_MAX;++i) { if(relAxisBits[i/8]&(1<<(i%8))) { relAxisMap[i]=numAxes; ++numAxes; ++numRelAxes; } else relAxisMap[i]=-1; } #ifdef VERBOSE printf("HIDDevice: %d relative axes found\n",numRelAxes); fflush(stdout); #endif } /* Set number of valuators on device: */ setNumValuators(numAxes,configFile); /* Initialize axis converters: */ axisConverters=new AxisConverter[numAxes]; if(absAxisMap!=0) { /* Initialize absolute axis converters: */ #ifdef VERBOSE printf("HIDDevice: Initializing absolute axis converters\n"); fflush(stdout); #endif for(int i=0;i<=ABS_MAX;++i) if(absAxisMap[i]>=0) { /* Query configuration of this axis: */ input_absinfo absAxisConf; if(ioctl(deviceFd,EVIOCGABS(i),&absAxisConf)<0) Misc::throwStdErr("HIDDevice: Unable to query device absolute axis configuration"); #ifdef VERBOSE printf("Axis %2d: min %d, max %d, fuzz %d, flat %d\n",absAxisMap[i],absAxisConf.minimum,absAxisConf.maximum,absAxisConf.fuzz,absAxisConf.flat); fflush(stdout); #endif /* Initialize converter with queried values: */ AxisConverter& converter=axisConverters[absAxisMap[i]]; float mid=Math::mid(absAxisConf.minimum,absAxisConf.maximum); converter=AxisConverter(absAxisConf.minimum,mid-absAxisConf.flat,mid+absAxisConf.flat,absAxisConf.maximum); /* Override axis settings from configuration file: */ char axisSettingsTag[20]; snprintf(axisSettingsTag,sizeof(axisSettingsTag),"axis%dSettings",absAxisMap[i]); converter=configFile.retrieveValue<AxisConverter>(axisSettingsTag,converter); #ifdef VERBOSE printf("Axis %2d: %s\n",absAxisMap[i],Misc::ValueCoder<AxisConverter>::encode(converter).c_str()); fflush(stdout); #endif } } if(relAxisMap!=0) { /* Initialize relative axis converters: */ #ifdef VERBOSE printf("HIDDevice: Initializing relative axis converters\n"); fflush(stdout); #endif for(int i=0;i<=REL_MAX;++i) if(relAxisMap[i]>=0) { /* Initialize converter with default values: */ AxisConverter& converter=axisConverters[relAxisMap[i]]; converter=AxisConverter(-1.0f,1.0f); /* Override axis settings from configuration file: */ char axisSettingsTag[20]; snprintf(axisSettingsTag,sizeof(axisSettingsTag),"axis%dSettings",relAxisMap[i]); converter=configFile.retrieveValue<AxisConverter>(axisSettingsTag,converter); #ifdef VERBOSE printf("Axis %2d: %s\n",relAxisMap[i],Misc::ValueCoder<AxisConverter>::encode(converter).c_str()); fflush(stdout); #endif } } #if 0 /* Initialize gain arrays: */ valuatorGains=new float[getNumValuators()]; for(int i=0;i<getNumValuators();++i) { char valuatorGainTag[40]; snprintf(valuatorGainTag,sizeof(valuatorGainTag),"./valuatorGain%d",i); valuatorGains[i]=configFile.retrieveValue<float>(valuatorGainTag,1.0f); } #endif /* Initialize state arrays: */ buttonStates=new bool[getNumButtons()]; for(int i=0;i<getNumButtons();++i) buttonStates[i]=false; valuatorStates=new float[getNumValuators()]; for(int i=0;i<getNumValuators();++i) valuatorStates[i]=0.0f; /* Start device thread (HID device cannot be disabled): */ startDeviceThread(); }