WiiMoteDriver.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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"
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
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
00101 for(unsigned int i=0; i<NumOutputs; i++)
00102 providingOutput(i);
00103 } else if(thread!=NULL && p==NULL) {
00104
00105 for(unsigned int i=0; i<NumOutputs; i++)
00106 ignoringOutput(i);
00107 }
00108 DataSource::setDataSourceThread(p);
00109
00110
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
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)
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
00191 bdaddr_t my_addr;
00192 memset(my_addr.b,0,sizeof(uint8_t)*6);
00193
00194
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
00201
00202
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
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 status = wiimote_command(wiim,WIIMOTE_CMD_RPT_MODE,
00227 WIIMOTE_RPT_STATUS|WIIMOTE_RPT_BTN|WIIMOTE_RPT_ACC);
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
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