Hey gang.
I just bought my WiiMote and am trying the library out for the first time. Very impressed! Bluetooth issues aside however thats not your fault ;)
I am using the library in a .NET 3.5 WPF project. I am getting very very slow connect rate and probably 40% failure to work with the WiiMote. If I run your test app it works very quickly but in my WPF one it fails or is dog slow to connect. Once its receiving values it is fine however.
I don't know threading well however I suspect it might be related to the conversion of your Winforms BeginInvoke to my WPF Dispatcher.Invoke. Do you know if this is the wrong way to approach this?
void wiiMote_OnWiimoteChanged(object sender, WiimoteChangedEventArgs e){ mutex.WaitOne(); Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new WiimoteChangedEventHandler(OnWiimoteChanged), sender, new object[] {e}); mutex.ReleaseMutex();}
I've tried Dispatcher.BeginInvoke() but it seems worse.
Also I have some questions about the data I am receiving. I am only seeing values change when I ROTATE the WiiMote oppose to when I move it. Can you guys please explain this behaviour to me? I am looking to detect swings however its possible to move the WiiMote without much rotation which is making it difficult to me to detect a motion.
Also I am having some difficulty distinguishing the difference between the Y and Z axis. It seems when I rotate one, the other moves along with it for the most part. I am trying to understand what movement the Z axis does isolated so I can understand its place.
I am not using IR just the WiiMote.
Sorry for the noobish questions :)
Ok I am an idiot lol. Shortly after writting the rotation vs acceleration issue I figured out that actually rotating the WiiMote is causing minor acceleration on axis and I was thinking the values I was seeing was rotation. I am now seeing acceleration rather than rotation.
I was basing my values on a scale of -1 to +1. What are the max/min values for acceleration on all 3 axis so that I can properly rate?
Still having the WPF threading issue however.
Thanks!
I'm not sure I have any answers for you off the top of my head regarding WPF. You may be the first person to try wedging this into a WPF application...
As for the accelerometer question, as you figured out, you're measuring acceleration. You're only getting changes on the axes that are affected by gravity when you rotate. You have to create a higher acceleration to get higher values, obviously.
In terms of max values, the accelerometers are currently read as an 8-bit value (0-255) and then "normalized" by correcting with the calibration information as follows:
mWiimoteState.AccelState.X = (mWiimoteState.AccelState.RawX - mWiimoteState.CalibrationInfo.X0) / (mWiimoteState.CalibrationInfo.XG - mWiimoteState.CalibrationInfo.X0);
Which is casted to a float. Ultimately it will depend on the calibration values used I suppose. You'd have to look at the calibration values returned by your Wiimote to determine what the maxes would be based on the above formula. Every Wiimote will be slightly different, so there should be a max +-.
Thanks for the reply!
I am definately having some performance issues in WPF. I don't know what it is however. It keeps hitting the same exception and it takes forever to hit or if it does work it just takes forever for the app to respond.
Here is where it always seems to fail when it does fail:
Wiimote.cs Line: 755
if(!mReadDone.WaitOne(2500, false)) throw new Exception("Error reading data from Wiimote...is it connected?");
I suspect this might be related to the same issue as the app being really slow to start however.
Any thoughts? It's a pretty simple test case to run into. Run VS 2008 Beta 2, create a WPF project, reference the WiiMote library and just connect and handle the onchange event, don't even have to use any values.
So I hit that exception about half the time when I run the app. However if I run the Winforms app its consistently working and much quicker at getting values.
I do not trust my Dispatcher use though. I'm not sure if that is the best replacement.
Is there any chance someone could look into this with me? I am not hugely knowledgable in threading and in WPF the library performs very unreliably. You have to start/stop about 3-4 times before you get it to properly work. Even when it does work it takes a long time to respond. According to the WPF documentation I am using the proper method to handle UI calls on the UI thread using the Dispatcher.
Thanks and take care.
I'm not great at threading so please forgive my lack of knowledge on this post but I am trying to debug why the library fails most of the time when running on WPF. I have tried with .NET 3.0 and the 3.5 that comes with 2008 Beta 2.
It seems that a thread somewhere is sleeping/suspended indefinately. I'm guessing for whatever reason the syncing in the lib isn't happening when run in WPF and sometimes a deadlock occurs.
If I pause the debugger it says its paused on:
private void WriteReport() on the line which says mStream.Write(mBuff, 0, REPORT_LENGTH);
I'm not sure how to check where this thread is being paused like this. I don't see any sleeps or suspends that would cause this except for a couple that say 100ms and 2500ms but I don't think those would cause this because its paused it seems indefinately.
The mStream says the thread is suspended.
Any thoughts?
Also I thought the point of async was so you didn't have to do all of this syncing?
I still don't have an answer for your main issue, but to answer the query on synchronization: The sleep of 100ms is there to slow down writes to the Wiimote. If one writes several reports to the Wiimote in quick succession, it will sometimes lock up the device. So, we sleep for a few milliseconds between writes. The 2500ms you're seeing is a "give up" time in waiting for a reply for the Wiimote. If we ask it for something and don't hear back within 2.5 seconds, we assume it's not connected any longer (or never was).
So, there's no sync'ing going on, just 1) working around a limitation of the Wiimote and 2) ensuring the library doesn't die waiting forever for a response.
Hi Synced, I think I have the solution for your problems ;)
For the WPF performance, it is a Best practice to do all the animation or UI modification in the OnRender event, this way you aren't rendering when there isn't need.
For the wiimote handling, I just do the Wiimote capturing the way the wiimotelib is designed to be used but the trick is that I keep that state on an object, which I have called JLWiimoteState (Ithink) that handles as an intermediate object and I consult that object's state from the OnRender event to apply the wiimote changes to the UI.
As for the accelerometer movement I have added a conversion factor which I apply to a 3D axis rotation, it is not perfect but it does do it's job. It can be improved much, so if you do please share :D
It can be found here: http://silverlightguy.com/2007/10/03/a-3d-control-for-a-3d-world/ with all the source code included ;)
If you like it please add a comment, too.
Thanks,
Jose