Noob Question[Wiimote]

Started by
10 comments, last by remigius 17 years, 1 month ago
Well, I recently got a Bluetooth adapter, and I hooked up my Wiimote to it. I've been using GlovePIE, but I realized that while fun, game development with it is obviously limited. I set out to get some C++ scripts for the wiimote, and found cWiimote. I compiled and verified that everything worked. I downloaded NeHe's second lesson, and slapped in the cWiimote code, which worked as well. Then I looked up how to draw text in OpenGL(NeHe lesson 13), and slapped that in there, too. Now, I'm drawing the "supposed" X,Y, and Z values of the acceloromaters, but they don't change. I'm fairly positive I messed something up, but I'm not sure where. Keep in mind, I'm also pretty noobish at programming, so sorry for any obvious errors. So, heres my wii_draw() function that gets called within DrawGLScene.

void wii_draw()
{
	float wX,wY,wZ;
	glTranslatef(0.0f,0.0f,-1.0f);
	// Pulsing Colors Based On Text Position
	//glColor3f(1.0f*float(cos(cnt1)),1.0f*float(sin(cnt2)),1.0f-0.5f*float(cos(cnt1+cnt2)));
	// Position The Text On The Screen
	glRasterPos2f(-5, -2);
	cWiiMote wiimote;
	if (wiimote.ConnectToDevice() && wiimote.StartDataStream())
	{
			wiimote.HeartBeat();
			//wiimote.SetVibration(1);
			//wiimote.SetLEDs(1,0,1,0);
			wiimote.GetCalibratedAcceleration(wX,wY,wZ);
			glPrint("W:[X:%+1.2f,Y:%+1.2f,Z:%+1.2f]",wX,wY,wZ);	// Print GL Text To The Screen
	}
	else
	glPrint("Connection failed.");
	//cnt1+=0.051f;						// Increase The First Counter
	//cnt2+=0.005f;						// Increase The Second Counter
}

And here's the GetCalibratedAcceleration function, from cWiimote.

void cWiiMote::GetCalibratedAcceleration(float & x, float & y, float &z) const
{
 	x = (mLastMotionReport.mX - mAccelCalibrationData.mXZero) / (float)(mAccelCalibrationData.mXG- mAccelCalibrationData.mXZero);
	y = (mLastMotionReport.mY - mAccelCalibrationData.mYZero) / (float)(mAccelCalibrationData.mYG- mAccelCalibrationData.mYZero);
	z = (mLastMotionReport.mZ - mAccelCalibrationData.mZZero) / (float)(mAccelCalibrationData.mZG- mAccelCalibrationData.mZZero);
}

Again, sorry if I've made an obvious/noob mistake. :P [Edited by - Tsunekuni on March 4, 2007 7:49:55 PM]
Advertisement
I cant really help you as i don't see any obvious mistake, you could try to introduce your own values, like replace wX with your own value just before glPrint, if the printout changes then the bug might be within wiimote.GetCalibratedAcceleration.

If so then try feeding it the raw data, wX=mLastMotionReport.mX; might do, change things like that until you zero in on the problem.

Edit: or it could be that mLastMotionReport.mX and mAccelCalibrationData.mXZero might be the same, since you seem to be starting the device within the rendering loop.
Well, I tried both of those and they both didn't work. I, however, moved the device initialization to the beggining of the program, and the device still makes a connection.

I tried to get raw data, but the values are in the private section of the cWiimote script. I also replaced the value of wX before the glPrint, and it the printout stayed to what I set it to.

I'm not entirely sure what to do; I'll keep trying things. If you want, I could upload my project files to megaupload or something of the like so you could take a closer look.

Thanks alot for your help so far. :D
Thought I might update(sorry for the double post :P).

I turned on Fraps, and added some code so that a triangle would follow the wiimote. To my suprise, it somewhat worked. It seems, though, that the signal is very sporadic(as I'm calling the heartbeat in the render loop.) The triangle would flicker on and off, vibrating when the code was updating. I wiggled around some windows, and again, to my suprise, the heartbeat strengthed and I got a near perfect signal, so long as I wiggled a window. I think I'm getting closer. :P
A friend of mine is working on a project which uses wii-motes rather heavily. He told me its one has been detected as a standard HID device and all the programs (even WinAMP) recognized it as a joystick... How this exactly works is beyond me but I believe you shouldn't need any special library at compile time.

Previously "Krohm"

From what I've read the WiiMote is indeed recognized as a bluetooth HID device. Unfortunately it seems it kinda abuses the HID specification, so applications don't know what to do with it exactly. So even though it's recognized, you can't use it out of the box. Maybe some driver has been written in the meantime that allows the wiimote to be recognized as a joystick, but I haven't seen anything about that yet. Your friend might have come to that conclusion because there's a Winamp plugin available that supports wiimote input.

As for the problem the OP is having, you might need to turn on continuous reporting on the wiimote (as described here). I still haven't had time to look into coding my own lib, but it looks like the wiimote by default only reports back data whenever it has changed. This would explain why your program only works when you keep wiggling the wiimote; it is waiting on data to come in from the wiimote, which in turn is waiting to be moved so new data becomes available. Enabling continuous reporting should allow the wiimote to send back its unchanged state and solve this problem.

Hope this helps & good luck with your project :)
Rim van Wersch [ MDXInfo ] [ XNAInfo ] [ YouTube ] - Do yourself a favor and bookmark this excellent free online D3D/shader book!
I did a little bit of research, and discovered that cWiimote already sets the report mode to Continuous.

Now, after placing wiimote.Heartbeat() in the window drawing command, after the SwapBuffers(hDC) command, I managed to finally get results. I am able to move the triangle around without wiggiling a window. However, this solution is extremely laggy, and jittery.

After thinking and researching today, I came up with a solution: a threaded function. What I need to do is put the wiimote.Heartbeat() in a threaded function, so that 1) lag decreases majorly, and 2) constant reading of the wiimote data occurs. However, I have no idea how to setup a threaded function, so any links or guides pointing me to the right direction would be great!

Thanks again to everyone. :D

EDIT: When I say "threaded," I mean dealing with wiimote.Heartbeat() in a different thread, as stated on the cWiimote homepage.

[Edited by - Tsunekuni on March 6, 2007 7:55:27 PM]
Quote:Original post by remigius
Your friend might have come to that conclusion because there's a Winamp plugin available that supports wiimote input.

It is a possibility but it works anyway in other programs as well - in fact he used it as a drop-in replacement for the previous accelerometer.
(A little note: the previous accelerometer was about 900$ **grin** )
Quote:Original post by remigiuslooks like the wiimote by default only reports back data whenever it has changed.

Yes, definetly. This is almost standard for any serious battery-saving device.
Quote:Original post by remigiusEnabling continuous reporting should allow the wiimote to send back its unchanged state and solve this problem.
It's a quick solution that does the work...

Previously "Krohm"

Quote:Original post by Krohm
Quote:Original post by remigiusEnabling continuous reporting should allow the wiimote to send back its unchanged state and solve this problem.
It's a quick solution that does the work...


Yeah, it's a bit of a messy quick solution. As the OP stated it would be much cleaner to read the data from the WiiMote in a seperate thread. I think it might be even better to do this while it's not in continuous reporting mode and keep track of the current state in some variable that gets updated from that other thread when the WiiMote does move. That way you both minimize bluetooth traffic and by retrieving the state from a local variable you keep the render loop running unobstructed.

Unfortunately I can't tell you much about threading in C++, so I can only wish you some more good luck :)
Rim van Wersch [ MDXInfo ] [ XNAInfo ] [ YouTube ] - Do yourself a favor and bookmark this excellent free online D3D/shader book!
Well, some updates - I found out that it was indeed, not set in continuous mode. I set it to continuous mode, and it now runs pretty well. However, the program only gets about 40FPS, with only a triangle being rendered.

I continued adding things, and added IR support. With IR reading, the program drops to about 15-20FPS. I think the only solution at this point is to put the heartbeat function in a thread.

Thanks for all the help so far! :D

This topic is closed to new replies.

Advertisement