int main(int argc, char ** argv) { gtk_init(&argc, &argv); // g_pConnection=new ::vrpn_Connection; g_pConnection=vrpn_create_server_connection(); g_pButtonServer=new ::vrpn_Button_Server(_vrpn_peripheral_name_, g_pConnection, 10); g_pAnalogServer=new ::vrpn_Analog_Server(_vrpn_peripheral_name_, g_pConnection); g_pAnalogServer->setNumChannels(10); ::GtkBuilder* l_pInterface=gtk_builder_new(); // glade_xml_new("../share/openvibe-applications/vrpn-simulator/interface.ui", "window", NULL); gtk_builder_add_from_file(l_pInterface, "../share/openvibe-applications/vrpn-simulator/interface.ui", NULL); ::GtkWidget* l_pMainWindow=GTK_WIDGET(gtk_builder_get_object(l_pInterface, "window")); ::GtkWidget* l_pHBoxButton=GTK_WIDGET(gtk_builder_get_object(l_pInterface, "hbox_button")); ::GtkWidget* l_pHBoxAnalog=GTK_WIDGET(gtk_builder_get_object(l_pInterface, "hbox_analog")); g_signal_connect(G_OBJECT(l_pMainWindow), "destroy", gtk_main_quit, NULL); gtk_container_foreach(GTK_CONTAINER(l_pHBoxButton), fConnectCB, NULL); gtk_container_foreach(GTK_CONTAINER(l_pHBoxAnalog), fConnectCB, NULL); gtk_builder_connect_signals(l_pInterface, NULL); std::cout << "got " << g_iAnalogCount << " analogs...\n"; std::cout << "got " << g_iButtonCount << " buttons...\n"; g_idle_add(fIdleApplicationLoop, NULL); gtk_widget_show(l_pMainWindow); gtk_main(); delete g_pAnalogServer; delete g_pButtonServer; delete g_pConnection; return 0; }
int main (int argc, char ** argv) { int port = vrpn_DEFAULT_LISTEN_PORT_NO; vrpn_Connection * connection; char con_name[1024]; sprintf(con_name, ":%d", port); connection = vrpn_create_server_connection(con_name, NULL, NULL); vrpn_Tracker * nt; if ((nt = new vrpn_Tracker_NULL("Tracker0", connection, 2, 2.0)) == NULL) { fprintf(stderr,"Can't create new vrpn_Tracker_NULL\n"); return -1; } fprintf(stderr,"Created new NULL Tracker\nUse 'vrpn_print_devices Tracker0@localhost' in vrpn/client_src/pc_linux to see results\n"); while (1) { nt->mainloop(); connection->mainloop(); // Sleep so we don't eat the CPU vrpn_SleepMsecs(1); } }
int main (int argc, char* argv[]) { if (argc != 2) { fprintf(stderr, "Must pass a device name as the sole argument\n"); return 1; } char msg[MAX]; vrpn_Connection *sc = vrpn_create_server_connection(); vrpn_Text_Sender *s = new vrpn_Text_Sender(argv[1], sc); while (1) { while (!sc->connected()) { // wait until we've got a connection sc->mainloop(); } while (sc->connected()) { printf("Please enter the message:\n"); if (scanf("%s", msg) != 1) { fprintf(stderr, "No message entered\n"); return(-1); } s->send_message(msg, vrpn_TEXT_NORMAL); s->mainloop(); sc->mainloop(); } } }
void vrpn_Forwarder_Server::start_remote_forwarding (vrpn_int32 remote_port) { vrpn_Forwarder_List * fp; // Make sure it isn't already there for (fp = d_myForwarders; fp; fp = fp->next) if (fp->port == remote_port) { fprintf(stderr, "vrpn_Forwarder_Server::start_remote_forwarding: " "Already open on port %d.\n", remote_port); return; } // Create it and add it to the list fp = new vrpn_Forwarder_List; fp->port = remote_port; fp->connection = vrpn_create_server_connection(remote_port); fp->forwarder = new vrpn_ConnectionForwarder (d_connection, fp->connection); fp->next = d_myForwarders; d_myForwarders = fp; //fprintf(stderr, "vrpn_Forwarder_Server::start_remote_forwarding: " //"On port %d.\n", remote_port); }
DeviceThreadVRPNAnalog::DeviceThreadVRPNAnalog(DeviceThreadAnalogCreator deviceMaker) { // Initialize things we don't set in this constructor m_genericServer = NULL; // Construct a loopback connection for us to use. m_connection = vrpn_create_server_connection("loopback:"); // Construct the server object and client object, having them // use the connection and the same name. std::string deviceName = "DeviceThread"; m_server = deviceMaker(deviceName.c_str(), m_connection); m_remote = new vrpn_Analog_Remote(deviceName.c_str(), m_connection); if (!m_connection || !m_server || !m_remote) { delete m_remote; m_remote = NULL; delete m_server; m_server = NULL; if (m_connection) { m_connection->removeReference(); m_connection = NULL; } m_broken = true; return; } // Connect the callback handler for the Analog remote to our static // function that handles pushing the reports onto the vector of // reports, giving it a pointer to this class instance. m_remote->register_change_handler(this, HandleAnalogCallback); // Start our thread running StartThread(); }
int main (int argc, char * argv []) { unsigned controller = 0, sendBody = 0, sendUser = 1; sprintf(trackerName, "%s", TRACKER_NAME); // The only command line argument is a string for the configuration if (argc > 1) { // Get the arguments (device_name, controller_index, bodyFrame, userFrame) if (sscanf(argv[1], "%511s%u%u%u", trackerName, &controller, &sendBody, &sendUser) != 4) { fprintf(stderr, "Bad vrpn_Freespace line: %s\n", argv[1]); fprintf(stderr, "Expect: deviceName controllerIndex bodyFrame userFrame\n"); return -1; } } // Correctly handle command line input addControlHandler(); //--------------------------------------------------------------------- // explicitly open the connection connection = vrpn_create_server_connection(CONNECTION_PORT); //--------------------------------------------------------------------- // create a freespace tracker for the first device. printf("Tracker's name is %s.\n", trackerName); freespace = vrpn_Freespace::create(trackerName, connection, 0, (sendBody != 0), (sendUser != 0)); if (!freespace) { fprintf(stderr, "Error opening freespace device: %s\n", trackerName); return 1; } // the freespace device exposes 3 vrpn interfaces. Tracker, buttons, // and a Dial (scrollwheel) // libfreespace also reports values like a mouse (dx/dy), though the // vrpn messages are not currently sent. Considering the client side doesn't // have a notion of a mouse, but treats it as an analog device, I didn't feel // compelled to generate the messages, though the additional code is fairly // straight forward create_and_link_tracker_remote(trackerName); create_and_link_button_remote(trackerName); create_and_link_dial_remote(trackerName); while ( !quit ) { // Let the servers, clients and connection do their things freespace->mainloop(); rtkr->mainloop(); connection->mainloop(); // Sleep for 1ms each iteration so we don't eat the CPU vrpn_SleepMsecs(1); } delete freespace; delete rtkr; delete connection; return 0; } /* main */
int main (int argc, char * argv []) { bool sendBody = 0, sendUser = 1; // painfully simple CL options to turn on/off body/user frame reports if (argc > 1) { sendBody = atoi(argv[1]); if (argc > 2) { sendUser = atoi(argv[2]); } } //--------------------------------------------------------------------- // explicitly open the connection connection = vrpn_create_server_connection(CONNECTION_PORT); //--------------------------------------------------------------------- // Open the tracker server, using this connection, 2 sensors, update 1 times/sec printf("Tracker's name is %s.\n", TRACKER_NAME); // create a freespace tracker for the first device. freespace = vrpn_Freespace::create(TRACKER_NAME, connection, 0, sendBody, sendUser); if (!freespace) { fprintf(stderr, "Error opening freespace device\n"); return 1; } // the freespace device exposes 3 vrpn interfaces. Tracker, buttons, // and a Dial (scrollwheel) // libfreespace also reports values like a mouse (dx/dy), though the // vrpn messages are not currently sent. Considering the client side doesn't // have a notion of a mouse, but treats it as an analog device, I didn't feel // compelled to generate the messages, though the additional code is fairly // straight forward create_and_link_tracker_remote(); create_and_link_button_remote(); create_and_link_dial_remote(); /* * main interactive loop */ while ( 1 ) { // Let the servers, clients and connection do their things freespace->mainloop(); rtkr->mainloop(); connection->mainloop(); // Sleep for 1ms each iteration so we don't eat the CPU vrpn_SleepMsecs(1); } return 0; } /* main */
int main (int argc, char ** argv) { if (argc != 2) { fprintf(stderr, "Must pass a port number as the sole argument\n"); return 1; } vrpn_Connection * c; c = vrpn_create_server_connection(atoi(argv[1])); vrpn_Shared_int32_Server a ("a", 0, VRPN_SO_DEFER_UPDATES); a.setSerializerPolicy(vrpn_DENY_REMOTE); c->mainloop(); a.bindConnection(c); a.register_handler(¬eChange, &a); c->mainloop(); printf("a = %d.\n", a.value()); c->mainloop(); a = 3; c->mainloop(); printf("a = %d.\n", a.value()); c->mainloop(); a = -3; c->mainloop(); printf("a = %d.\n", a.value()); c->mainloop(); while (c->doing_okay()) { c->mainloop(); } printf("C is not OK; shutting down.\n"); delete c; return 2; }
bool init_server_code(void) { if ( (svrcon = vrpn_create_server_connection()) == NULL) { fprintf(stderr, "Could not open server connection\n"); return false; } if ( (svr = new vrpn_Imager_Server("TestImage", svrcon, image_x_size, image_y_size)) == NULL) { fprintf(stderr, "Could not open Imager Server\n"); return false; } if ( (svrchan = svr->add_channel("value", "unsigned16bit", 0, (float)(pow(2.0,16)-1))) == -1) { fprintf(stderr, "Could not add channel to server image\n"); return false; } return true; }
int main (int argc, char ** argv) { vrpn_Connection * c; vrpn_Mutex_Server * me; int portno = vrpn_DEFAULT_LISTEN_PORT_NO; if (argc > 2) { portno = atoi(argv[2]); } char con_name[512]; sprintf(con_name, "localhost:%d", portno); c = vrpn_create_server_connection(con_name); me = new vrpn_Mutex_Server (argv[1], c); while (1) { me->mainloop(); } }
int main(int argc, char ** argv) { #if defined TARGET_HAS_ThirdPartyVRPN const int l_nChannels = 8; gtk_init(&argc, &argv); // g_pConnection=new ::vrpn_Connection; g_pConnection=vrpn_create_server_connection(); g_pButtonServer=new ::vrpn_Button_Server(_vrpn_peripheral_name_, g_pConnection, l_nChannels); g_pAnalogServer=new ::vrpn_Analog_Server(_vrpn_peripheral_name_, g_pConnection, l_nChannels); ::GtkBuilder* l_pInterface=gtk_builder_new(); // glade_xml_new(OpenViBE::Directories::getDataDir() + "/openvibe-applications/vrpn-simulator/interface.ui", "window", NULL); gtk_builder_add_from_file(l_pInterface, OpenViBE::Directories::getDataDir() + "/openvibe-applications/vrpn-simulator/interface.ui", NULL); ::GtkWidget* l_pMainWindow=GTK_WIDGET(gtk_builder_get_object(l_pInterface, "window")); ::GtkWidget* l_pHBoxButton=GTK_WIDGET(gtk_builder_get_object(l_pInterface, "hbox_button")); ::GtkWidget* l_pHBoxAnalog=GTK_WIDGET(gtk_builder_get_object(l_pInterface, "hbox_analog")); g_signal_connect(G_OBJECT(l_pMainWindow), "destroy", gtk_main_quit, NULL); gtk_container_foreach(GTK_CONTAINER(l_pHBoxButton), fConnectCB, NULL); gtk_container_foreach(GTK_CONTAINER(l_pHBoxAnalog), fConnectCB, NULL); gtk_builder_connect_signals(l_pInterface, NULL); std::cout << "VRPN Stimulator\n"; std::cout << "Got " << g_iAnalogCount << " analogs...\n"; std::cout << "Got " << g_iButtonCount << " buttons...\n"; std::cout << "Using " << l_nChannels << " VRPN channels...\n"; std::cout << "Signals will be sent to peripheral [" << _vrpn_peripheral_name_ << "]\n"; g_idle_add(fIdleApplicationLoop, NULL); gtk_widget_show(l_pMainWindow); gtk_main(); delete g_pAnalogServer; delete g_pButtonServer; delete g_pConnection; #endif // TARGET_HAS_ThirdPartyVRPN return 0; }
vrpn_PeerMutex::vrpn_PeerMutex(const char *name, int port, const char *NICaddress) : d_state(AVAILABLE) , d_server(NULL) , d_peer(NULL) , d_numPeers(0) , d_numConnectionsAllocated(0) , d_myIP(getmyIP(NICaddress)) , d_myPort(port) , d_holderIP(0) , d_holderPort(-1) , d_reqGrantedCB(NULL) , d_reqDeniedCB(NULL) , d_takeCB(NULL) , d_releaseCB(NULL) , d_peerData(NULL) { if (!name) { fprintf(stderr, "vrpn_PeerMutex: NULL name!\n"); return; } // XXX Won't work with non-IP connections (MPI, for example) char con_name[512]; sprintf(con_name, "%s:%d", NICaddress, port); d_server = vrpn_create_server_connection(con_name); if (d_server) { d_server->addReference(); d_server->setAutoDeleteStatus(true); } else { fprintf(stderr, "vrpn_PeerMutex: " "Couldn't open connection on port %d!\n", port); return; } init(name); }
int main (int argc, char * argv []) { if (argc != 1) { fprintf(stderr, "Usage: %s\n", argv[0]); return -1; } //--------------------------------------------------------------------- // test the packing and unpacking routines if (!vrpn_test_pack_unpack()) { fprintf(stderr, "vrpn_test_pack_unpack() failed!\n"); return -1; } //--------------------------------------------------------------------- // test the thread library if (!vrpn_test_threads_and_semaphores()) { fprintf(stderr, "vrpn_test_threads_and_semaphores() failed!\n"); fprintf(stderr, " (This is not often used within VRPN, so it should not be fatal\n"); } else { printf("Thread code passes tests (not using for the following though)\n"); } //--------------------------------------------------------------------- // explicitly open the connection connection = vrpn_create_server_connection("loopback:"); if (!connection->doing_okay()) { fprintf(stderr, "Connection not doing okay (should be impossible)!\n"); return -1; } //--------------------------------------------------------------------- // Open the tracker server, using this connection, 2 sensors, update 1 times/sec stkr = new vrpn_Tracker_NULL(TRACKER_NAME, connection, 2, 1.0); printf("Tracker's name is %s.\n", TRACKER_NAME); create_and_link_tracker_remote(); //--------------------------------------------------------------------- // Open the dial server, using this connection, 2 dials, spin 0.5 rev/sec, // update 1 times/sec sdial = new vrpn_Dial_Example_Server(DIAL_NAME, connection, 2, 0.5, 1.0); printf("Dial's name is %s.\n", DIAL_NAME); create_and_link_dial_remote(); //--------------------------------------------------------------------- // Open the button server, using this connection, defaults sbtn = new vrpn_Button_Example_Server(BUTTON_NAME, connection); printf("Button's name is %s.\n", BUTTON_NAME); create_and_link_button_remote(); //--------------------------------------------------------------------- // Open the text sender and receiver. stext = new vrpn_Text_Sender(TEXT_NAME, connection); printf("Text's name is %s.\n", TEXT_NAME); create_and_link_text_remote(); //--------------------------------------------------------------------- // Open the analog server, using this connection. sana = new vrpn_Analog_Server(ANALOG_NAME, connection); sana->setNumChannels(8); printf("Analog's name is %s.\n", ANALOG_NAME); create_and_link_analog_remote(); //--------------------------------------------------------------------- // Open the analog output remote , using this connection. ranaout = new vrpn_Analog_Output_Remote(ANALOG_OUTPUT_NAME, connection); printf("Analog's name is %s.\n", ANALOG_OUTPUT_NAME); create_and_link_analog_output_server(); //--------------------------------------------------------------------- // open the poser remote rposer = new vrpn_Poser_Remote( POSER_NAME, connection ); printf( "Poser's name is %s.\n", POSER_NAME ); create_and_link_poser_server(); /* * main interactive loop */ int repeat_tests = 4; while ( repeat_tests > 0 ) { static long secs = 0; struct timeval now; // Let the servers, clients and connection do their things send_analog_output_once_in_a_while(); ranaout->mainloop(); // The remote is on the server for AnalogOutput sanaout->mainloop(); // The server is on the client for AnalogOutput send_analog_once_in_a_while(); sana->mainloop(); rana->mainloop(); send_text_once_in_a_while(); rtext->mainloop(); sdial->mainloop(); rdial->mainloop(); sbtn->mainloop(); rbtn->mainloop(); stkr->mainloop(); rtkr->mainloop(); send_poser_once_in_a_while(); rposer->mainloop(); sposer->mainloop(); connection->mainloop(); // Every 2 seconds, delete the old remotes and create new ones vrpn_gettimeofday(&now, NULL); if (secs == 0) { // First time through secs = now.tv_sec; } if ( now.tv_sec - secs >= 2 ) { secs = now.tv_sec; printf("\nDeleting and restarting _Remote objects\n"); delete rtkr; delete rdial; delete rbtn; delete rtext; delete rana; delete sanaout; delete sposer; create_and_link_tracker_remote(); create_and_link_dial_remote(); create_and_link_button_remote(); create_and_link_text_remote(); create_and_link_analog_remote(); create_and_link_analog_output_server(); create_and_link_poser_server(); --repeat_tests; } // Sleep for 1ms each iteration so we don't eat the CPU vrpn_SleepMsecs(1); } if ( (pcount == 0) || (vcount == 0) || (acount == 0) || (dcount == 0) || (tcount == 0) || (ancount == 0) || (aocount == 0) || (bcount == 0) || (pocount == 0) || (prcount == 0) ) { fprintf(stderr,"Did not get callbacks from one or more device\n"); return -1; } printf("\nDeleting _Remote objects\n"); delete rtkr; delete rdial; delete rbtn; delete rtext; delete rana; delete ranaout; delete rposer; printf("Testing whether two connections to a tracker and to a button each get their own messages.\n"); vrpn_Tracker_Remote *t1 = new vrpn_Tracker_Remote(TRACKER_NAME, connection); t1->register_change_handler(NULL, handle_pos1); vrpn_Tracker_Remote *t2 = new vrpn_Tracker_Remote(TRACKER_NAME, connection); t2->register_change_handler(NULL, handle_pos2); vrpn_Button_Remote *b1 = new vrpn_Button_Remote(BUTTON_NAME, connection); b1->register_change_handler(NULL, handle_button1); vrpn_Button_Remote *b2 = new vrpn_Button_Remote(BUTTON_NAME, connection); b2->register_change_handler(NULL, handle_button2); unsigned long secs; struct timeval start, now; vrpn_gettimeofday(&start, NULL); do { stkr->mainloop(); sbtn->mainloop(); t1->mainloop(); t2->mainloop(); b1->mainloop(); b2->mainloop(); connection->mainloop(); vrpn_gettimeofday(&now, NULL); secs = now.tv_sec - start.tv_sec; } while (secs <= 2); if ( (p1count == 0) || (p2count == 0) ) { fprintf(stderr,"Did not get callbacks from trackers\n"); return -1; } if ( (b1count == 0) || (b2count == 0) ) { fprintf(stderr,"Did not get callbacks from buttons\n"); return -1; } printf("Deleting extra remote objects\n"); delete t1; delete t2; delete b1; delete b2; printf("Deleting servers and connection\n"); delete stkr; delete sbtn; delete sdial; delete stext; delete sana; delete sanaout; delete sposer; connection->removeReference(); printf("Success!\n"); return 0; } /* main */
int main (int argc, const char *argv[]) { int bail_on_error = 1; int verbose = 0; int realparams = 0; // Parse the command line int i = 1; while (i < argc) { if (!strcmp(argv[i], "-warn")) {// Don't bail on errors bail_on_error = 0; } else if (!strcmp(argv[i], "-v")) { // Verbose verbose = 1; } else if (argv[i][0] == '-') { // Unknown flag Usage(argv[0]); } else switch (realparams) { // Non-flag parameters case 0: default: Usage(argv[0]); } i++; } #ifdef _WIN32 WSADATA wsaData; int status; if ((status = WSAStartup(MAKEWORD(1,1), &wsaData)) != 0) { fprintf(stderr, "WSAStartup failed with %d\n", status); } else if(verbose) { fprintf(stderr, "WSAStartup success\n"); } #endif const char handTrackerName[] = "Joystick0"; vrpn_Connection * connection = vrpn_create_server_connection(); // Create the joystick for analog and buttons vrpn_DirectXFFJoystick *joyServer = new vrpn_DirectXFFJoystick(handTrackerName, connection, 200, 200); if (joyServer==NULL) { fprintf(stderr, "Could not create Joystick\n"); return -1; } // Create the tracker to link to the joystick and provide transforms. // We put "*" in the name to indicate that it should use the same // connection. char analogName[1024]; sprintf(analogName, "*%s", (char*)handTrackerName); vrpn_Tracker_AnalogFlyParam afp; afp.x.name = (char*)analogName; afp.x.channel = 0; afp.x.offset = 0; afp.x.thresh = 0; afp.x.scale = (float)0.07; afp.x.power = 1; afp.y = afp.x; afp.y.channel = 1; afp.y.scale = (float)-0.07; afp.z = afp.x; afp.z.channel = 6; afp.z.scale = (float)0.2; afp.z.offset = (float)1.5; afp.sz = afp.x; afp.sz.channel = 5; afp.sz.scale = (float)0.06; vrpn_Tracker_AnalogFly *joyflyServer = new vrpn_Tracker_AnalogFly((char*) handTrackerName, connection, &afp, 200, vrpn_true); if (joyflyServer==NULL) { fprintf(stderr, "phantom_init(): Could not create AnalogFly\n"); return -1; } // Loop forever calling the mainloop()s for all devices /* struct timeval tv1, tv2; */ int counter = 0; while (1) { /* if ( counter == 0 ) { vrpn_gettimeofday( &tv1, NULL ); } counter++; */ // Let all the trackers generate reports joyServer->mainloop(); joyflyServer->mainloop(); // Send and receive all messages connection->mainloop(); // Sleep for a short while to make sure we don't eat the whole CPU //vrpn_SleepMsecs(1); /* if ( counter == 50 ) { vrpn_gettimeofday( &tv2, NULL ); printf( "%f\n", 50.0/(((tv2.tv_sec*1000 +tv2.tv_usec/1000.0) - (tv1.tv_sec*1000 +tv1.tv_usec/1000.0))/1000.0)); counter = 0; } */ } }
int main (int argc, char * argv []) { if (argc != 1) { fprintf(stderr, "Usage: %s\n", argv[0]); exit(-1); } //--------------------------------------------------------------------- // explicitly open the connection connection = vrpn_create_server_connection(CONNECTION_PORT); //--------------------------------------------------------------------- // Open the analog server, using this connection. sana = new vrpn_Analog_Server(ANALOG_NAME, connection); sana->setNumChannels(1); sana->channels()[0] = 1.0; //< Set the value to 1 printf("Analog's name is %s.\n", ANALOG_NAME); create_and_link_analog_remote(); //--------------------------------------------------------------------- // Open the tracker remotes, using this connection. printf("Tracker 1's name is %s.\n", TRACKER1_NAME); printf("Tracker 2's name is %s.\n", TRACKER2_NAME); create_and_link_tracker_remotes(); //--------------------------------------------------------------------- // Create the differential and absolute trackers. Both should send one // report every two seconds. First, create the axis descriptor (used // for all axes). Then pack this into the parameter descriptor and start // the relative tracker and absolute tracker. vrpn_TAF_axis taf_axis1; // Axis that returns values from the analog char name[500]; sprintf(name, "*%s", ANALOG_NAME); taf_axis1.name = name; taf_axis1.channel = 0; taf_axis1.offset = 0.0; taf_axis1.thresh = 0.0; taf_axis1.scale = 1.0; taf_axis1.power = 1.0; vrpn_TAF_axis taf_axisNULL; // Axis that doesn't return anything taf_axisNULL.name = NULL; taf_axisNULL.channel = 0; taf_axisNULL.offset = 0.0; taf_axisNULL.thresh = 0.0; taf_axisNULL.scale = 1.0; taf_axisNULL.power = 1.0; vrpn_Tracker_AnalogFlyParam p; p.reset_name = NULL; p.reset_which = 0; p.x = taf_axis1; p.y = taf_axis1; p.z = taf_axis1; p.sx = taf_axisNULL; // Don't want any rotation! p.sy = taf_axisNULL; p.sz = taf_axisNULL; stkr1 = new vrpn_Tracker_AnalogFly(TRACKER1_NAME, connection, &p, 0.5, vrpn_false); stkr2 = new vrpn_Tracker_AnalogFly(TRACKER2_NAME, connection, &p, 0.5, vrpn_true); /* * main interactive loop */ printf("You should see tracker1 positions increasing by 2 per 2 seconds\n"); printf("You should see tracker2 positions remaining at 1\n"); struct timeval start, now, diff; vrpn_gettimeofday(&start, NULL); vrpn_gettimeofday(&now, NULL); diff = vrpn_TimevalDiff(now, start); while ( diff.tv_sec <= 10 ) { // Make sure that we are getting analog values { static struct timeval last_report; static int first = 1; struct timeval now; if (first) { vrpn_gettimeofday(&last_report, NULL); first = 0; } vrpn_gettimeofday(&now, NULL); if (now.tv_sec - last_report.tv_sec > 1) { if (!getting_analog_values) { fprintf(stderr, "Error - not getting analog values!\n"); } vrpn_gettimeofday(&last_report, NULL); getting_analog_values = 0; // Make sure we get more next time } } // Let the servers, clients and connection do their things sana->report(); sana->mainloop(); stkr1->mainloop(); stkr2->mainloop(); rana->mainloop(); rtkr1->mainloop(); rtkr2->mainloop(); connection->mainloop(); // Sleep for 1ms each iteration so we don't eat the CPU vrpn_SleepMsecs(1); vrpn_gettimeofday(&now, NULL); diff = vrpn_TimevalDiff(now, start); } delete sana; delete rtkr1; delete rtkr2; delete stkr1; delete stkr2; delete connection; return 0; } /* main */
int main (int argc, char * argv []) { // Return value is good so far... int ret = 0; if (argc != 1) { fprintf(stderr, "Usage: %s\n", argv[0]); return -1; } //--------------------------------------------------------------------- // explicitly open the server connection, telling it to log its // incoming and outgoing messages even when there is not a logging // client connection. server_connection = vrpn_create_server_connection(CONNECTION_PORT, SERVER_BASE_INCOMING_LOG, SERVER_BASE_OUTGOING_LOG); if (server_connection == NULL) { fprintf(stderr,"Cannot open server connection\n"); return -1; } //--------------------------------------------------------------------- // Open the server-side text sender and receivers. server_text_sender = new vrpn_Text_Sender(CLIENT_TEXT_NAME, server_connection); server_text_receiver = new vrpn_Text_Receiver(SERVER_TEXT_NAME, server_connection); if ( (server_text_sender == NULL) || (server_text_receiver == NULL) ) { fprintf(stderr,"Cannot create text server or client\n"); return -3; } //--------------------------------------------------------------------- // Establish the no-logging connection and make sure it works. // (This will put entries into the server-side log files.) printf("Sending messages to and from server with base logging only\n"); if (0 != open_client_connection_and_loop(NULL, NULL, NULL, NULL)) { fprintf(stderr,"Could not test no-logging connection\n"); ret = -4; } //--------------------------------------------------------------------- // Establish the client-in-logging connection and make sure it works. // (This will put entries into the server-side log files.) printf("Sending messages to and from server with client-in\n"); if (0 != open_client_connection_and_loop(CLIENT_CLIENT_INCOMING_LOG, NULL, NULL, NULL)) { fprintf(stderr,"Could not test CLIENT_CLIENT_INCOMING_LOG connection\n"); ret = -4; } //--------------------------------------------------------------------- // Establish the client-out-logging connection and make sure it works. // (This will put entries into the server-side log files.) printf("Sending messages to and from server with client-out\n"); if (0 != open_client_connection_and_loop(NULL, CLIENT_CLIENT_OUTGOING_LOG, NULL, NULL)) { fprintf(stderr,"Could not test CLIENT_CLIENT_OUTGOING_LOG connection\n"); ret = -4; } //--------------------------------------------------------------------- // Establish the server-in-logging connection and make sure it works. // Actually, this has to be done below in a separate step because the // server has been set to automatically log incoming connections. //--------------------------------------------------------------------- // Establish the server-out-logging connection and make sure it works. // (This will put entries into the server-side log files.) printf("Sending messages to and from server with server-out\n"); if (0 != open_client_connection_and_loop(NULL, NULL, NULL, CLIENT_SERVER_OUTGOING_LOG)) { fprintf(stderr,"Could not test CLIENT_SERVER_OUTGOING_LOG connection\n"); ret = -4; } //--------------------------------------------------------------------- // Mainloop the sever connection to make sure we close all open links printf("Waiting for connections to close\n"); struct timeval now, start; vrpn_gettimeofday(&now, NULL); start = now; while ( now.tv_sec - start.tv_sec < 3 ) { server_connection->mainloop(); vrpn_gettimeofday(&now, NULL); } //--------------------------------------------------------------------- // Delete the server-side objects and get rid of the server connection // by reducing its reference count. delete server_text_receiver; delete server_text_sender; server_connection->removeReference(); //--------------------------------------------------------------------- // To test the case of logging server-side incoming messages when the // server was not constructed to do so automatically, we need to open // the server again with no logging requested and then connect to it // with a client that requests it. server_connection = vrpn_create_server_connection(CONNECTION_PORT); if (server_connection == NULL) { fprintf(stderr,"Cannot open server connection\n"); return -1; } //--------------------------------------------------------------------- // Open the server-side text sender and receivers. server_text_sender = new vrpn_Text_Sender(CLIENT_TEXT_NAME, server_connection); server_text_receiver = new vrpn_Text_Receiver(SERVER_TEXT_NAME, server_connection); if ( (server_text_sender == NULL) || (server_text_receiver == NULL) ) { fprintf(stderr,"Cannot create text server or client\n"); return -3; } //--------------------------------------------------------------------- // Establish the server-in-logging connection and make sure it works. // (This will put entries into the server-side log files.) printf("Sending messages to and from server with server-out\n"); if (0 != open_client_connection_and_loop(NULL, NULL, CLIENT_SERVER_INCOMING_LOG, NULL )) { fprintf(stderr,"Could not test CLIENT_SERVER_INCOMING_LOG connection\n"); ret = -4; } //--------------------------------------------------------------------- // Mainloop the sever connection to make sure we close all open links printf("Waiting for connections to close\n"); vrpn_gettimeofday(&now, NULL); start = now; while ( now.tv_sec - start.tv_sec < 3 ) { server_connection->mainloop(); vrpn_gettimeofday(&now, NULL); } //--------------------------------------------------------------------- // Delete the server-side objects and get rid of the server connection // by reducing its reference count. delete server_text_receiver; delete server_text_sender; server_connection->removeReference(); //--------------------------------------------------------------------- // Try reading from each of the log files in turn to make sure each // contains at least one text message of the desired type. if (0 != check_for_messages_in(SERVER_TEXT_NAME, make_server_incoming_name(SERVER_BASE_INCOMING_LOG,1))) { fprintf(stderr,"Failure when reading from server base incoming log file\n"); ret = -5; } if (0 != check_for_messages_in(CLIENT_TEXT_NAME, SERVER_BASE_OUTGOING_LOG)) { fprintf(stderr,"Failure when reading from server base outgoing log file\n"); ret = -5; } if (0 != check_for_messages_in(CLIENT_TEXT_NAME, CLIENT_CLIENT_INCOMING_LOG)) { fprintf(stderr,"Failure when reading from client-side incoming log file\n"); ret = -5; } if (0 != check_for_messages_in(SERVER_TEXT_NAME, CLIENT_CLIENT_OUTGOING_LOG)) { fprintf(stderr,"Failure when reading from client-side outgoing log file\n"); ret = -5; } if (0 != check_for_messages_in(SERVER_TEXT_NAME, CLIENT_SERVER_INCOMING_LOG)) { fprintf(stderr,"Failure when reading from server-side incoming log file\n"); ret = -5; } if (0 != check_for_messages_in(CLIENT_TEXT_NAME, CLIENT_SERVER_OUTGOING_LOG)) { fprintf(stderr,"Failure when reading from server-side outgoing log file\n"); ret = -5; } //--------------------------------------------------------------------- // Try re-writing the same log file a couple of times. This turned up a // crash case before. We do it twice because it may save an emergency // log file in temp the first time. printf("Testing for crash when attempt to rewrite file with client-out\n"); open_client_connection_and_loop(NULL, CLIENT_CLIENT_OUTGOING_LOG, NULL, NULL); if (0 == open_client_connection_and_loop(NULL, CLIENT_CLIENT_OUTGOING_LOG, NULL, NULL)) { fprintf(stderr,"Unexpected success when writing to existing server-side outgoing log file\n"); ret = -6; } // Clean up after ourselves by deleting the log files. printf("Deleting log files\n"); // Don't complain about using "unlink" #ifdef _MSC_VER #pragma warning ( disable : 4996 ) #endif char * name; name = make_server_incoming_name(SERVER_BASE_INCOMING_LOG,1); unlink(name); delete[] name; name = make_server_incoming_name(SERVER_BASE_INCOMING_LOG,2); unlink(name); delete[] name; name = make_server_incoming_name(SERVER_BASE_INCOMING_LOG,3); unlink(name); delete[] name; name = make_server_incoming_name(SERVER_BASE_INCOMING_LOG,4); unlink(name); delete[] name; unlink(SERVER_BASE_OUTGOING_LOG); unlink(CLIENT_CLIENT_INCOMING_LOG); unlink(CLIENT_CLIENT_OUTGOING_LOG); unlink(CLIENT_SERVER_INCOMING_LOG); unlink(CLIENT_SERVER_OUTGOING_LOG); if (ret == 0) { printf("Success!\n"); } else { printf("Failure\n"); } return ret; } /* main */
bool init_server_code(const char *outgoing_logfile_name, bool do_color) { if ( (svrcon = vrpn_create_server_connection(g_svrPORT, NULL, outgoing_logfile_name)) == NULL) { fprintf(stderr, "Could not open imager server connection\n"); return false; } if ( (svr = new vrpn_Imager_Server("TestImage", svrcon, g_camera->get_num_columns(), g_camera->get_num_rows())) == NULL) { fprintf(stderr, "Could not open Imager Server\n"); return false; } if (do_color) { if ( (svrchan = svr->add_channel("red", "unknown", 0, (float)(g_maxval) )) == -1) { fprintf(stderr, "Could not add channel to server image\n"); return false; } // This relies on VRPN to hand us sequential channel numbers. This might be // dangerous. if ( (svr->add_channel("green", "unknown", 0, (float)(g_maxval) )) == -1) { fprintf(stderr, "Could not add channel to server image\n"); return false; } if ( (svr->add_channel("blue", "unknown", 0, (float)(g_maxval) )) == -1) { fprintf(stderr, "Could not add channel to server image\n"); return false; } } else { if ( (svrchan = svr->add_channel("mono", "unknown", 0, (float)(g_maxval) )) == -1) { fprintf(stderr, "Could not add channel to server image\n"); return false; } } vrpn_ThreadData td; td.pvUD = NULL; svrthread = new vrpn_Thread(imager_server_thread_func, td); if (svrthread == NULL) { fprintf(stderr,"Can't create server thread\n"); return false; } if (!svrthread->go()) { fprintf(stderr,"Can't start server thread\n"); return false; } printf("Local loopback server thread on %d\n", g_svrPORT); // Now handle the main thread's code, which will run an // imager forwarder. if ( (strcon = vrpn_create_server_connection(g_strPORT)) == NULL) { fprintf(stderr, "Could not open imager stream buffer connection\n"); return false; } char svrname[1024]; sprintf(svrname,"TestImage@localhost:%d", g_svrPORT); if ( (str = new vrpn_Imager_Stream_Buffer("TestImage", svrname, strcon)) == NULL) { fprintf(stderr, "Could not open imager stream buffer\n"); return false; } printf("Waiting for video connections on %d\n", g_strPORT); return true; }
int main (int argc, char ** argv) { char * source_location; char * source_name; char * client_name; int port = 4510; int retval; if ((argc < 3) || (argc > 4)) Usage(argv[0]); // Expect that source_name and client_name are both ??? // Port is the port that our client will connect to us on source_location = argv[1]; source_name = argv[2]; client_name = argv[2]; if (argc == 4) port = atoi(argv[3]); // Connect to the server. server_connection = vrpn_get_connection_by_name (source_location); // Open a port for our client to connect to us. client_connection = vrpn_create_server_connection(port); // Put a forwarder on that port. forwarder = new vrpn_StreamForwarder (server_connection, source_name, client_connection, client_name); // Tell the forwarder to send Tracker Pos/Quat messages through, // using the same name on both sides. retval = forwarder->forward("Tracker Pos/Quat", "Tracker Pos/Quat"); if (retval) fprintf(stderr, "forwarder->forward(\"Tracker Pos/Quat\") failed.\n"); else fprintf(stderr, "forwarder->forward(\"Tracker Pos/Quat\") succeeded.\n"); // Set up a signal handler to shut down cleanly on control-C. install_handler(); // Do the dirty work. while (1) { // Get any received messages and queue them up for transmission // to the client. server_connection->mainloop(); // Send them. client_connection->mainloop(); } }
int main (int argc, char * argv[]) { const char * config_file_name = "vrpn.cfg"; bool bail_on_error = true; bool auto_quit = false; bool flush_continuously = false; int realparams = 0; int i; int port = vrpn_DEFAULT_LISTEN_PORT_NO; #ifdef _WIN32 // On Windows, the millisleep with 0 option frees up the CPU time slice for other jobs // but does not sleep for a specific time. On Unix, this returns immediately and does // not do anything but waste cycles. int milli_sleep_time = 0; // How long to sleep each iteration (default: free the timeslice but be runnable again immediately) #else int milli_sleep_time = 1; // How long to sleep each iteration (default: 1ms) #endif #ifdef _WIN32 WSADATA wsaData; int status; if ((status = WSAStartup(MAKEWORD(1,1), &wsaData)) != 0) { fprintf(stderr, "WSAStartup failed with %d\n", status); return(1); } // This handles all kinds of signals. SetConsoleCtrlHandler(handleConsoleSignalsWin, TRUE); #else #ifdef sgi sigset( SIGINT, sighandler ); sigset( SIGKILL, sighandler ); sigset( SIGTERM, sighandler ); sigset( SIGPIPE, sighandler ); #else signal( SIGINT, sighandler ); signal( SIGKILL, sighandler ); signal( SIGTERM, sighandler ); signal( SIGPIPE, sighandler ); #endif // not sgi #endif // not WIN32 // Parse the command line i = 1; while (i < argc) { if (!strcmp(argv[i], "-f")) { // Specify config-file name if (++i > argc) { Usage(argv[0]); } config_file_name = argv[i]; } else if (!strcmp(argv[i], "-millisleep")) { // How long to sleep each loop? if (++i > argc) { Usage(argv[0]); } milli_sleep_time = atoi(argv[i]); } else if (!strcmp(argv[i], "-warn")) {// Don't bail on errors bail_on_error = false; } else if (!strcmp(argv[i], "-v")) { // Verbose verbose = true; vrpn_System_TextPrinter.set_min_level_to_print(vrpn_TEXT_NORMAL); } else if (!strcmp(argv[i], "-q")) { // quit on dropped last con auto_quit = true; } else if (!strcmp(argv[i], "-NIC")) { // specify a network interface if (++i > argc) { Usage(argv[0]); } if (verbose) { fprintf(stderr, "Listening on network interface card %s.\n", argv[i]); } g_NICname = argv[i]; } else if (!strcmp(argv[i], "-li")) { // specify server-side logging if (++i > argc) { Usage(argv[0]); } if (verbose) { fprintf(stderr, "Incoming logfile name %s.\n", argv[i]); } g_inLogName = argv[i]; } else if (!strcmp(argv[i], "-lo")) { // specify server-side logging if (++i > argc) { Usage(argv[0]); } if (verbose) { fprintf(stderr, "Outgoing logfile name %s.\n", argv[i]); } g_outLogName = argv[i]; } else if (!strcmp(argv[i], "-flush")) { flush_continuously = true; } else if (argv[i][0] == '-') { // Unknown flag Usage(argv[0]); } else switch (realparams) { // Non-flag parameters case 0: port = atoi(argv[i]); realparams++; break; default: Usage(argv[0]); } i++; } // Need to have a global pointer to the connection so we can shut it down // in the signal handler (so we can close any open logfiles.) // Form the name based on the type of connection requested. For a standard // VRPN UDP/TCP port, we give it the name "NIC:port" if there is a NIC name, // otherwise just ":port" for the default NIC. char con_name[1024]; if (g_NICname) { sprintf(con_name, "%s:%d", g_NICname, port); } else { sprintf(con_name, ":%d", port); } connection = vrpn_create_server_connection(con_name, g_inLogName, g_outLogName); // Create the generic server object and make sure it is doing okay. generic_server = new vrpn_Generic_Server_Object(connection, config_file_name, port, verbose, bail_on_error); if ( (generic_server == NULL) || !generic_server->doing_okay() ) { fprintf(stderr,"Could not start generic server, exiting\n"); shutDown(); } // Open the Forwarder Server forwarderServer = new vrpn_Forwarder_Server (connection); // If we're set to auto-quit, then register a handler for the last connection // dropped that will cause a callback which will exit. if (auto_quit) { int dlc_m_id = connection->register_message_type( vrpn_dropped_last_connection); connection->register_handler(dlc_m_id, handle_dlc, NULL); } // ******************************************************************** // ** ** // ** MAIN LOOP ** // ** ** // ******************************************************************** // ^C handler sets done to let us know to quit. while (!done) { // Let the generic object server do its thing. if (generic_server) { generic_server->mainloop(); } // Send and receive all messages. connection->mainloop(); // Save all log messages that are pending so that they are on disk // in case we end up exiting improperly. This may slow down the // server waiting for disk writes to complete, but will more reliably // log messages. if (flush_continuously) { connection->save_log_so_far(); } // Bail if the connection is in trouble. if (!connection->doing_okay()) { shutDown(); } // Handle forwarding requests; send messages // on auxiliary connections. forwarderServer->mainloop(); // Sleep so we don't eat the CPU #if defined(_WIN32) if (milli_sleep_time >= 0) { #else if (milli_sleep_time > 0) { #endif vrpn_SleepMsecs(milli_sleep_time); } } shutDown(); return 0; }
int main (int, char **) { vrpn_Connection * connection; connection = vrpn_create_server_connection(4999); int myID = connection->register_sender("rpc_Test"); rpc_Test * enc_out = new rpc_Test(connection); connection->mainloop(); struct timeval now; char * buf = NULL; vrpn_int32 len = 0; vrpn_gettimeofday(&now, NULL); printf("Expect Empty\n"); connection->pack_message(len, now, enc_out->d_Empty_type, myID, (char *) buf, vrpn_CONNECTION_RELIABLE); connection->mainloop(); buf = enc_out->encode_Simple(&len, 2, 1.85f, 3.23f); vrpn_gettimeofday(&now, NULL); printf("Expect Simple, 2, 1.85, 3.23\n"); connection->pack_message(len, now, enc_out->d_Simple_type, myID, (char *) buf, vrpn_CONNECTION_RELIABLE); delete [] buf; buf = NULL; connection->mainloop(); const vrpn_int32 cnt = 3; char nm[NAME_LENGTH] = "Jones"; char nm2[cnt]= "nM"; char doublenm[4][NAME_LENGTH] = {"one", "two", "three", "four"}; int i; // char *p_to_char[4]= {"one", "two", "three", "four"}; // char (*arr_of_p)[4] ; // printf ("size %d %d\n", sizeof(p_to_char), sizeof(arr_of_p)); char **triplenm[4]; //char **(*p_t)[4] = &triplenm; for (i =0; i<4; i++) { triplenm[i] = new char *[cnt]; for (int j=0; j< cnt; j++) { triplenm[i][j] = new char[cnt]; sprintf (triplenm[i][j], "%c%c", (char)((int)'a' + i), (char)((int)'j' + j)); } } // char triplenm[4][cnt][cnt] = { {"aa", "ab", "ac" } , // {"ba", "bb", "bc" } , // {"ca", "cb", "cc" } , // {"da", "db", "dc" } }; buf = enc_out->encode_CharArray(&len, cnt, nm, nm2, doublenm, triplenm); vrpn_gettimeofday(&now, NULL); printf("Expect CharArray ...\n"); connection->pack_message(len, now, enc_out->d_CharArray_type, myID, (char *) buf, vrpn_CONNECTION_RELIABLE); delete [] buf; buf = NULL; connection->mainloop(); // vrpn_int32 cnt; vrpn_int32 shortstuff[] = {1,2,3}; vrpn_int32 constdouble[6][4]; vrpn_int32 *triple[4][NAME_LENGTH]; for ( i =0; i<6; i++) { for (int j=0; j< 4; j++) { constdouble[i][j] = i+j; } } for ( i =0; i<4; i++) { for (int j=0; j< NAME_LENGTH; j++) { triple[i][j] = new vrpn_int32[cnt]; for (int k=0; k< cnt; k++) { triple[i][j][k] = i+j+k; } } } buf = enc_out->encode_IntArray(&len, cnt, &(shortstuff[0]), constdouble, triple); vrpn_gettimeofday(&now, NULL); printf("Expect IntArray ...\n"); connection->pack_message(len, now, enc_out->d_IntArray_type, myID, (char *) buf, vrpn_CONNECTION_RELIABLE); delete [] buf; buf = NULL; connection->mainloop(); vrpn_int32 count = 3; char name[64] = "Z Piezo"; char units[64]= "nm"; vrpn_float32 offset = 1.3f; vrpn_float32 scale = 0.025f; char * mptr; int mlen; buf = enc_out->encode_ReportScanDatasets_header ( &len, &mptr, &mlen, count ); for (int lv_1 = 0; lv_1 < count; lv_1++) { enc_out->encode_ReportScanDatasets_body ( &len, buf, &mptr, &mlen, name, units, offset, scale ); offset *= 2; scale *=3; } vrpn_gettimeofday(&now, NULL); printf("Expect ReportScanDatasets ...\n"); connection->pack_message(len, now, enc_out->d_ReportScanDatasets_type, myID, (char *) buf, vrpn_CONNECTION_RELIABLE); delete [] buf; buf = NULL; connection->mainloop(); return 0; }
int vrpn_Tracker_DeadReckoning_Rotation::test(void) { // Construct a loopback connection to be used by all of our objects. vrpn_Connection *c = vrpn_create_server_connection("loopback:"); // Create a tracker server to be the initator and a dead-reckoning // rotation tracker to use it as a base; have it predict 1 second // into the future. vrpn_Tracker_Server *t0 = new vrpn_Tracker_Server("Tracker0", c, 2); vrpn_Tracker_DeadReckoning_Rotation *t1 = new vrpn_Tracker_DeadReckoning_Rotation("Tracker1", c, "*Tracker0", 2, 1); // Create a remote tracker to listen to t1 and set up its callbacks for // position and velocity reports. They will fill in the static structures // listed above with whatever values they receive. vrpn_Tracker_Remote *tr = new vrpn_Tracker_Remote("Tracker1", c); tr->register_change_handler(&poseResponse, handle_test_tracker_report); tr->register_change_handler(&velResponse, handle_test_tracker_velocity_report); // Set up the values in the pose and velocity responses with incorrect values // so that things will fail if the class does not perform as expected. q_vec_set(poseResponse.pos, 1, 1, 1); q_make(poseResponse.quat, 0, 0, 1, 0); poseResponse.time.tv_sec = 0; poseResponse.time.tv_usec = 0; poseResponse.sensor = -1; // Send a pose report from sensors 0 and 1 on the original tracker that places // them at (1,1,1) and with the identity rotation. We should get a response for // each of them so we should end up with the sensor-1 response matching what we // sent, with no change in position or orientation. q_vec_type pos = { 1, 1, 1 }; q_type quat = { 0, 0, 0, 1 }; struct timeval firstSent; vrpn_gettimeofday(&firstSent, NULL); t0->report_pose(0, firstSent, pos, quat); t0->report_pose(1, firstSent, pos, quat); t0->mainloop(); t1->mainloop(); c->mainloop(); tr->mainloop(); if ( (poseResponse.time.tv_sec != firstSent.tv_sec + 1) || (poseResponse.sensor != 1) || (q_vec_distance(poseResponse.pos, pos) > 1e-10) || (poseResponse.quat[Q_W] != 1) ) { std::cerr << "vrpn_Tracker_DeadReckoning_Rotation::test(): Got unexpected" << " initial response: pos (" << poseResponse.pos[Q_X] << ", " << poseResponse.pos[Q_Y] << ", " << poseResponse.pos[Q_Z] << "), quat (" << poseResponse.quat[Q_X] << ", " << poseResponse.quat[Q_Y] << ", " << poseResponse.quat[Q_Z] << ", " << poseResponse.quat[Q_W] << ")" << " from sensor " << poseResponse.sensor << " at time " << poseResponse.time.tv_sec << ":" << poseResponse.time.tv_usec << std::endl; delete tr; delete t1; delete t0; c->removeReference(); return 1; } // Send a second tracker report for sensor 0 coming 0.4 seconds later that has // translated to position (2,1,1) and rotated by 0.4 * 90 degrees around Z. // This should cause a prediction for one second later than this new pose // message that has rotated by very close to 1.4 * 90 degrees. q_vec_type pos2 = { 2, 1, 1 }; q_type quat2; double angle2 = 0.4 * 90 * M_PI / 180.0; q_from_axis_angle(quat2, 0, 0, 1, angle2); struct timeval p4Second = { 0, 400000 }; struct timeval firstPlusP4 = vrpn_TimevalSum(firstSent, p4Second); t0->report_pose(0, firstPlusP4, pos2, quat2); t0->mainloop(); t1->mainloop(); c->mainloop(); tr->mainloop(); double x, y, z, angle; q_to_axis_angle(&x, &y, &z, &angle, poseResponse.quat); if ((poseResponse.time.tv_sec != firstPlusP4.tv_sec + 1) || (poseResponse.sensor != 0) || (q_vec_distance(poseResponse.pos, pos2) > 1e-10) || !isClose(x, 0) || !isClose(y, 0) || !isClose(z, 1) || !isClose(angle, 1.4 * 90 * M_PI / 180.0) ) { std::cerr << "vrpn_Tracker_DeadReckoning_Rotation::test(): Got unexpected" << " predicted pose response: pos (" << poseResponse.pos[Q_X] << ", " << poseResponse.pos[Q_Y] << ", " << poseResponse.pos[Q_Z] << "), quat (" << poseResponse.quat[Q_X] << ", " << poseResponse.quat[Q_Y] << ", " << poseResponse.quat[Q_Z] << ", " << poseResponse.quat[Q_W] << ")" << " from sensor " << poseResponse.sensor << std::endl; delete tr; delete t1; delete t0; c->removeReference(); return 2; } // Send a velocity report for sensor 1 that has has translation by (1,0,0) // and rotating by 0.4 * 90 degrees per 0.4 of a second around Z. // This should cause a prediction for one second later than the first // report that has rotated by very close to 90 degrees. The translation // should be ignored, so the position should be the original position. q_vec_type vel = { 0, 0, 0 }; t0->report_pose_velocity(1, firstPlusP4, vel, quat2, 0.4); t0->mainloop(); t1->mainloop(); c->mainloop(); tr->mainloop(); q_to_axis_angle(&x, &y, &z, &angle, poseResponse.quat); if ((poseResponse.time.tv_sec != firstSent.tv_sec + 1) || (poseResponse.sensor != 1) || (q_vec_distance(poseResponse.pos, pos) > 1e-10) || !isClose(x, 0) || !isClose(y, 0) || !isClose(z, 1) || !isClose(angle, 90 * M_PI / 180.0) ) { std::cerr << "vrpn_Tracker_DeadReckoning_Rotation::test(): Got unexpected" << " predicted velocity response: pos (" << poseResponse.pos[Q_X] << ", " << poseResponse.pos[Q_Y] << ", " << poseResponse.pos[Q_Z] << "), quat (" << poseResponse.quat[Q_X] << ", " << poseResponse.quat[Q_Y] << ", " << poseResponse.quat[Q_Z] << ", " << poseResponse.quat[Q_W] << ")" << " from sensor " << poseResponse.sensor << std::endl; delete tr; delete t1; delete t0; c->removeReference(); return 3; } // To test the behavior of the prediction code when we're moving around more // than one axis, and when we're starting from a non-identity orientation, // set sensor 1 to be rotated 180 degrees around X. Then send a velocity // report that will produce a rotation of 180 degrees around Z. The result // should match a prediction of 180 degrees around Y (plus or minus 180, plus // or minus Y axis are all equivalent). struct timeval oneSecond = { 1, 0 }; struct timeval firstPlusOne = vrpn_TimevalSum(firstSent, oneSecond); q_type quat3; q_from_axis_angle(quat3, 1, 0, 0, M_PI); t0->report_pose(1, firstPlusOne, pos, quat3); q_type quat4; q_from_axis_angle(quat4, 0, 0, 1, M_PI); t0->report_pose_velocity(1, firstPlusOne, vel, quat4, 1.0); t0->mainloop(); t1->mainloop(); c->mainloop(); tr->mainloop(); q_to_axis_angle(&x, &y, &z, &angle, poseResponse.quat); if ((poseResponse.time.tv_sec != firstPlusOne.tv_sec + 1) || (poseResponse.sensor != 1) || (q_vec_distance(poseResponse.pos, pos) > 1e-10) || !isClose(x, 0) || !isClose(fabs(y), 1) || !isClose(z, 0) || !isClose(fabs(angle), M_PI) ) { std::cerr << "vrpn_Tracker_DeadReckoning_Rotation::test(): Got unexpected" << " predicted pose + velocity response: pos (" << poseResponse.pos[Q_X] << ", " << poseResponse.pos[Q_Y] << ", " << poseResponse.pos[Q_Z] << "), quat (" << poseResponse.quat[Q_X] << ", " << poseResponse.quat[Q_Y] << ", " << poseResponse.quat[Q_Z] << ", " << poseResponse.quat[Q_W] << ")" << " from sensor " << poseResponse.sensor << std::endl; delete tr; delete t1; delete t0; c->removeReference(); return 4; } // To test the behavior of the prediction code when we're moving around more // than one axis, and when we're starting from a non-identity orientation, // set sensor 0 to start out at identity. Then in one second it will be // rotated 180 degrees around X. Then in another second it will be rotated // additionally by 90 degrees around Z; the prediction should be another // 90 degrees around Z, which should turn out to compose to +/-180 degrees // around +/- Y, as in the velocity case above. // To make this work, we send a sequence of three poses, one second apart, // starting at the original time. We do this on sensor 0, which has never // had a velocity report, so that it will be using the pose-only prediction. struct timeval firstPlusTwo = vrpn_TimevalSum(firstPlusOne, oneSecond); q_from_axis_angle(quat3, 1, 0, 0, M_PI); t0->report_pose(0, firstSent, pos, quat); t0->report_pose(0, firstPlusOne, pos, quat3); q_from_axis_angle(quat4, 0, 0, 1, M_PI / 2); q_type quat5; q_mult(quat5, quat4, quat3); t0->report_pose(0, firstPlusTwo, pos, quat5); t0->mainloop(); t1->mainloop(); c->mainloop(); tr->mainloop(); q_to_axis_angle(&x, &y, &z, &angle, poseResponse.quat); if ((poseResponse.time.tv_sec != firstPlusTwo.tv_sec + 1) || (poseResponse.sensor != 0) || (q_vec_distance(poseResponse.pos, pos) > 1e-10) || !isClose(x, 0) || !isClose(fabs(y), 1.0) || !isClose(z, 0) || !isClose(fabs(angle), M_PI) ) { std::cerr << "vrpn_Tracker_DeadReckoning_Rotation::test(): Got unexpected" << " predicted pose + pose response: pos (" << poseResponse.pos[Q_X] << ", " << poseResponse.pos[Q_Y] << ", " << poseResponse.pos[Q_Z] << "), quat (" << poseResponse.quat[Q_X] << ", " << poseResponse.quat[Q_Y] << ", " << poseResponse.quat[Q_Z] << ", " << poseResponse.quat[Q_W] << ")" << " from sensor " << poseResponse.sensor << "; axis = (" << x << ", " << y << ", " << z << "), angle = " << angle << std::endl; delete tr; delete t1; delete t0; c->removeReference(); return 5; } // Done; delete our objects and return 0 to indicate that // everything worked. delete tr; delete t1; delete t0; c->removeReference(); return 0; }