/* Copyright (C) 2007 L. Donnie Smith * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define APP_NAME "CWiid wmgui" #define APP_VERSION PACKAGE_VERSION #define APP_COPYRIGHT "Copyright (C) 2007 L. Donnie Smith " \ "" #define APP_COMMENTS "Wiimote GUI" #include #include #include #include #include #include #include #include #include #include #include "interface.h" #include "support.h" #include #include "cwiid.h" #include #include "libcalib.h" #include #include #include using namespace std; // #include // #include // using namespace Cantag; #define PI 3.14159265358979323 timeval t; /* Globals */ cwiid_wiimote_t *wiimote = NULL; bdaddr_t bdaddr; cwiid_wiimote_t *wiimote2 = NULL; bdaddr_t bdaddr2; FILE* file1; FILE* file2; FILE* file3; struct cwiid_ir_mesg ir_data; struct cwiid_ir_mesg ir_data2; struct coord { int x; int y; int pt; }; int swaps1[4]; int swaps2[4]; int xi = 1; /* Widgets */ GtkWidget *winMain; GtkWidget *winDialog; GtkWidget *menuConnect, *menuDisconnect, *menuConnect2, *menuDisconnect2, *menuQuit, *menuCamera1, *menuCamera2, *menuSync, *menuLog, *menuLog2, *menuBoth, *menuAlign, *menuAlign1, *menuAlign2, *menuRecord; GtkWidget *lblIR; GtkWidget *drawIR; GtkWidget *lblIR2; GtkWidget *drawIR2; GtkWidget *statConnection, *statBattery; GtkWidget *statConnection2, *statBattery2; /* matrices */ mxArray *om, *T, *fc_left, *cc_left, *kc_left, *alpha_c_left, *fc_right, *cc_right, *kc_right, *alpha_c_right; /* CORBA */ InventorEngines::SourceEngine_var engine_ref, engine_ref2; /* Utility functions */ void write_pre(FILE* file); void write_post(FILE* file); void set_gui_state(); void clear_widgets(); void clear_ir_data(); void clear_ir_data2(); void message(GtkMessageType type, const gchar *message, GtkWindow *parent); void status(const gchar *status); void status2(const gchar *status); /* GTK Callbacks */ gboolean winMain_delete_event(void); void menuConnect_activate(void); void menuDisconnect_activate(void); void menuConnect2_activate(void); void menuDisconnect2_activate(void); void menuQuit_activate(void); void menuAlign_activate(void); void menuAlign1_activate(void); void menuAlign2_activate(void); void menuCamera1_activate(void); void menuCamera2_activate(void); void menuBoth_activate(void); void menuSync_activate(void); void menuLog_activate(void); void menuLog2_activate(void); void menuRecord_activate(void); void drawIR_expose_event(void); void drawIR2_expose_event(void); void set_report_mode(cwiid_wiimote_t *wiimote); void create_file_selection(int); /* Wiimote Callback */ cwiid_mesg_callback_t cwiid_callback; /* Wiimote Handler Functions */ void cwiid_ir(struct cwiid_ir_mesg *); void cwiid_ir2(struct cwiid_ir_mesg *); /* GetOpt */ #define OPTSTRING "h" extern char *optarg; extern int optind, opterr, optopt; #define USAGE "usage:%s [-h] [BDADDR]\n" /* cwiid_err_t err; void err(int id, const char *s, ...) { message(GTK_MESSAGE_ERROR, s, GTK_WINDOW(winMain)); } */ int hack = 0; int main (int argc, char *argv[]) { mclmcrInitialize(); // Call application and library initialization. Perform this // initialization before calling any API functions or // Compiler-generated libraries. if (!mclInitializeApplication(NULL,0)) { std::cerr << "could not initialize the application properly" << std::endl; return -1; } if( !libcalibInitialize() ) { std::cerr << "could not initialize the library properly" << std::endl; return -1; } else { try { MATFile *matfile = matOpen("Calib_Results_stereo.mat", "r"); om = matGetVariable(matfile, "om"); T = matGetVariable(matfile, "T"); fc_left = matGetVariable(matfile, "fc_left"); cc_left = matGetVariable(matfile, "cc_left"); kc_left = matGetVariable(matfile, "kc_left"); alpha_c_left = matGetVariable(matfile, "alpha_c_left"); fc_right = matGetVariable(matfile, "fc_right"); cc_right = matGetVariable(matfile, "cc_right"); kc_right = matGetVariable(matfile, "kc_right"); alpha_c_right = matGetVariable(matfile, "alpha_c_right"); matClose(matfile); printf("om = \n"); mlfPrintmatrix(om); printf("T = \n"); mlfPrintmatrix(T); printf("fc_left = \n"); mlfPrintmatrix(fc_left); printf("cc_left = \n"); mlfPrintmatrix(cc_left); CORBA::ORB_var orb = CORBA::ORB_init(argc, argv); //cerr << "after init" << endl; CORBA::Object_var obj = orb->string_to_object((const char*) "corbaname:rir:#Wii.Context/Lion.Object"); engine_ref = InventorEngines::SourceEngine::_narrow(obj); CORBA::Object_var obj2 = orb->string_to_object((const char*) "corbaname:rir:#Wii.Context/Sphere.Object"); //cerr << "after strtoobj" << endl; //cerr << "uri is " << orb->object_to_string(obj2) << endl; engine_ref2 = InventorEngines::SourceEngine::_narrow(obj2); //cerr << "after narrow" << endl; if (CORBA::is_nil(engine_ref)) { cerr << "Can't narrow lion to SourceEngine" << endl; return -1; } if (CORBA::is_nil(engine_ref2)) { cerr << "Can't narrow sphere to SourceEngine" << endl; return -1; } /* int c; char *str_addr; apparently unused */ gtk_set_locale (); gtk_init (&argc, &argv); if (!g_thread_supported()) { g_thread_init(NULL); } gdk_threads_init(); gdk_threads_enter(); bdaddr = *BDADDR_ANY; bdaddr2 = *BDADDR_ANY; /* Create the window */ winMain = create_winMain(); /* Lookup Widgets */ menuConnect = lookup_widget(winMain, "menuConnect"); menuDisconnect = lookup_widget(winMain, "menuDisconnect"); menuQuit = lookup_widget(winMain, "menuQuit"); menuConnect2 = lookup_widget(winMain, "menuConnect2"); menuDisconnect2 = lookup_widget(winMain, "menuDisconnect2"); menuCamera1 = lookup_widget(winMain, "menuCamera1"); menuCamera2 = lookup_widget(winMain, "menuCamera2"); menuBoth = lookup_widget(winMain, "menuBoth"); menuSync = lookup_widget(winMain, "menuSync"); menuLog = lookup_widget(winMain, "menuLog"); menuLog2 = lookup_widget(winMain, "menuLog2"); menuAlign = lookup_widget(winMain, "menuAlign"); menuAlign1 = lookup_widget(winMain, "menuAlign1"); menuAlign2 = lookup_widget(winMain, "menuAlign2"); menuRecord = lookup_widget(winMain, "menuRecord"); lblIR = lookup_widget(winMain, "lblIR"); drawIR = lookup_widget(winMain, "drawIR"); lblIR2 = lookup_widget(winMain, "lblIR2"); drawIR2 = lookup_widget(winMain, "drawIR2"); statConnection = lookup_widget(winMain, "statConnection"); statBattery = lookup_widget(winMain, "statBattery"); statConnection2 = lookup_widget(winMain, "statConnection2"); statBattery2 = lookup_widget(winMain, "statBattery2"); /* Connect Callbacks */ g_signal_connect(winMain, "delete_event", G_CALLBACK(winMain_delete_event), NULL); g_signal_connect(menuConnect, "activate", G_CALLBACK(menuConnect_activate), NULL); g_signal_connect(menuDisconnect, "activate", G_CALLBACK(menuDisconnect_activate), NULL); g_signal_connect(menuConnect2, "activate", G_CALLBACK(menuConnect2_activate), NULL); g_signal_connect(menuDisconnect2, "activate", G_CALLBACK(menuDisconnect2_activate), NULL); g_signal_connect(menuQuit, "activate", G_CALLBACK(menuQuit_activate), NULL); g_signal_connect(menuCamera1, "activate", G_CALLBACK(menuCamera1_activate), NULL); g_signal_connect(menuCamera2, "activate", G_CALLBACK(menuCamera2_activate), NULL); g_signal_connect(menuBoth, "activate", G_CALLBACK(menuBoth_activate), NULL); g_signal_connect(menuSync, "activate", G_CALLBACK(menuSync_activate), NULL); g_signal_connect(menuLog, "activate", G_CALLBACK(menuLog_activate), NULL); g_signal_connect(menuLog2, "activate", G_CALLBACK(menuLog2_activate), NULL); g_signal_connect(menuAlign, "activate", G_CALLBACK(menuAlign_activate), NULL); g_signal_connect(menuAlign1, "activate", G_CALLBACK(menuAlign1_activate), NULL); g_signal_connect(menuAlign2, "activate", G_CALLBACK(menuAlign2_activate), NULL); g_signal_connect(menuRecord, "activate", G_CALLBACK(menuRecord_activate), NULL); g_signal_connect(drawIR, "expose_event", G_CALLBACK(drawIR_expose_event), NULL); g_signal_connect(drawIR2, "expose_event", G_CALLBACK(drawIR2_expose_event), NULL); swaps1[0] = swaps1[1] = swaps1[2] = swaps1[3] = 3; swaps2[0] = swaps2[1] = swaps2[2] = swaps2[3] = 3; /* Initialize */ set_gui_state(); clear_widgets(); status("No connection"); status2("No connection"); gtk_widget_show(winMain); gtk_main(); gdk_threads_leave(); } // end of try catch (const mwException& e) { std::cerr << e.what() << std::endl; return -2; } catch(CORBA::TRANSIENT&) { cerr << "Caught system exception TRANSIENT -- unable to contact the " << "server." << endl; } catch(CORBA::SystemException& ex) { cerr << "Caught a CORBA::" << ex._name() << endl; } catch(CORBA::Exception& ex) { cerr << "Caught CORBA::Exception: " << ex._name() << endl; } catch(omniORB::fatalException& fe) { cerr << "Caught omniORB::fatalException:" << endl; cerr << " file: " << fe.file() << endl; cerr << " line: " << fe.line() << endl; cerr << " mesg: " << fe.errmsg() << endl; } catch (...) { std::cerr << "Unexpected error thrown" << std::endl; return -3; } // Call the application and library termination routine libcalibTerminate(); } // end of else /* Note that you should call mclTerminate application at the end of * your application. */ mclTerminateApplication(); return 0; } void message(GtkMessageType type, const gchar *message, GtkWindow *parent) { GtkWidget *dialog; dialog = gtk_message_dialog_new(parent, GTK_DIALOG_DESTROY_WITH_PARENT, type, GTK_BUTTONS_OK, message); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } void status(const gchar *status) { gtk_statusbar_push(GTK_STATUSBAR(statConnection), 0, status); } void status2(const gchar *status) { gtk_statusbar_push(GTK_STATUSBAR(statConnection2), 0, status); } void set_gui_state() { gboolean connected, connected2; // gboolean acc_active; connected = wiimote ? TRUE : FALSE; connected2 = wiimote2 ? TRUE : FALSE; /* Set Input Widget Sensitivities */ gtk_widget_set_sensitive(menuConnect, !connected); gtk_widget_set_sensitive(menuDisconnect, connected); gtk_widget_set_sensitive(menuConnect2, !connected2); gtk_widget_set_sensitive(menuDisconnect2, connected2); /* Set IC Widget Sensitivities */ gtk_widget_set_sensitive(lblIR, TRUE); gtk_widget_set_sensitive(lblIR2, TRUE); } void clear_widgets() { gtk_statusbar_push(GTK_STATUSBAR(statBattery), 0, ""); clear_ir_data(); } void clear_widgets2() { gtk_statusbar_push(GTK_STATUSBAR(statBattery2), 0, ""); clear_ir_data2(); } void clear_ir_data() { int i; for (i=0; i < CWIID_IR_SRC_COUNT; i++) { ir_data.src[i].pos[CWIID_X] = -1; ir_data.src[i].pos[CWIID_Y] = -1; ir_data.src[i].size = -1; } gtk_widget_queue_draw(drawIR); } void clear_ir_data2() { int i; for (i=0; i < CWIID_IR_SRC_COUNT; i++) { ir_data2.src[i].pos[CWIID_X] = -1; ir_data2.src[i].pos[CWIID_Y] = -1; ir_data2.src[i].size = -1; } gtk_widget_queue_draw(drawIR2); } gboolean winMain_delete_event(void) { menuQuit_activate(); return FALSE; } void menuSync_activate(void) { if(!wiimote) { message(GTK_MESSAGE_ERROR, "Could not synchronise - controller 1 is not connected", GTK_WINDOW(winMain)); return; } if(!wiimote2) { message(GTK_MESSAGE_ERROR, "Could not synchronise - controller 2 is not connected", GTK_WINDOW(winMain)); return; } uint8_t rpt_mode; rpt_mode = CWIID_RPT_STATUS | CWIID_RPT_BTN; if (cwiid_set_rpt_mode(wiimote, rpt_mode) || cwiid_set_rpt_mode(wiimote2, rpt_mode)) { message(GTK_MESSAGE_ERROR, "error setting report mode", GTK_WINDOW(winMain)); } rpt_mode |= CWIID_RPT_IR; if (cwiid_set_rpt_mode(wiimote, rpt_mode) || cwiid_set_rpt_mode(wiimote2, rpt_mode)) { message(GTK_MESSAGE_ERROR, "error setting report mode", GTK_WINDOW(winMain)); } cwiid_set_led(wiimote, CWIID_LED1_ON | CWIID_LED3_ON | CWIID_LED4_ON ); cwiid_set_led(wiimote2, CWIID_LED2_ON | CWIID_LED3_ON | CWIID_LED4_ON ); cwiid_set_led(wiimote, CWIID_LED1_ON); cwiid_set_led(wiimote2, CWIID_LED2_ON); } void menuConnect_activate(void) { char reset_bdaddr = 0; if (bacmp(&bdaddr, BDADDR_ANY) == 0) { reset_bdaddr = 1; } message(GTK_MESSAGE_INFO, "Put Wiimote in discoverable mode (press 1+2) and press OK", GTK_WINDOW(winMain)); if ((wiimote = cwiid_open(&bdaddr, CWIID_FLAG_MESG_IFC)) == NULL) { message(GTK_MESSAGE_ERROR, "Unable to connect", GTK_WINDOW(winMain)); status("No connection"); } else if (cwiid_set_mesg_callback(wiimote, &cwiid_callback)) { message(GTK_MESSAGE_ERROR, "Error setting callback", GTK_WINDOW(winMain)); if (cwiid_close(wiimote)) { message(GTK_MESSAGE_ERROR, "Error on disconnect", GTK_WINDOW(winMain)); } wiimote = NULL; status("No connection"); } else { cwiid_set_led(wiimote, CWIID_LED1_ON); status("Connected"); /* if (cwiid_get_acc_cal(wiimote, CWIID_EXT_NONE, &wm_cal)) { message(GTK_MESSAGE_ERROR, "Unable to retrieve accelerometer " "calibration", GTK_WINDOW(winMain)); } */ set_gui_state(); set_report_mode(wiimote); cwiid_request_status(wiimote); } if (reset_bdaddr) { bdaddr = *BDADDR_ANY; } } void menuDisconnect_activate(void) { cwiid_set_led(wiimote, 0); if (cwiid_close(wiimote)) { message(GTK_MESSAGE_ERROR, "Error on disconnect", GTK_WINDOW(winMain)); } wiimote = NULL; status("No connection"); clear_widgets(); set_gui_state(); } void menuConnect2_activate(void) { char reset_bdaddr = 0; if (bacmp(&bdaddr2, BDADDR_ANY) == 0) { reset_bdaddr = 1; } message(GTK_MESSAGE_INFO, "Put Wiimote in discoverable mode (press 1+2) and press OK", GTK_WINDOW(winMain)); if ((wiimote2 = cwiid_open(&bdaddr2, CWIID_FLAG_MESG_IFC)) == NULL) { message(GTK_MESSAGE_ERROR, "Unable to connect", GTK_WINDOW(winMain)); status2("No connection"); } else if (cwiid_set_mesg_callback(wiimote2, &cwiid_callback)) { message(GTK_MESSAGE_ERROR, "Error setting callback", GTK_WINDOW(winMain)); if (cwiid_close(wiimote2)) { message(GTK_MESSAGE_ERROR, "Error on disconnect", GTK_WINDOW(winMain)); } wiimote2 = NULL; status2("No connection"); } else { cwiid_set_led(wiimote2, CWIID_LED2_ON); status2("Connected"); /* if (cwiid_get_acc_cal(wiimote, CWIID_EXT_NONE, &wm_cal)) { message(GTK_MESSAGE_ERROR, "Unable to retrieve accelerometer " "calibration", GTK_WINDOW(winMain)); } */ set_gui_state(); set_report_mode(wiimote2); cwiid_request_status(wiimote2); } if (reset_bdaddr) { bdaddr2 = *BDADDR_ANY; } /* gettimeofday(&t, NULL); printf("%d\n", (t.tv_sec * 1000000) + t.tv_usec); */ } void menuDisconnect2_activate(void) { cwiid_set_led(wiimote2, 0); if (cwiid_close(wiimote2)) { message(GTK_MESSAGE_ERROR, "Error on disconnect", GTK_WINDOW(winMain)); } wiimote2 = NULL; status2("No connection"); clear_widgets2(); set_gui_state(); } void menuQuit_activate(void) { if (wiimote) { menuDisconnect_activate(); } if (wiimote2) { menuDisconnect2_activate(); } if(file1) menuLog_activate(); if(file2) menuLog2_activate(); if(file3) menuRecord_activate(); printf("\n"); /* gettimeofday(&t, NULL); printf("%d\n", (t.tv_sec * 1000000) + t.tv_usec); */ gtk_main_quit(); } int compare_x(const void *p1, const void *p2) { const struct coord *c1 = (struct coord*)p1; const struct coord *c2 = (struct coord*)p2; return (c1->x)-(c2->x); } int compare_y(const void *p1, const void *p2) { const struct coord *c1 = (struct coord*)p1; const struct coord *c2 = (struct coord*)p2; return (c1->y)-(c2->y); } int compare_y_inv(const void *p1, const void *p2) { const struct coord *c1 = (struct coord*)p1; const struct coord *c2 = (struct coord*)p2; return (c2->y)-(c1->y); } int get_coords(int controller, struct coord* coords) { cwiid_wiimote_t *wii; if(controller == 1) wii = wiimote; else wii = wiimote2; int i; if(wii) { for (i=0; i < CWIID_IR_SRC_COUNT; i++) { if(controller == 1) { if (ir_data.src[i].valid) { struct coord c; c.x = ir_data.src[i].pos[CWIID_X]; c.y = ir_data.src[i].pos[CWIID_Y]; if(c.x > 1024 || c.x < 0 || c.y > 768 || c.y < 0) { message(GTK_MESSAGE_ERROR, "Could not capture - controller 1 data invalid", GTK_WINDOW(winMain)); return 1; } c.pt = i; coords[i] = c; } else { message(GTK_MESSAGE_ERROR, "Could not capture - controller 1 does not see 4 points", GTK_WINDOW(winMain)); return 1; } } else { if (ir_data2.src[i].valid) { struct coord c; c.x = ir_data2.src[i].pos[CWIID_X]; c.y = ir_data2.src[i].pos[CWIID_Y]; if(c.x > 1024 || c.x < 0 || c.y > 768 || c.y < 0) { message(GTK_MESSAGE_ERROR, "Could not capture - controller 2 data invalid", GTK_WINDOW(winMain)); return 1; } c.pt = i; coords[i] = c; } else { message(GTK_MESSAGE_ERROR, "Could not capture - controller 2 does not see 4 points", GTK_WINDOW(winMain)); return 1; } } } } else { message(GTK_MESSAGE_ERROR, "Could not capture - controller is not connected", GTK_WINDOW(winMain)); return 1; } return 0; } void capture(int controller) { struct coord coords[4]; FILE *file; int *swaps; if(get_coords(controller, coords)); return; if(controller == 1) { file = file1; swaps = swaps1; } else { file = file2; swaps = swaps2; } if(swaps[0] == swaps[1]) { // order bottom left, top left, top right, bottom left // haven't done align yet qsort(coords, 4, sizeof(struct coord), compare_x); qsort(coords, 2, sizeof(struct coord), compare_y); qsort(coords+2, 2, sizeof(struct coord), compare_y_inv); } else { // return in order specified by align struct coord coordstemp[4]; coordstemp[swaps[0]] = coords[0]; coordstemp[swaps[1]] = coords[1]; coordstemp[swaps[2]] = coords[2]; coordstemp[swaps[3]] = coords[3]; coords[0] = coordstemp[0]; coords[1] = coordstemp[1]; coords[2] = coordstemp[2]; coords[3] = coordstemp[3]; } // Wii puts origin in bottom left, Y up; toolbox in top left, Y down. Convert by subtracting y from 768. if(file) fprintf(file, "X_%d = [ 0 1 1 0 ; 0 0 1 1 ; 0 0 0 0 ];\nx_%d = [ %d %d %d %d ; %d %d %d %d ];\n", xi, xi, coords[1].x, coords[2].x, coords[3].x, coords[0].x, 768 - coords[1].y, 768 - coords[2].y, 768 - coords[3].y, 768 - coords[0].y); else printf("X_%d = [ 0 1 1 0 ; 0 0 1 1 ; 0 0 0 0 ];\nx_%d = [ %d %d %d %d ; %d %d %d %d ];\n", xi, xi, coords[1].x, coords[2].x, coords[3].x, coords[0].x, 768 - coords[1].y, 768 - coords[2].y, 768 - coords[3].y, 768 - coords[0].y); xi++; } void capture_both(void) { struct coord coords[4]; struct coord coords2[4]; if(get_coords(1, coords)) return; if(get_coords(2, coords2)) return; if(swaps1[0] == swaps1[1]) { // order bottom left, top left, top right, bottom left // haven't done align yet qsort(coords, 4, sizeof(struct coord), compare_x); qsort(coords, 2, sizeof(struct coord), compare_y); qsort(coords+2, 2, sizeof(struct coord), compare_y_inv); } else { // return in order specified by align struct coord coordstemp[4]; coordstemp[swaps1[0]] = coords[0]; coordstemp[swaps1[1]] = coords[1]; coordstemp[swaps1[2]] = coords[2]; coordstemp[swaps1[3]] = coords[3]; coords[0] = coordstemp[0]; coords[1] = coordstemp[1]; coords[2] = coordstemp[2]; coords[3] = coordstemp[3]; } // Wii puts origin in bottom left, Y up; toolbox in top left, Y down. Convert by subtracting y from 768. if(file1) fprintf(file1, "X_%d = [ 0 1 1 0 ; 0 0 1 1 ; 0 0 0 0 ];\nx_%d = [ %d %d %d %d ; %d %d %d %d ];\n", xi, xi, coords[1].x, coords[2].x, coords[3].x, coords[0].x, 768 - coords[1].y, 768 - coords[2].y, 768 - coords[3].y, 768 - coords[0].y); else printf("X_%d = [ 0 1 1 0 ; 0 0 1 1 ; 0 0 0 0 ];\nx_%d = [ %d %d %d %d ; %d %d %d %d ];\n", xi, xi, coords[1].x, coords[2].x, coords[3].x, coords[0].x, 768 - coords[1].y, 768 - coords[2].y, 768 - coords[3].y, 768 - coords[0].y); if(swaps2[0] == swaps2[1]) { // order bottom left, top left, top right, bottom left // haven't done align yet qsort(coords2, 4, sizeof(struct coord), compare_x); qsort(coords2, 2, sizeof(struct coord), compare_y); qsort(coords2+2, 2, sizeof(struct coord), compare_y_inv); } else { // return in order specified by align struct coord coordstemp[4]; coordstemp[swaps2[0]] = coords2[0]; coordstemp[swaps2[1]] = coords2[1]; coordstemp[swaps2[2]] = coords2[2]; coordstemp[swaps2[3]] = coords2[3]; coords2[0] = coordstemp[0]; coords2[1] = coordstemp[1]; coords2[2] = coordstemp[2]; coords2[3] = coordstemp[3]; } if(file2) { fprintf(file2, "X_%d = [ 0 1 1 0 ; 0 0 1 1 ; 0 0 0 0 ];\nx_%d = [ %d %d %d %d ; %d %d %d %d ];\n", xi, xi, coords2[1].x, coords2[2].x, coords2[3].x, coords2[0].x, 768 - coords2[1].y, 768 - coords2[2].y, 768 - coords2[3].y, 768 - coords2[0].y); } else { printf("X_%d = [ 0 1 1 0 ; 0 0 1 1 ; 0 0 0 0 ];\nx_%d = [ %d %d %d %d ; %d %d %d %d ];\n", xi, xi, coords2[1].x, coords2[2].x, coords2[3].x, coords2[0].x, 768 - coords2[1].y, 768 - coords2[2].y, 768 - coords2[3].y, 768 - coords2[0].y); } xi++; } void record() { /* int x1, y1, x2, y2; int i; if(wiimote) { for (i=0; i < CWIID_IR_SRC_COUNT; i++) { if (ir_data.src[i].valid) { x1 = ir_data.src[i].pos[CWIID_X]; y1 = ir_data.src[i].pos[CWIID_Y]; break; } else if(i == CWIID_IR_SRC_COUNT) { // message(GTK_MESSAGE_ERROR, "Could not capture - controller 1 does not see point", GTK_WINDOW(winMain)); return; } } } else { // message(GTK_MESSAGE_ERROR, "Could not capture - controller 1 is not connected", GTK_WINDOW(winMain)); return; } if(wiimote2) { for (i=0; i < CWIID_IR_SRC_COUNT; i++) { if (ir_data2.src[i].valid) { x2 = ir_data2.src[i].pos[CWIID_X]; y2 = ir_data2.src[i].pos[CWIID_Y]; break; } else if(i == CWIID_IR_SRC_COUNT) { // message(GTK_MESSAGE_ERROR, "Could not capture - controller 1 does not see point", GTK_WINDOW(winMain)); return; } } } else { // message(GTK_MESSAGE_ERROR, "Could not capture - controller 1 is not connected", GTK_WINDOW(winMain)); return; } if(x1 > 1024 || x2 > 1024 || y1 > 768 || y2 > 768) return; // obviously nonsense point //if(hack == 0) printf("[%d %d %d %d]\n", x1, y1, x2, y2); // hack++; // if(hack == 2) // hack = 0; */ struct coord coords[4]; struct coord coords2[4]; int i; if(wiimote) { for (i=0; i < CWIID_IR_SRC_COUNT; i++) { if (ir_data.src[i].valid) { struct coord c; c.x = ir_data.src[i].pos[CWIID_X]; c.y = 768 - ir_data.src[i].pos[CWIID_Y]; if(c.x > 1024 || c.x < 0 || c.y > 768 || c.y < 0) { message(GTK_MESSAGE_ERROR, "Could not capture - controller 1 data invalid", GTK_WINDOW(winMain)); return; } c.pt = i; coords[i] = c; } else { struct coord c; c.x = -1; c.y = -1; c.pt = i; coords[i] = c; } } } else { message(GTK_MESSAGE_ERROR, "Could not capture - controller is not connected", GTK_WINDOW(winMain)); return; } if(wiimote2) { for (i=0; i < CWIID_IR_SRC_COUNT; i++) { if (ir_data2.src[i].valid) { struct coord c; c.x = ir_data2.src[i].pos[CWIID_X]; c.y = 768 - ir_data2.src[i].pos[CWIID_Y]; if(c.x > 1024 || c.x < 0 || c.y > 768 || c.y < 0) { message(GTK_MESSAGE_ERROR, "Could not capture - controller 1 data invalid", GTK_WINDOW(winMain)); return; } c.pt = i; coords2[i] = c; } else { struct coord c; c.x = -1; c.y = -1; c.pt = i; coords2[i] = c; } } } else { message(GTK_MESSAGE_ERROR, "Could not capture - controller is not connected", GTK_WINDOW(winMain)); return; } if(swaps1[0] == swaps1[1]) { // order bottom left, top left, top right, bottom left // haven't done align yet qsort(coords, 4, sizeof(struct coord), compare_x); qsort(coords, 2, sizeof(struct coord), compare_y); qsort(coords+2, 2, sizeof(struct coord), compare_y_inv); } else { // return in order specified by align struct coord coordstemp[4]; coordstemp[swaps1[0]] = coords[0]; coordstemp[swaps1[1]] = coords[1]; coordstemp[swaps1[2]] = coords[2]; coordstemp[swaps1[3]] = coords[3]; coords[0] = coordstemp[0]; coords[1] = coordstemp[1]; coords[2] = coordstemp[2]; coords[3] = coordstemp[3]; } // Wii puts origin in bottom left, Y up; toolbox in top left, Y down. Convert by subtracting y from 768. if(swaps2[0] == swaps2[1]) { // order bottom left, top left, top right, bottom left // haven't done align yet qsort(coords2, 4, sizeof(struct coord), compare_x); qsort(coords2, 2, sizeof(struct coord), compare_y); qsort(coords2+2, 2, sizeof(struct coord), compare_y_inv); } else { // return in order specified by align struct coord coordstemp[4]; coordstemp[swaps2[0]] = coords2[0]; coordstemp[swaps2[1]] = coords2[1]; coordstemp[swaps2[2]] = coords2[2]; coordstemp[swaps2[3]] = coords2[3]; coords2[0] = coordstemp[0]; coords2[1] = coordstemp[1]; coords2[2] = coordstemp[2]; coords2[3] = coordstemp[3]; } printf(" [%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d]\n", coords[0].x, coords[0].y, coords2[0].x, coords2[0].y, coords[1].x, coords[1].y, coords2[1].x, coords2[1].y, coords[2].x, coords[2].y, coords2[2].x, coords2[2].y, coords[3].x, coords[3].y, coords2[3].x, coords2[3].y); int count = 0; for(int i = 0; i < 4; i++) { if(coords[i].x != -1 || coords[i].y != -1 || coords2[i].x != -1 || coords2[i].y != -1) count++; } if(count > 0) { mxArray *pts1, *pts2; pts1 = mxCreateDoubleMatrix(2, count, mxREAL); pts2 = mxCreateDoubleMatrix(2, count, mxREAL); double pts1_pr[2 * count]; double pts2_pr[2 * count]; int j = 0; for(int i = 0; i < 4; i++) { if(coords[i].x != -1 || coords[i].y != -1 || coords2[i].x != -1 || coords2[i].y != -1) { pts1_pr[j] = coords[i].x; pts1_pr[j+1] = coords[i].y; pts2_pr[j] = coords2[i].x; pts2_pr[j+1] = coords2[i].y; j += 2; } } memcpy(mxGetPr(pts1), pts1_pr, 2 * count * sizeof(double)); memcpy(mxGetPr(pts2), pts2_pr, 2 * count * sizeof(double)); //mlfPrintmatrix(pts1); //mlfPrintmatrix(pts2); mxArray *XL = NULL; mxArray *XR = NULL; mlfStereo_triangulation(2, &XL, &XR, pts1,pts2,om,T,fc_left,cc_left,kc_left,alpha_c_left,fc_right,cc_right,kc_right,alpha_c_right); printf("XL = \n"); mlfPrintmatrix(XL); try { if(count == 4) { mxArray *ret = NULL; mlfPose_recovery(1, &ret, XL); mlfPrintmatrix(ret); double *ret_pr = mxGetPr(ret); InventorEngines::Position3f pos; InventorEngines::Quaternion4f ori; pos[0] = ret_pr[0]; pos[1] = ret_pr[1]; pos[2] = ret_pr[2]; ori[0] = ret_pr[3]; ori[1] = ret_pr[4]; ori[2] = ret_pr[5]; ori[3] = ret_pr[6]; engine_ref->setPose(pos, ori); } else { InventorEngines::Position3f pos2; double *XL_pr = mxGetPr(XL); //printf("size: %d %d\n", mxGetM(XL), mxGetN(XL)); pos2[0] = XL_pr[0]; pos2[1] = XL_pr[1]; pos2[2] = XL_pr[2]; //printf("pos2: %f %f %f\n", XL_pr[0], XL_pr[1], XL_pr[2]); engine_ref2->setPosition(pos2); } } catch (CORBA::TRANSIENT& ) { cerr << "caught a CORBA::TRANSIENT but carrying on regardless" << endl; } } } void menuCamera1_activate(void) { capture(1); } void menuCamera2_activate(void) { capture(2); } void menuBoth_activate(void) { capture_both(); } void menuLog_activate(void) { if(file1) { write_post(file1); fclose(file1); file1 = NULL; } else create_file_selection(1); } void menuLog2_activate(void) { if(file2) { write_post(file2); fclose(file2); file2 = NULL; } else create_file_selection(2); } void menuAlign1_activate(void) { struct coord coords[4]; if(get_coords(1, coords)) return; qsort(coords, 4, sizeof(struct coord), compare_x); qsort(coords, 2, sizeof(struct coord), compare_y); qsort(coords+2, 2, sizeof(struct coord), compare_y_inv); for(int i = 0; i < 4; i++) { swaps1[coords[i].pt] = i; } } void menuAlign2_activate(void) { struct coord coords[4]; if(get_coords(2, coords)) return; qsort(coords, 4, sizeof(struct coord), compare_x); qsort(coords, 2, sizeof(struct coord), compare_y); qsort(coords+2, 2, sizeof(struct coord), compare_y_inv); for(int i = 0; i < 4; i++) { swaps2[coords[i].pt] = i; } } void menuAlign_activate(void) { /* int i; struct coord coords[4], coords2[4]; if(wiimote) { for (i=0; i < CWIID_IR_SRC_COUNT; i++) { if (ir_data.src[i].valid) { struct coord c; c.x = ir_data.src[i].pos[CWIID_X] - 512; c.y = ir_data.src[i].pos[CWIID_Y] - 384; c.pt = i; coords[i] = c; } else { message(GTK_MESSAGE_ERROR, "Could not align - controller 1 does not see 4 points", GTK_WINDOW(winMain)); return; } } } else { message(GTK_MESSAGE_ERROR, "Could not align - controller 1 is not connected", GTK_WINDOW(winMain)); return; } if(wiimote2) { for (i=0; i < CWIID_IR_SRC_COUNT; i++) { if (ir_data2.src[i].valid) { struct coord c; c.x = ir_data2.src[i].pos[CWIID_X] - 512; c.y = ir_data2.src[i].pos[CWIID_Y] - 384; c.pt = i; coords2[i] = c; } else { message(GTK_MESSAGE_ERROR, "Could not align - controller 2 does not see 4 points", GTK_WINDOW(winMain)); return; } } } else { message(GTK_MESSAGE_ERROR, "Could not align - controller 2 is not connected", GTK_WINDOW(winMain)); return; } qsort(coords, 4, sizeof(struct coord), compare_x); qsort(coords, 2, sizeof(struct coord), compare_y); qsort(coords+2, 2, sizeof(struct coord), compare_y_inv); qsort(coords2, 4, sizeof(struct coord), compare_x); qsort(coords2, 2, sizeof(struct coord), compare_y); qsort(coords2+2, 2, sizeof(struct coord), compare_y_inv); for(i = 0; i < 4; i++) { swaps[coords2[i].pt] = coords[i].pt; } */ menuAlign1_activate(); menuAlign2_activate(); } void menuRecord_activate(void) { if(file3) { pclose(file3); file3 = NULL; } else file3 = popen ("./tri.sh", "w"); } void drawIR_expose_event(void) { int i; int size; gint width, height; gdk_window_get_geometry(drawIR->window, NULL, NULL, &width, &height, NULL); GdkGC *gc; GdkColor colours[] = { { 0, 0xFFFF, 0x0000, 0x0000 }, { 0, 0x0000, 0xFFFF, 0x0000 }, { 0, 0x0000, 0x0000, 0xFFFF }, { 0, 0x0000, 0x0000, 0x0000 } }; GdkColormap *cmap = gdk_colormap_get_system( ); for (i=0; i < CWIID_IR_SRC_COUNT; i++) { if (ir_data.src[i].valid) { if (ir_data.src[i].size == -1) { size = 3; } else { size = ir_data.src[i].size+1; } gdk_colormap_alloc_color(cmap, colours+swaps1[i], FALSE, TRUE); gc = gdk_gc_new(drawIR->window); gdk_gc_set_foreground(gc, colours+swaps1[i]); gdk_draw_arc(drawIR->window, // drawIR->style->fg_gc[GTK_WIDGET_STATE(drawIR)], gc, TRUE, ir_data.src[i].pos[CWIID_X] * width / CWIID_IR_X_MAX, height - ir_data.src[i].pos[CWIID_Y] * height / CWIID_IR_Y_MAX, size, size, 0, 64 * 360); } } } void drawIR2_expose_event(void) { int i; int size; gint width, height; gdk_window_get_geometry(drawIR2->window, NULL, NULL, &width, &height, NULL); GdkGC *gc; GdkColor colours[] = { { 0, 0xFFFF, 0x0000, 0x0000 }, { 0, 0x0000, 0xFFFF, 0x0000 }, { 0, 0x0000, 0x0000, 0xFFFF }, { 0, 0x0000, 0x0000, 0x0000 } }; GdkColormap *cmap = gdk_colormap_get_system( ); for (i=0; i < CWIID_IR_SRC_COUNT; i++) { if (ir_data2.src[i].valid) { if (ir_data2.src[i].size == -1) { size = 3; } else { size = ir_data2.src[i].size+1; } gdk_colormap_alloc_color(cmap, colours+swaps2[i], FALSE, TRUE); gc = gdk_gc_new(drawIR->window); gdk_gc_set_foreground(gc, colours+swaps2[i]); gdk_draw_arc(drawIR2->window, // drawIR2->style->fg_gc[GTK_WIDGET_STATE(drawIR2)], gc, TRUE, ir_data2.src[i].pos[CWIID_X] * width / CWIID_IR_X_MAX, height - ir_data2.src[i].pos[CWIID_Y] * height / CWIID_IR_Y_MAX, size, size, 0, 64 * 360); } } } char chartox(char c) { char str[2]; char *endptr; int val; str[0] = c; str[1] = '\0'; val = strtol(str, &endptr, 16); if (*endptr != '\0') { return -1; } return (char)val; } void set_report_mode(cwiid_wiimote_t *wiimote) { uint8_t rpt_mode; rpt_mode = CWIID_RPT_STATUS | CWIID_RPT_BTN; rpt_mode |= CWIID_RPT_IR; if (cwiid_set_rpt_mode(wiimote, rpt_mode)) { message(GTK_MESSAGE_ERROR, "error setting report mode", GTK_WINDOW(winMain)); } } #define BATTERY_STR_LEN 14 /* "Battery: 100%" + '\0' */ void cwiid_callback(cwiid_wiimote_t *wiimote, int mesg_count, union cwiid_mesg mesg_array[], struct timespec *timestamp) { int i; char battery[BATTERY_STR_LEN]; // char *ext_str; // static enum cwiid_ext_type ext_type = CWIID_EXT_NONE; gdk_threads_enter(); for (i=0; i < mesg_count; i++) { switch (mesg_array[i].type) { case CWIID_MESG_STATUS: snprintf(battery, BATTERY_STR_LEN,"Battery:%d%%", (int) (100.0 * mesg_array[i].status_mesg.battery / CWIID_BATTERY_MAX)); if(wiimote == wiimote2) gtk_statusbar_push(GTK_STATUSBAR(statBattery2), 0, battery); else gtk_statusbar_push(GTK_STATUSBAR(statBattery), 0, battery); break; case CWIID_MESG_IR: if(wiimote == wiimote2) cwiid_ir2(&mesg_array[i].ir_mesg); else cwiid_ir(&mesg_array[i].ir_mesg); break; case CWIID_MESG_ERROR: if(wiimote == wiimote2) menuDisconnect2_activate(); else menuDisconnect_activate(); break; default: break; } } gdk_flush(); gdk_threads_leave(); } void cwiid_ir(struct cwiid_ir_mesg *mesg) { /* memcpy(&ir_data, mesg, sizeof(struct cwiid_ir_mesg)); */ ir_data = *mesg; gtk_widget_queue_draw(drawIR); } void cwiid_ir2(struct cwiid_ir_mesg *mesg) { /* memcpy(&ir_data, mesg, sizeof(struct cwiid_ir_mesg)); */ ir_data2 = *mesg; // if(file3) record(); gtk_widget_queue_draw(drawIR2); } void set_led(cwiid_wiimote_t *wiimote, uint8_t LED_state) { if (cwiid_set_led(wiimote, LED_state)) { message(GTK_MESSAGE_ERROR, "error setting LEDs", GTK_WINDOW(winMain)); } } /*-- Declare gloabal variables for the file dialog box and the filename --*/ GtkWidget *file_selection_box; //gchar *filename; void write_pre(FILE* file) { fprintf(file, "clear;\n\nnx = 1024;\nny = 768;\n\nNp = 4;\n\nest_alpha = 0;\n\n"); } void write_post(FILE* file) { fprintf(file, "\n\nn_ima = %d\n\n%% Set the toolbox not to prompt the user (choose default values)\n\ndont_ask = 1;\n\n%% Run the main calibration routine:\n\ngo_calib_optim;\n\n", xi-1); fprintf(file, "%% Shows the extrinsic parameters:\n\next_calib;\n\n%% Saves the results into a file called Calib_Results.mat:\n\nsaving_calib;\n\n%% Set the toolbox to normal mode of operation again:\n\ndont_ask = 0;"); } void store_filename1(GtkFileSelection *file_selection, gpointer data) { file1 = fopen(gtk_file_selection_get_filename(GTK_FILE_SELECTION(file_selection_box)),"a+"); write_pre(file1); } void store_filename2(GtkFileSelection *file_selection, gpointer data) { file2 = fopen(gtk_file_selection_get_filename(GTK_FILE_SELECTION(file_selection_box)),"a+"); write_pre(file2); } void store_filename3(GtkFileSelection *file_selection, gpointer data) { file3 = fopen(gtk_file_selection_get_filename(GTK_FILE_SELECTION(file_selection_box)),"a+"); fprintf(file3, "pts1 = [];\npts2 = [];\n\n"); } void create_file_selection(int file) { /*-- Create the selector widget --*/ file_selection_box = gtk_file_selection_new("Please select a log file"); /*-- Link the ok button to the store_filename function --*/ if(file == 1) gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(file_selection_box)->ok_button), "clicked", GTK_SIGNAL_FUNC (store_filename1), NULL); else if(file == 2) gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(file_selection_box)->ok_button), "clicked", GTK_SIGNAL_FUNC (store_filename2), NULL); else gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(file_selection_box)->ok_button), "clicked", GTK_SIGNAL_FUNC (store_filename3), NULL); /*-- Destroy the dialog box when the user clicks the ok_button --*/ gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION(file_selection_box)->ok_button), "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) file_selection_box); /*-- Destroy the dialog box when the user clicks the cancel_button --*/ gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION(file_selection_box)->cancel_button), "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) file_selection_box); /* Display the file dialog box */ gtk_widget_show (file_selection_box); }