Sign in to follow this  
Tsunekuni

Noob Question[Wiimote]

Recommended Posts

Tsunekuni    122
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]

Share this post


Link to post
Share on other sites
lc_overlord    436
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.

Share this post


Link to post
Share on other sites
Tsunekuni    122
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

Share this post


Link to post
Share on other sites
Tsunekuni    122
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

Share this post


Link to post
Share on other sites
Krohm    5031
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.

Share this post


Link to post
Share on other sites
remigius    1172
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 :)

Share this post


Link to post
Share on other sites
Tsunekuni    122
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]

Share this post


Link to post
Share on other sites
Krohm    5031
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...

Share this post


Link to post
Share on other sites
remigius    1172
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 :)

Share this post


Link to post
Share on other sites
Tsunekuni    122
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

Share this post


Link to post
Share on other sites
remigius    1172
Interpolating the values actually is an interesting idea, I'm gonna keep that in mind for when I finally get some time to take a shot at my wiimote library plans. But since reading out the wiimote data seems to be the limiting factor in the OP's application, the best thing to try first probably is to move it to another thread. Especially if you want to be able to read out multiple wiimotes at interactive rates, one thread per wiimote might be worth considering.

The transfer speed seems a bit low though. Assuming reading the wiimote is indeed the limiting factor in your game, this would mean the IR data only comes in at some 20-25 updates per second. This probably will result in some choppy movement, so I'd image the wiimote itself is designed to support a higher transfer rate. Is there still room for optimization on reading the data? If not, interpolation definitely will help you out.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this