Пример #1
0
void VRPNClient::start(void)
	{
	/* Set device manager's states to current states: */
	{
	Threads::Mutex::Lock stateLock(stateMutex);
	for(int i=0;i<getNumTrackers();++i)
		setTrackerState(i,trackerStates[i]);
	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;
	}
	}
Пример #2
0
void ViconTarsus::start(void)
	{
	/* Initialize tracker states: */
	for(int i=0;i<getNumTrackers();++i)
		{
		trackerStates[i].positionOrientation=PositionOrientation(Vector::zero,Rotation::identity);
		trackerStates[i].linearVelocity=Vrui::VRDeviceState::TrackerState::LinearVelocity::zero;
		trackerStates[i].angularVelocity=Vrui::VRDeviceState::TrackerState::AngularVelocity::zero;
		}
	
	/* Start device communication thread: */
	startDeviceThread();
	
	/* Activate streaming: */
	#ifdef VERBOSE
	printf("ViconTarsus: Starting continuous update mode\n");
	#endif
	pipe.write<int>(3);
	pipe.write<int>(0);
	}
Пример #3
0
void ArtDTrack::processAsciiData(void)
	{
	while(true)
		{
		/* Wait for the next data message from the DTrack daemon: */
		char messageBuffer[4096];
		size_t messageSize=dataSocket.receiveMessage(messageBuffer,sizeof(messageBuffer)-1);
		
		/* Newline-terminate the message: */
		messageBuffer[messageSize]='\n';
		
		/* Parse the received message: */
		char* mPtr=messageBuffer;
		char* mEnd=messageBuffer+messageSize;
		while(mPtr<mEnd)
			{
			/* Find the end of the current line: */
			char* lineEnd;
			for(lineEnd=mPtr;*lineEnd!='\n';++lineEnd)
				;
			
			/* Skip whitespace: */
			while(mPtr<lineEnd&&isspace(*mPtr))
				++mPtr;
			
			/* Get the line identifier: */
			char* idStart=mPtr;
			while(mPtr<lineEnd&&!isspace(*mPtr))
				++mPtr;
			
			/* Determine the type of the line: */
			int lineType=-1;
			if(mPtr-idStart==2&&strncasecmp(idStart,"6d",2)==0)
				lineType=0;
			else if(mPtr-idStart==3&&strncasecmp(idStart,"6df",3)==0)
				lineType=1;
			else if(mPtr-idStart==4&&strncasecmp(idStart,"6df2",4)==0)
				lineType=2;
			else if(mPtr-idStart==4&&strncasecmp(idStart,"6dmt",4)==0)
				lineType=3;
			else if(mPtr-idStart==2&&strncasecmp(idStart,"3d",2)==0)
				lineType=4;
			
			/* Process the line: */
			if(lineType>=0)
				{
				if(lineType==2)
					{
					/* Skip the number of defined flysticks: */
					readInt(mPtr);
					}
				
				/* Read the number of reported bodies: */
				int numBodies=readInt(mPtr);
				
				/* Parse each body: */
				for(int body=0;body<numBodies;++body)
					{
					/* Find the first opening bracket: */
					while(mPtr<lineEnd&&isspace(*mPtr))
						++mPtr;
					if(*mPtr!='[')
						break; // Ignore the rest of the line
					++mPtr;
					
					/* Read the body's ID: */
					int id=readInt(mPtr);
					Device* device=deviceIdToIndex[id]>=0?&devices[deviceIdToIndex[id]]:0;
					
					/* Skip the quality value: */
					float(readFloat(mPtr));
					
					if(lineType==1||lineType==3)
						{
						/* Read the button bit flag: */
						unsigned int bits=readUint(mPtr);
						
						if(device!=0)
							{
							/* Set the button states: */
							for(int i=0;i<32&&i<device->numButtons;++i)
								{
								setButtonState(device->firstButtonIndex+i,(bits&0x1)!=0x0);
								bits>>=1;
								}
							}
						}
					
					int numButtons=0;
					int numValuators=0;
					if(lineType==2)
						{
						/* Read the number of buttons and valuators: */
						numButtons=readInt(mPtr);
						numValuators=readInt(mPtr);
						}
					
					/* Find the first closing bracket: */
					while(mPtr<lineEnd&&isspace(*mPtr))
						++mPtr;
					if(*mPtr!=']')
						break; // Ignore the rest of the line
					++mPtr;
					
					/* Find the second opening bracket: */
					while(mPtr<lineEnd&&isspace(*mPtr))
						++mPtr;
					if(*mPtr!='[')
						break; // Ignore the rest of the line
					++mPtr;
					
					/* Read the body's position: */
					Vector pos;
					for(int i=0;i<3;++i)
						pos[i]=VScalar(readFloat(mPtr));
					
					Rotation orient=Rotation::identity;
					if(lineType==0||lineType==1)
						{
						/* Read the body's orientation angles: */
						VScalar angles[3];
						for(int i=0;i<3;++i)
							angles[i]=VScalar(readFloat(mPtr));
						
						/* Calculate the body's orientation quaternion: */
						orient*=Rotation::rotateX(Math::rad(angles[0]));
						orient*=Rotation::rotateY(Math::rad(angles[1]));
						orient*=Rotation::rotateZ(Math::rad(angles[2]));
						}
					
					/* Find the second closing bracket: */
					while(mPtr<lineEnd&&isspace(*mPtr))
						++mPtr;
					if(*mPtr!=']')
						break; // Ignore the rest of the line
					++mPtr;
					
					if(lineType!=4)
						{
						/* Find the third opening bracket: */
						while(mPtr<lineEnd&&isspace(*mPtr))
							++mPtr;
						if(*mPtr!='[')
							break; // Ignore the rest of the line
						++mPtr;
						}
					
					if(lineType==2||lineType==3)
						{
						/* Read the body's orientation matrix (yuck!): */
						Geometry::Matrix<VScalar,3,3> matrix;
						for(int j=0;j<3;++j)
							for(int i=0;i<3;++i)
								matrix(i,j)=VScalar(readFloat(mPtr));
						
						/* Calculate the body's orientation quaternion: */
						orient=Rotation::fromMatrix(matrix);
						
						/* Find the third closing bracket: */
						while(mPtr<lineEnd&&isspace(*mPtr))
							++mPtr;
						if(*mPtr!=']')
							break; // Ignore the rest of the line
						++mPtr;
						}
					else if(lineType!=4)
						{
						/* Ignore the body's orientation matrix: */
						while(mPtr<lineEnd&&*mPtr!=']')
							++mPtr;
						if(*mPtr!=']') // Ignore the rest of the line
							break;
						}
					
					if(lineType==2)
						{
						/* Find the fourth opening bracket: */
						while(mPtr<lineEnd&&isspace(*mPtr))
							++mPtr;
						if(*mPtr!='[')
							break; // Ignore the rest of the line
						++mPtr;
						
						/* Read the flystick's button bits: */
						for(int bitIndex=0;bitIndex<numButtons;bitIndex+=32)
							{
							/* Read the next button bit mask: */
							unsigned int bits=readUint(mPtr);
							
							if(device!=0)
								{
								/* Set the device's button values: */
								for(int i=0;i<32;++i)
									{
									/* Set the button state if the button is valid: */
									if(bitIndex+i<device->numButtons)
										setButtonState(device->firstButtonIndex+bitIndex+i,(bits&0x1)!=0x0);
									bits>>=1;
									}
								}
							}
						
						/* Read the flystick's valuator values: */
						for(int i=0;i<numValuators;++i)
							{
							/* Read the next valuator value: */
							float value=float(readFloat(mPtr));
							
							/* Set the valuator value if the valuator is valid: */
							if(device!=0&&i<device->numValuators)
								setValuatorState(device->firstValuatorIndex+i,value);
							}
						
						/* Find the fourth closing bracket: */
						while(mPtr<lineEnd&&isspace(*mPtr))
							++mPtr;
						if(*mPtr!=']')
							break; // Ignore the rest of the line
						++mPtr;
						}
					
					/* Check if this body has been configured as a device: */
					if(device!=0)
						{
						/* Set the device's tracker state: */
						trackerStates[deviceIdToIndex[id]].positionOrientation=PositionOrientation(pos,orient);
						}
					}
				}
			
			/* Go to the start of the next line: */
			mPtr=lineEnd+1;
			}
		
		/* Update all tracker states (including those that were not updated): */
		for(int i=0;i<getNumTrackers();++i)
			setTrackerState(i,trackerStates[i]);
		}
Пример #4
0
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();
	}
Пример #5
0
void ViconTarsus::deviceThreadMethod(void)
	{
	while(true)
		{
		/* Wait for the next packet from the server: */
		int packetKind=pipe.read<int>();
		if(pipe.read<int>()==1) // Ignore request packets
			{
			switch(packetKind)
				{
				case 0:
				case 4:
					/* Shut down the thread method: */
					return;
				
				case 2:
					{
					/* Read the data packet: */
					int numPacketChannels=pipe.read<int>();
					if(numPacketChannels>numChannels)
						{
						/* Read the relevant channels: */
						pipe.read<double>(channelPacketBuffer,numChannels);
						
						/* Ignore all spurious channels: */
						for(int i=numChannels;i<numPacketChannels;++i)
							pipe.read<double>();
						numPacketChannels=numChannels;
						}
					else
						{
						/* Read all channels: */
						pipe.read<double>(channelPacketBuffer,numPacketChannels);
						}
					
					/* Process the data packet: */
					for(int trackerIndex=0;trackerIndex<getNumTrackers();++trackerIndex)
						{
						/* Get the tracker's position: */
						Vector translation;
						bool valid=true;
						for(int i=0;i<3;++i)
							{
							if(trackerChannelIndices[trackerIndex*6+i]<numPacketChannels)
								translation[i]=VScalar(channelPacketBuffer[trackerChannelIndices[trackerIndex*6+i]]);
							else
								valid=false;
							}
						
						if(valid)
							{
							if(trackerSixDofs[trackerIndex])
								{
								/* Get the tracker's orientation: */
								PositionOrientation::Rotation::Vector rotation;
								bool sixDof=true;
								for(int i=0;i<3;++i)
									{
									if(trackerChannelIndices[trackerIndex*6+3+i]<numPacketChannels)
										rotation[i]=RScalar(channelPacketBuffer[trackerChannelIndices[trackerIndex*6+3+i]]);
									else
										sixDof=false;
									}
								
								if(sixDof)
									{
									/* Set the 6-DOF tracker state: */
									trackerStates[trackerIndex].positionOrientation=PositionOrientation(translation,Rotation::rotateScaledAxis(rotation));
									}
								else
									{
									/* Set the 6-DOF tracker state with the previous orientation: */
									trackerStates[trackerIndex].positionOrientation=PositionOrientation(translation,trackerStates[trackerIndex].positionOrientation.getRotation());
									}
								}
							else
								{
								/* Set the 3-DOF tracker state: */
								trackerStates[trackerIndex].positionOrientation=PositionOrientation(translation,Rotation::identity);
								}
							}
						}
					
					/* Update all tracker states (including those that were not updated): */
					for(int i=0;i<getNumTrackers();++i)
						setTrackerState(i,trackerStates[i]);
					break;
					}
				
				default:
					/* Ignore the packet: */
					;
				}
			}
		}
	}
Пример #6
0
ViconTarsus::ViconTarsus(VRDevice::Factory* sFactory,VRDeviceManager* sDeviceManager,Misc::ConfigurationFile& configFile)
	:VRDevice(sFactory,sDeviceManager,configFile),
	 pipe(configFile.retrieveString("./serverName"),configFile.retrieveValue<int>("./serverPort",800),Comm::TCPPipe::LittleEndian),
	 trackerChannelIndices(0),
	 trackerSixDofs(0),
	 trackerMap(0),
	 channelPacketBuffer(0),
	 trackerStates(0)
	{
	/* Read the list of tracked bodies: */
	std::vector<std::string> trackedBodies=configFile.retrieveValue<std::vector<std::string> >("./trackedBodies");
	
	/* Set tracker's layout: */
	setNumTrackers(trackedBodies.size(),configFile);
	
	/* Initialize the tracker channel index array: */
	trackerChannelIndices=new int[getNumTrackers()*6];
	for(int i=0;i<getNumTrackers()*6;++i)
		trackerChannelIndices[i]=-1;
	
	/* Send info request to server: */
	#ifdef VERBOSE
	printf("ViconTarsus: Requesting info packet\n");
	#endif
	pipe.write<int>(1); // Info
	pipe.write<int>(0); // Request
	
	/* Wait for the server's reply: */
	if(pipe.read<int>()!=1)
		Misc::throwStdErr("ViconTarsus: Unable to connect to tracking server at %s",pipe.getPeerHostname().c_str());
	if(pipe.read<int>()!=1)
		Misc::throwStdErr("ViconTarsus: Unable to connect to tracking server at %s",pipe.getPeerHostname().c_str());
	
	/* Read the info packet's data: */
	numChannels=pipe.read<int>();
	#ifdef VERBOSE
	printf("ViconTarsus: Server reports %d channels\n",numChannels);
	#endif
	for(int channelIndex=0;channelIndex<numChannels;++channelIndex)
		{
		/* Read the channel descriptor (fortunately, Vicon's string protocol is compatible to TCPPipe's): */
		std::string channelName=pipe.read<std::string>();
		#ifdef VERBOSE
		printf("ViconTarsus: Server channel %2d: %s\n",channelIndex,channelName.c_str());
		#endif
		
		/* Parse the channel name: */
		const char* nameStart=channelName.c_str();
		const char* nameEnd;
		for(nameEnd=nameStart;*nameEnd!='\0'&&*nameEnd!=' '&&*nameEnd!='-'&&*nameEnd!='<'&&*nameEnd!='>';++nameEnd)
			;
		const char* codeStart;
		for(codeStart=nameEnd;*codeStart!='\0'&&*codeStart!='<';++codeStart)
			;
		const char* codeEnd;
		for(codeEnd=codeStart;*codeEnd!='\0'&&*codeEnd!='>';++codeEnd)
			;
		
		/* Check if the channel name is well-formed: */
		if(*codeStart=='<'&&*codeEnd=='>')
			{
			std::string code(codeStart+1,codeEnd);
			
			/* Check if the channel encodes a body parameter or a marker parameter: */
			if(code[0]=='P'||code[0]=='A'||code[0]=='T')
				{
				/* Check if the name corresponds to a tracked body: */
				std::string name(nameStart,nameEnd);
				int bodyIndex;
				for(bodyIndex=0;bodyIndex<getNumTrackers();++bodyIndex)
					if(trackedBodies[bodyIndex]==name)
						break;
				if(bodyIndex<getNumTrackers())
					{
					/* Parse the channel code: */
					if(code=="P-X"||code=="T-X")
						trackerChannelIndices[bodyIndex*6+0]=channelIndex;
					else if(code=="P-Y"||code=="T-Y")
						trackerChannelIndices[bodyIndex*6+1]=channelIndex;
					else if(code=="P-Z"||code=="T-Z")
						trackerChannelIndices[bodyIndex*6+2]=channelIndex;
					else if(code=="A-X")
						trackerChannelIndices[bodyIndex*6+3]=channelIndex;
					else if(code=="A-Y")
						trackerChannelIndices[bodyIndex*6+4]=channelIndex;
					else if(code=="A-Z")
						trackerChannelIndices[bodyIndex*6+5]=channelIndex;
					}
				}
			}
		}
	
	/* Check if all requested trackers have channels associated with them: */
	trackerSixDofs=new bool[getNumTrackers()];
	int numSixDofTrackers=0;
	for(int bodyIndex=0;bodyIndex<getNumTrackers();++bodyIndex)
		{
		/* Check if the tracker has 3-DOF data: */
		bool valid=true;
		for(int i=0;i<3;++i)
			if(trackerChannelIndices[bodyIndex*6+i]==-1)
				valid=false;
		if(!valid)
			Misc::throwStdErr("ViconTarsus: Insufficient data to track body %s",trackedBodies[bodyIndex].c_str());
		
		/* Check if the tracker has 6-DOF data (for later): */
		bool sixDof=true;
		for(int i=3;i<6;++i)
			if(trackerChannelIndices[bodyIndex*6+i]==-1)
				sixDof=false;
		trackerSixDofs[bodyIndex]=sixDof;
		if(sixDof)
			++numSixDofTrackers;
		}
	#ifdef VERBOSE
	printf("ViconTarsus: Tracking %d 3-DOF tracker(s) and %d 6-DOF tracker(s)\n",getNumTrackers()-numSixDofTrackers,numSixDofTrackers);
	#endif
	
	/* Construct the tracker map: */
	trackerMap=new std::pair<int,int>[numChannels];
	for(int i=0;i<numChannels;++i)
		trackerMap[i]=std::pair<int,int>(-1,-1);
	for(int bodyIndex=0;bodyIndex<getNumTrackers();++bodyIndex)
		for(int i=0;i<6;++i)
			{
			if(trackerChannelIndices[bodyIndex*6+i]!=-1)
				trackerMap[trackerChannelIndices[bodyIndex*6+i]]=std::pair<int,int>(bodyIndex,i);
			}
	
	/* Initialize the channel packet buffer: */
	channelPacketBuffer=new double[numChannels];
	
	/* Initialize tracker states: */
	trackerStates=new Vrui::VRDeviceState::TrackerState[getNumTrackers()];
	}