Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

WiiMoteDriver.cc

Go to the documentation of this file.
00001 /* 
00002  * This is a little test program to test your bluetooth and wiimote setup.
00003  * It should compile on any Debian distribution with the following line:
00004  * 
00005  * g++ -o test test.c -lwiimote -lbluetooth
00006  * 
00007  * If your wiimote or bluetooth libraries are in locations other than /usr, then you should
00008  * pass the compiler the -I and -L flags of their respective locations.
00009  * 
00010  * After that, all you do is run the program.
00011  * Once you connect, the program will run until you press Ctrl-C.  In the meantime,
00012  * whenever you are holding down any button on the wiimote, the current accelerometer data
00013  * will be printed to the screen.  Each accelerometer's values are given as a byte (a char)
00014  * of data, ranging from 0 to 255, so see how low or high you can get the values to go!
00015  */
00016 
00017 #ifdef __linux__
00018 #ifdef HAVE_CWIID
00019 
00020 #include <bluetooth/bluetooth.h>
00021 #include <wiimote.h>
00022 #include <stdio.h>
00023 #include <unistd.h>
00024 #include <time.h>
00025 #include <assert.h>
00026 #include <signal.h>
00027 #include <math.h>
00028 
00029 #include "WiiMoteDriver.h"
00030 
00031 #include "Shared/Config.h" //for calibration_{offset,scale}
00032 #include "IPC/Thread.h"
00033 
00034 #include <iostream>
00035 #include <sstream>
00036 #include <unistd.h>
00037 
00038 const std::string WiiMoteDriver::autoRegisterWiiMoteDriver = DeviceDriver::getRegistry().registerType<WiiMoteDriver>("WiiMote");
00039 
00040 DataCache::DataCache():acc_mesg(), btn_mesg(), number(0), state(), states(), 
00041                        cstate(0), updateCond(), updateLock(), updated(0) {
00042   
00043 }
00044 
00045 unsigned int DataCache::getData(const char *& payload, unsigned int& len, 
00046                                 unsigned int& timestamp, std::string& name){
00047   updateLock.lock();
00048   if(!updated)
00049     updateCond.wait(updateLock);
00050   updated = 0;
00051 
00052   timestamp = get_time();
00053   number++;
00054 
00055   state.str("");
00056   state << "#POS\n";
00057   state << "condensed " << RobotInfo::RobotName << "\n";
00058   
00059   state << "meta-info = ";
00060   state << timestamp;
00061   state << " ";
00062   state << number;
00063   state << "\n";
00064   
00065   state << "outputs = 0 0 0 0\n";
00066 
00067   state << "sensors = ";
00068   state << (unsigned) acc_mesg.x << " ";
00069   state << (unsigned) acc_mesg.y << " ";
00070   state << (unsigned) acc_mesg.z << "\n";
00071   state << "buttons = ";
00072 
00073   state << !!(btn_mesg.buttons & WIIMOTE_BTN_2) << " ";
00074   state << !!(btn_mesg.buttons & WIIMOTE_BTN_1) << " ";
00075   state << !!(btn_mesg.buttons & WIIMOTE_BTN_B) << " ";
00076   state << !!(btn_mesg.buttons & WIIMOTE_BTN_A) << " ";
00077   state << !!(btn_mesg.buttons & WIIMOTE_BTN_MINUS) << " ";
00078   state << !!(btn_mesg.buttons & WIIMOTE_BTN_HOME) << " ";
00079   state << !!(btn_mesg.buttons & WIIMOTE_BTN_LEFT) << " ";
00080   state << !!(btn_mesg.buttons & WIIMOTE_BTN_RIGHT) << " ";
00081   state << !!(btn_mesg.buttons & WIIMOTE_BTN_DOWN) << " ";
00082   state << !!(btn_mesg.buttons & WIIMOTE_BTN_UP) << " ";
00083   state << !!(btn_mesg.buttons & WIIMOTE_BTN_PLUS) << "\n";
00084 
00085   state << "#END\n";
00086   //cout << state.str() << endl;
00087   states[cstate] = state.str();
00088   len = states[cstate].size();
00089   name = "(none-sensor)";
00090 
00091   payload = const_cast<char *>(states[cstate].c_str());
00092   
00093   cstate = !cstate;
00094   updateLock.unlock();
00095   return number;
00096 }
00097 
00098 void DataCache::setDataSourceThread(LoadDataThread* p) {
00099   if(thread==NULL && p!=NULL) {
00100     // just starting to be used, announce what feedback we provide
00101     for(unsigned int i=0; i<NumOutputs; i++)
00102       providingOutput(i);
00103   } else if(thread!=NULL && p==NULL) {
00104     // going offline, cancel our announcement
00105     for(unsigned int i=0; i<NumOutputs; i++)
00106       ignoringOutput(i);
00107   }
00108   DataSource::setDataSourceThread(p);
00109   //if(p!=NULL)
00110   //  setSource(p->src);
00111 }
00112 
00113 void DataCache::updateAccMesg(const wiimote_acc_mesg &mesg) { 
00114   updateLock.lock();
00115   acc_mesg = mesg;
00116   updated = 1;
00117   updateCond.signal();
00118   updateLock.unlock();
00119 }
00120 
00121 void DataCache::updateBtnMesg(const wiimote_btn_mesg &mesg) {
00122   updateLock.lock();
00123   btn_mesg = mesg;
00124   updated = 1;
00125   updateCond.signal();
00126   updateLock.unlock();
00127 }
00128 
00129 
00130 
00131 static void wiimote_mesg_callback(int id, int mesg_count, union wiimote_mesg* mesg[]){
00132   if(driver){
00133     driver->mesg_callback(id, mesg_count, mesg);
00134   }
00135 }
00136 
00137 void WiiMoteDriver::mesg_callback(int id, int mesg_count, union wiimote_mesg* mesg[]){
00138   //printf("Received %d message(s).\n",mesg_count);
00139   for(int i = 0; i < mesg_count; i++){
00140     switch(mesg[i]->type){
00141       case WIIMOTE_MESG_STATUS:{
00142         printf("It's a status message.  ");
00143         printf("Battery is at %d.\n",mesg[i]->status_mesg.battery);
00144         break;
00145       }
00146       case WIIMOTE_MESG_BTN:{
00147         data.updateBtnMesg(mesg[i]->btn_mesg);
00148         break;
00149       }
00150       case WIIMOTE_MESG_ACC:{
00151         data.updateAccMesg(mesg[i]->acc_mesg);
00152         break;
00153       }
00154       default:
00155         printf("Error: Unknown type %d\n", mesg[i]->type);
00156         break;
00157     }
00158   }
00159 }
00160 
00161 void WiiMoteDriver::motionUpdated(const std::vector<size_t>& changedIndices,
00162                                   const float outputs[][NumOutputs]) {
00163   if(wiim==NULL)
00164     return;
00165 
00166   
00167 #ifdef stub_stub_stub_stub
00168   std::set<size_t> updatedIndices(changedIndices.begin(),changedIndices.end());
00169   
00170   for(unsigned int i=LEDOffset; i<LEDOffset+NumLEDs; ++i) {
00171     float v = outputs[NumFrames-1][i];
00172     if(v>0 && v<1) // intermediate value, need to flicker activation
00173       updatedIndices.insert(i);
00174   }
00175   
00176   if(updatedIndices.size()==0)
00177     return;
00178   try {
00179     ::TeRK::LEDCommand ledc;
00180     ledc.ledMask.assign(NumLEDs,false);
00181     ledc.ledModes.assign(NumLEDs,::TeRK::LEDOff);
00182   } catch(...) {
00183     std::cerr << "error" << std::endl;
00184     close();
00185   }
00186 #endif
00187 }
00188 
00189 int WiiMoteDriver::init(){
00190   /*You need an empty bdaddr_t, the bluetooth address*/
00191   bdaddr_t my_addr;
00192   memset(my_addr.b,0,sizeof(uint8_t)*6);
00193   
00194   /*Initialize your wiimote and id number*/
00195   int id = -5,status;
00196 
00197   printf("Please press the '1' and '2' buttons on your wiimote simultaneously, until "
00198     "you see the LEDs at the bottom all start flashing.\n");
00199 
00200   /* This is the first command from the wiimote library, wiimote_connect.
00201    * It will block for a few seconds or until it connects to a wiimote.
00202    * This can take up to 8 or 9 seconds, or as little as 5.
00203    */
00204   wiim = wiimote_connect(&my_addr,wiimote_mesg_callback,&id);
00205   
00206   if(wiim==NULL || id==-5){
00207     printf("Didn't connect to wiimote.\n");
00208     return -1;
00209   }
00210 
00211   printf("Connected to a wiimote.\n");
00212 
00213   /*This method tells the wiimote that we want to turn the LEDs on or off, on in this case.*/
00214   //status = wiimote_command(wiim,WIIMOTE_CMD_LED,WIIMOTE_LED1_ON);
00215   //assert(status==0);
00216   
00217   /*This method tells the wiimote to vibrate, but not for how long.*/
00218   //status = wiimote_command(wiim,WIIMOTE_CMD_RUMBLE,1);
00219   //assert(status==0);
00220   
00221   /*So we give it a time to vibrate...about .5 sec.*/
00222   //usleep(500000);
00223   
00224   //status = wiimote_command(wiim,WIIMOTE_CMD_RUMBLE,0);
00225   //assert(status==0);
00226   status = wiimote_command(wiim,WIIMOTE_CMD_RPT_MODE,
00227                            WIIMOTE_RPT_STATUS|WIIMOTE_RPT_BTN|WIIMOTE_RPT_ACC);
00228   /*
00229   while(1){
00230     usleep(1);
00231   }
00232   status = wiimote_command(wiim,WIIMOTE_CMD_LED,0);
00233   assert(status==0);
00234   printf("Disconnecting from wiimote.\n");
00235   status = wiimote_disconnect(wiim);
00236   if(status!=0){
00237     perror("Disconnect failed:");
00238     return -1;
00239   }
00240   */
00241   return 0;
00242 }
00243 
00244 #else
00245 #warning "CwiiD library not found! WiiMote driver will not be compiled!"
00246 #endif
00247 
00248 #else
00249 #warning "WiiMote driver currently only supports Linux!"
00250 #endif

Tekkotsu Hardware Abstraction Layer 5.1CVS
Generated Mon May 9 05:01:39 2016 by Doxygen 1.6.3