Difference between revisions of "NaviTrack Tutorial:Integrating:Passing coordinates data"
(13 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
=What you need to do= | =What you need to do= | ||
+ | #Create NaviTrack module to provide a node that can be accessed by you application. | ||
#Modify your application to push and pull NaviTrack events cyclically with certain interval. | #Modify your application to push and pull NaviTrack events cyclically with certain interval. | ||
− | |||
#Create NaviTrack configuration XML file to build tree structure of data flow. | #Create NaviTrack configuration XML file to build tree structure of data flow. | ||
=Sending side= | =Sending side= | ||
==Modify MyTutorialModule== | ==Modify MyTutorialModule== | ||
+ | To send data through NaviTrack, it is necessary to generate a new event, which contains the data. | ||
+ | The following code is implemented into MyTutorialModule to be called from your application. | ||
+ | void MyTutorialModule::setTracker(std::vector<float> pos,std::vector<float> quat) | ||
+ | { | ||
+ | if (pos.size() != 3 || quat.size() != 4) { | ||
+ | std::cout << "MyTutorialModule::setTracker(): illegal vector size." << std::endl; | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | if(source!=NULL) | ||
+ | { | ||
+ | ot::Event *event = new ot::Event(); | ||
+ | event->setAttribute("position",pos); | ||
+ | event->setAttribute("orientation",quat); | ||
+ | event->timeStamp(); | ||
+ | source->updateObservers( *event ); | ||
+ | } | ||
+ | } | ||
+ | |||
==pushpos.cxx== | ==pushpos.cxx== | ||
+ | The core part for sending coordinate data is as follows: | ||
+ | |||
+ | MyTutorialModule* mtm = (MyTutorialModule*) context.getModule("MyTutorialConfig"); | ||
+ | |||
+ | while (stopflag == 0) { | ||
+ | |||
+ | // set coordinate data (pos, quat) here | ||
+ | |||
+ | .... | ||
+ | |||
+ | if (mtm) { | ||
+ | mtm->setTracker(pos, quat); // call NaviTrack module member function to set data | ||
+ | } | ||
+ | |||
+ | stopflag = context.loopOnce(); // push and pull evets for NaviTrack | ||
+ | usleep(rate); | ||
+ | } | ||
=Receiving side= | =Receiving side= | ||
− | ==Modify MyTutorialSink== | + | ==Modify MyTutorialSink and MyTutorialModule== |
+ | |||
+ | An event to pull coordinate data is handled in onEventGenerated() function in MyTutorialSink. | ||
+ | There are two steps to pass the coordinate data to your application: STEP 1) onEventGenerated() stores the data into member variables in MyTutorialSinke; STEP 2) your application fetch the data from MyTutorialSink through MyTutorialModule. | ||
+ | |||
+ | Bellows are examples to implement STEP 1 and STEP 2. | ||
+ | |||
+ | MyTutorialSink.h: Add member variables to hold the coordinate data: | ||
+ | private: | ||
+ | std::vector<float> position; | ||
+ | std::vector<float> orientation; | ||
+ | |||
+ | MyTutorialSink.cxx: | ||
+ | void MyTutorialSink::onEventGenerated( Event& event, Node& generator) | ||
+ | { | ||
+ | if (event.hasAttribute("position")) | ||
+ | for(int i = 0; i < 3; i ++) | ||
+ | position[i]=event.getPosition()[i]; | ||
+ | else | ||
+ | { | ||
+ | position[0]=0.0; | ||
+ | position[1]=0.0; | ||
+ | position[2]=0.0; | ||
+ | } | ||
+ | |||
+ | if (event.hasAttribute("orientation")) | ||
+ | { | ||
+ | for (int i = 0; i < 4; i ++) { | ||
+ | orientation[i]= event.getOrientation()[i]; | ||
+ | } | ||
+ | std::cout << "orientation !!!" << std::endl; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | orientation[0]=0.0; | ||
+ | orientation[1]=0.0; | ||
+ | orientation[2]=0.0; | ||
+ | orientation[3]=0.0; | ||
+ | } | ||
+ | } | ||
+ | |||
==pullpos.cxx== | ==pullpos.cxx== | ||
+ | The core part for receiving coordinate is as follows: | ||
+ | |||
+ | MyTutorialModule* mtm; | ||
+ | MyTutorialSink* mts; | ||
+ | mtm = (MyTutorialModule*) context.getModule("MyTutorialConfig"); | ||
+ | if (mtm == NULL) { | ||
+ | exit(-1); | ||
+ | } | ||
+ | mts = mtm->getSink(); | ||
+ | if (mts == NULL) { | ||
+ | exit(-1); | ||
+ | } | ||
+ | int stopflag = 0; | ||
+ | |||
+ | while (stopflag == 0) { | ||
+ | |||
+ | stopflag = context.loopOnce(); | ||
+ | |||
+ | if (mts) { | ||
+ | ... | ||
+ | (get data here) | ||
+ | ... | ||
+ | } | ||
+ | |||
+ | OSUtils::sleep(interval); | ||
+ | } | ||
+ | |||
+ | context.close(); | ||
=Testing= | =Testing= | ||
Line 17: | Line 121: | ||
==Configure NaviTrack XML files== | ==Configure NaviTrack XML files== | ||
===tutorial_source.xml (for pushpos)=== | ===tutorial_source.xml (for pushpos)=== | ||
+ | <?xml version="1.0" encoding="UTF-8"?> | ||
+ | <!DOCTYPE OpenTracker SYSTEM "../share/navitrack.dtd"> | ||
+ | <OpenTracker> | ||
+ | |||
+ | <configuration> | ||
+ | <MyTutorialConfig name="MyModule"/> | ||
+ | <NetworkSourceConfig name="Network"/> | ||
+ | <!--<FileConfig/>--> | ||
+ | </configuration> | ||
+ | |||
+ | <NetworkSink mode="unicast" number="1" port="12345"> | ||
+ | <!--<FileSink file="temp.dat">--> | ||
+ | <MyTutorialSource/> | ||
+ | <!--</FileSink>--> | ||
+ | </NetworkSink> | ||
+ | |||
+ | </OpenTracker> | ||
===tutorial_sink.xml (for pullpos)=== | ===tutorial_sink.xml (for pullpos)=== | ||
+ | <?xml version="1.0" encoding="UTF-8"?> | ||
+ | <!DOCTYPE OpenTracker SYSTEM "../share/navitrack.dtd"> | ||
+ | <OpenTracker> | ||
+ | |||
+ | <configuration> | ||
+ | <MyTutorialConfig name="MyModule"/> | ||
+ | <NetworkConfig name="Network"/> | ||
+ | <!--<FileConfig realtime="true" loop="true"/>--> | ||
+ | </configuration> | ||
+ | |||
+ | <MyTutorialSink> | ||
+ | <NetworkSource mode="unicast" number="1" address="b2_d4_8" port="12345"/> | ||
+ | <!--<FileSource file="temp.dat"/>--> | ||
+ | </MyTutorialSink> | ||
+ | |||
+ | </OpenTracker> | ||
==Run the programs== | ==Run the programs== |
Latest revision as of 16:22, 14 June 2007
Home < NaviTrack Tutorial:Integrating:Passing coordinates dataWhat you need to do
- Create NaviTrack module to provide a node that can be accessed by you application.
- Modify your application to push and pull NaviTrack events cyclically with certain interval.
- Create NaviTrack configuration XML file to build tree structure of data flow.
Sending side
Modify MyTutorialModule
To send data through NaviTrack, it is necessary to generate a new event, which contains the data. The following code is implemented into MyTutorialModule to be called from your application.
void MyTutorialModule::setTracker(std::vector<float> pos,std::vector<float> quat) { if (pos.size() != 3 || quat.size() != 4) { std::cout << "MyTutorialModule::setTracker(): illegal vector size." << std::endl; return; } if(source!=NULL) { ot::Event *event = new ot::Event(); event->setAttribute("position",pos); event->setAttribute("orientation",quat); event->timeStamp(); source->updateObservers( *event ); } }
pushpos.cxx
The core part for sending coordinate data is as follows:
MyTutorialModule* mtm = (MyTutorialModule*) context.getModule("MyTutorialConfig"); while (stopflag == 0) { // set coordinate data (pos, quat) here .... if (mtm) { mtm->setTracker(pos, quat); // call NaviTrack module member function to set data } stopflag = context.loopOnce(); // push and pull evets for NaviTrack usleep(rate); }
Receiving side
Modify MyTutorialSink and MyTutorialModule
An event to pull coordinate data is handled in onEventGenerated() function in MyTutorialSink. There are two steps to pass the coordinate data to your application: STEP 1) onEventGenerated() stores the data into member variables in MyTutorialSinke; STEP 2) your application fetch the data from MyTutorialSink through MyTutorialModule.
Bellows are examples to implement STEP 1 and STEP 2.
MyTutorialSink.h: Add member variables to hold the coordinate data:
private: std::vector<float> position; std::vector<float> orientation;
MyTutorialSink.cxx:
void MyTutorialSink::onEventGenerated( Event& event, Node& generator) { if (event.hasAttribute("position")) for(int i = 0; i < 3; i ++) position[i]=event.getPosition()[i]; else { position[0]=0.0; position[1]=0.0; position[2]=0.0; } if (event.hasAttribute("orientation")) { for (int i = 0; i < 4; i ++) { orientation[i]= event.getOrientation()[i]; } std::cout << "orientation !!!" << std::endl; } else { orientation[0]=0.0; orientation[1]=0.0; orientation[2]=0.0; orientation[3]=0.0; } }
pullpos.cxx
The core part for receiving coordinate is as follows:
MyTutorialModule* mtm; MyTutorialSink* mts; mtm = (MyTutorialModule*) context.getModule("MyTutorialConfig"); if (mtm == NULL) { exit(-1); } mts = mtm->getSink(); if (mts == NULL) { exit(-1); } int stopflag = 0; while (stopflag == 0) { stopflag = context.loopOnce(); if (mts) { ... (get data here) ... } OSUtils::sleep(interval); } context.close();
Testing
Let's try to send position data from pushpos to pullpos program through network.
tutorial_source.xml (for pushpos)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE OpenTracker SYSTEM "../share/navitrack.dtd"> <OpenTracker> <configuration> <MyTutorialConfig name="MyModule"/> <NetworkSourceConfig name="Network"/> </configuration> <NetworkSink mode="unicast" number="1" port="12345"> <MyTutorialSource/> </NetworkSink> </OpenTracker>
tutorial_sink.xml (for pullpos)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE OpenTracker SYSTEM "../share/navitrack.dtd"> <OpenTracker> <configuration> <MyTutorialConfig name="MyModule"/> <NetworkConfig name="Network"/> </configuration> <MyTutorialSink> <NetworkSource mode="unicast" number="1" address="b2_d4_8" port="12345"/> </MyTutorialSink> </OpenTracker>
Run the programs
Open two terminals and go to the directory where the programs exists.
Terminal 1 (pushpos: sending side)
$ ./pushpos tutorial_source.xml
Terminal 2 (pullpos: receiving side)
$ ./pullpos tutorial_sink.xml
Back to Integrating into your application.