BrianPeek.com
A Compendium of Random Uselessness
WiimoteLib Future

This Blog

Syndication

AddThis Feed Button

My Book

Microsoft MVP - C#

My GamerCard

image I’ve been working on a version 2.0 of WiimoteLib which reorganizes the library quite a bit to clean up the codebase.  It’s not quite ready for release, and I don’t have an ETA currently, but I wanted to note some of the changes and get some feedback as I finish things up.

  • I will be including a VS2010 solution for the project in addition to the original VS2008 solution
  • I’m hoping to have support for both sound and the WiiMotion Plus extension completed
  • Support for the Taiko Drum and DJ Hero turntable (testers welcome for the DJ Hero turntable)
  • Extensions have been broken out into separate classes so their code is self contained:
    • image
    • All extensions inherit from ExtensionController
    • All state objects for extensions implement the IExtensionState interface
    • Here’s an example of the new Nunchuk class.  As you can see, everything related to the Nunchuk is located in this class:
    • using System;
      using System.Drawing;
       
      namespace WiimoteLib.Extensions
      {
          public class Nunchuk : ExtensionController<NunchukState>
          {
              internal Nunchuk(Wiimote wm) : base(wm)
              {
              }
       
              internal override void Initialize()
              {
                  byte[] buff = Wiimote.ReadData(REGISTER_EXTENSION_CALIBRATION, 16);
       
                  State.CalibrationInfo.AccelCalibration.X0 = buff[0];
                  State.CalibrationInfo.AccelCalibration.Y0 = buff[1];
                  State.CalibrationInfo.AccelCalibration.Z0 = buff[2];
                  State.CalibrationInfo.AccelCalibration.XG = buff[4];
                  State.CalibrationInfo.AccelCalibration.YG = buff[5];
                  State.CalibrationInfo.AccelCalibration.ZG = buff[6];
                  State.CalibrationInfo.MaxX = buff[8];
                  State.CalibrationInfo.MinX = buff[9];
                  State.CalibrationInfo.MidX = buff[10];
                  State.CalibrationInfo.MaxY = buff[11];
                  State.CalibrationInfo.MinY = buff[12];
                  State.CalibrationInfo.MidY = buff[13];
              }
       
              internal override void ParseData(byte[] buff, int offset)
              {
                  State.RawJoystick.X = buff[offset];
                  State.RawJoystick.Y = buff[offset + 1];
                  State.AccelState.RawValues.X = buff[offset + 2];
                  State.AccelState.RawValues.Y = buff[offset + 3];
                  State.AccelState.RawValues.Z = buff[offset + 4];
       
                  State.C = (buff[offset + 5] & 0x02) == 0;
                  State.Z = (buff[offset + 5] & 0x01) == 0;
       
                  State.AccelState.Values.X = (float)((float)State.AccelState.RawValues.X - State.CalibrationInfo.AccelCalibration.X0) / 
                                                  ((float)State.CalibrationInfo.AccelCalibration.XG - State.CalibrationInfo.AccelCalibration.X0);
                  State.AccelState.Values.Y = (float)((float)State.AccelState.RawValues.Y - State.CalibrationInfo.AccelCalibration.Y0) /
                                                  ((float)State.CalibrationInfo.AccelCalibration.YG - State.CalibrationInfo.AccelCalibration.Y0);
                  State.AccelState.Values.Z = (float)((float)State.AccelState.RawValues.Z - State.CalibrationInfo.AccelCalibration.Z0) /
                                                  ((float)State.CalibrationInfo.AccelCalibration.ZG - State.CalibrationInfo.AccelCalibration.Z0);
       
                  if(State.CalibrationInfo.MaxX != 0x00)
                      State.Joystick.X = (float)((float)State.RawJoystick.X - State.CalibrationInfo.MidX) / 
                                              ((float)State.CalibrationInfo.MaxX - State.CalibrationInfo.MinX);
       
                  if(State.CalibrationInfo.MaxY != 0x00)
                      State.Joystick.Y = (float)((float)State.RawJoystick.Y - State.CalibrationInfo.MidY) / 
                                              ((float)State.CalibrationInfo.MaxY - State.CalibrationInfo.MinY);
              }
       
              public override ExtensionType ExtensionType
              {
                  get { return ExtensionType.Nunchuk; }
              }
          }
       
          /// <summary>
          /// Current state of the Nunchuk extension
          /// </summary>
          [Serializable]
          [DataContract]    
          public class NunchukState : IExtensionState
          {
              /// <summary>
              /// Calibration data for Nunchuk extension
              /// </summary>
              [DataMember]
              public NunchukCalibrationInfo CalibrationInfo;
              /// <summary>
              /// State of accelerometers
              /// </summary>
              [DataMember]
              public AccelState AccelState;
              /// <summary>
              /// Raw joystick position before normalization.  Values range between 0 and 255.
              /// </summary>
              [DataMember]
              public Point RawJoystick;
              /// <summary>
              /// Normalized joystick position.  Values range between -0.5 and 0.5
              /// </summary>
              [DataMember]
              public PointF Joystick;
              /// <summary>
              /// Digital button on Nunchuk extension
              /// </summary>
              [DataMember]
              public bool C, Z;
          }
       
          /// <summary>
          /// Calibration information stored on the Nunchuk
          /// </summary>
          [Serializable]
          [DataContract]
          public struct NunchukCalibrationInfo
          {
              /// <summary>
              /// Accelerometer calibration data
              /// </summary>
              public AccelCalibrationInfo AccelCalibration;
              /// <summary>
              /// Joystick X-axis calibration
              /// </summary>
              [DataMember]
              public byte MinX, MidX, MaxX;
              /// <summary>
              /// Joystick Y-axis calibration
              /// </summary>
              [DataMember]
              public byte MinY, MidY, MaxY;
          }
      }
       
  • Minimal changes will need to be handled in application code, which is demonstrated in the WiimoteTest application included with the library.  The biggest change is in handling extensions.  Now, the Wiimote object itself will contain an ExtentionType property.  Use this to determine which extension is attached and cast the Wiimote.ExtensionController property to the proper object to access its state information as shown:
      switch(mWiimote.ExtensionController.ExtensionType)
      {
          case ExtensionType.Nunchuk:
              NunchukState ns = ((Nunchuk)mWiimote.ExtensionController).State;
              break;
      }

      I welcome any questions, comments and concerns on the direction I’m heading.  Thanks!


      Posted Fri, May 28 2010 1:25 AM by Brian Peek

      Comments

      Alvin Ashcraft wrote re: WiimoteLib Future
      on Fri, May 28 2010 7:26 AM

      I think you ought to get started on NatalLib  :)

      Brian Peek wrote re: WiimoteLib Future
      on Fri, May 28 2010 3:11 PM

      I will the instant I get my hands on a Natal.  :)

      Alexander Sigaras wrote re: WiimoteLib Future
      on Mon, May 31 2010 5:03 AM

      Could you please include also an updated version for the Microsoft Robotics Developer Studio 2008 R3?

      Thanks

      Brian Peek wrote re: WiimoteLib Future
      on Mon, May 31 2010 5:11 PM

      @Alexander, I'll take a look...

      ericmichael wrote re: WiimoteLib Future
      on Thu, Jun 3 2010 2:53 AM

      Brian,

      I tried to modify the the 1.7 src version so it works with MRDS(R3).  I couldn't see where/how to generate the transform dll.  I got everything else to compile.  I did leave out the The Dss Service dssModel Contract(s) function because I could find the ServiceSummaryLoader anywhere.

      tip if you didn't know already :

      Microsoft.Dss.Services.ContractModel  has changed to Microsoft.Dss.Core.ContractModel

      I am very anxious to try pair my NXT to the wiimote/balanceboard.

      Thanks for sacrificing all your free time.

      Brian Peek wrote re: WiimoteLib Future
      on Thu, Jun 3 2010 4:05 AM

      @ericmichael, I haven't touched MSRS/MRDS/whatever it's called now in a very long time.  I'm hoping to make the new version of WiimoteLib compatible with the latest MRDS release, but I haven't looked at it yet.

      shaggygi wrote re: WiimoteLib Future
      on Sat, Jun 5 2010 8:08 AM

      Is or will there be an easy way on how to use this library (and WiiMote) within a Silverlight application?

      Add a Comment

      (required)  
      (optional)
      (required)  
      Remember Me?