00001 #include "CWiidMotionReceiver.h"
00002 #include <bluetooth/bluetooth.h>
00003 #include <iostream>
00004 #include <cstdlib>
00005
00006 CWiidMotionReceiver::CWiidMotionReceiver() :
00007 m_wiimoteMacAdress("00:00:00:00:00:00")
00008 {
00009 }
00010
00011 CWiidMotionReceiver::~CWiidMotionReceiver()
00012 {
00013 stop();
00014 }
00015
00016 void CWiidMotionReceiver::start() throw(Error)
00017 {
00018 bdaddr_t addr;
00019 if (str2ba(m_wiimoteMacAdress.c_str(), &addr) != 0) {
00020 std::string err = "CWiidMotionReceiver::start(): cannot convert MAC-adress '";
00021 err += m_wiimoteMacAdress + "' to btaddr_t struct";
00022 throw Error(err.c_str());
00023 }
00024
00025
00026 m_wiimote = cwiid_open(&addr, CWIID_FLAG_MESG_IFC | CWIID_FLAG_CONTINUOUS | CWIID_FLAG_NONBLOCK);
00027 if (m_wiimote == NULL) {
00028 throw Error("CWiidMotionReceiver::start(): cannot connect to wiimote");
00029 }
00030
00031
00032 if (cwiid_get_acc_cal(m_wiimote, CWIID_EXT_NONE, &m_calibration)) {
00033 throw Error("CWiidMotionReceiver::start(): unable to retreive calibration data");
00034 }
00035
00036 cwiid_set_led(m_wiimote, CWIID_LED1_ON);
00037 }
00038
00039 void CWiidMotionReceiver::stop()
00040 {
00041
00042 setRunning(false);
00043 if (m_wiimote != NULL) {
00044 cwiid_close(m_wiimote);
00045 m_wiimote = NULL;
00046 }
00047 }
00048
00049 void CWiidMotionReceiver::run()
00050 {
00051 setRunning(true);
00052 cwiid_enable(m_wiimote, CWIID_FLAG_MESG_IFC | CWIID_FLAG_CONTINUOUS | CWIID_FLAG_NONBLOCK);
00053
00054 int msgCount = 0, status;
00055 union cwiid_mesg *msgs;
00056 struct timespec timestamp;
00057
00058 while (isRunning()) {
00059 status = cwiid_get_mesg(m_wiimote, &msgCount, &msgs, ×tamp);
00060 if (status == 0) {
00061 std::cout << "Got " << msgCount << " messages!" << std::endl;
00062 for (int i = 0; i < msgCount; ++i) {
00063 handleMessages(&msgs[i]);
00064 }
00065
00066 if (msgs != NULL) {
00067 free(msgs);
00068 msgs = NULL;
00069 }
00070 } else {
00071 std::string err = "CWiidMotionReceiver::run(): Something went wront in cwiid_get_mesg()!";
00072 throw Error(err.c_str());
00073 }
00074 }
00075 }
00076
00077
00078 void CWiidMotionReceiver::handleMessages(union cwiid_mesg *msg)
00079 {
00080 switch (msg->type) {
00081 case CWIID_MESG_BTN:
00082 handleButtons(&msg->btn_mesg);
00083 break;
00084 case CWIID_MESG_ACC:
00085 handleAccData(&msg->acc_mesg);
00086 break;
00087 case CWIID_MESG_ERROR:
00088 {
00089 std::string err = "CWiidMotionReceiver::handleMessages(): received error message #";
00090 err += msg->error_mesg.error;
00091 throw Error(err.c_str());
00092 }
00093 break;
00094 default:
00095 break;
00096 }
00097 }
00098
00099 void CWiidMotionReceiver::handleButtons(struct cwiid_btn_mesg *msg)
00100 {
00101 if (msg->buttons & CWIID_BTN_A) {
00102 setRunning(false);
00103 cwiid_disable(m_wiimote, CWIID_FLAG_MESG_IFC | CWIID_FLAG_CONTINUOUS | CWIID_FLAG_NONBLOCK);
00104 }
00105 }
00106
00107 void CWiidMotionReceiver::handleAccData(struct cwiid_acc_mesg *msg)
00108 {
00109 Vector3d v;
00110
00111
00112 v.set(0,
00113 (static_cast<double>( msg->acc[CWIID_X]) - m_calibration.zero[CWIID_X])
00114 / (m_calibration.one[CWIID_X] - m_calibration.zero[CWIID_X])
00115 );
00116 v.set(1,
00117 (static_cast<double>(msg->acc[CWIID_Y]) - m_calibration.zero[CWIID_Y])
00118 / (m_calibration.one[CWIID_Y] - m_calibration.zero[CWIID_Y])
00119 );
00120 v.set(2,
00121 (static_cast<double>(msg->acc[CWIID_Z]) - m_calibration.zero[CWIID_Z])
00122 / (m_calibration.one[CWIID_Z] - m_calibration.zero[CWIID_Z])
00123 );
00124
00125 notify(v);
00126 }