Sunday, June 13, 2010

Dynamic MotionPlus (WMP,WM+) Calibration - Part 2: Reversing calibration data at a40050h

I'm not completely done with it, but this is what I got so far. This was reverse engineered by me and megazig. Megazig even reverse engineered the checksum algo, but I won't publish it, since it is of no practical use to us. I will just add that the mechanism involves summing up bytes with constant table lookups and following xor'ing, which gets done a couple of times. Apart from that a big thanks to crediar for helping us out with the necessary input.

4x16 Bytes within the active motion plus register starting at 0xA40050. Data is interleaved,
starting with a 28 byte long structure for fast motion and following 28 bytes for slow motion.
8 Byte orientation blocks consist of 2 single-precision floats, former represent zero- and later scale-values.
The yellow block represents a 32bit signed integer, which is not fully understood yet.

This is how the game splits the data at 50h into a data structure, which is 28 bytes long. After the game has copied those values to the corresponding structure/datatype, a few floatpoint calculations which I haven't completely reversed yet, will be applied on those values. The data itself most likely just represents a simple orientation matrix. Note: I don't think yaw has to be set to an exact value at the beginning, since we only want to move relative to a fixpoint. So it's possible to just set it to a pseudo-random value, and move relative to it, as soon we have visual contact to the sensorbar to adjust the yaw. More later.

5 comments:

  1. Can you give any insight into why you think this is the division? It doesn't quite look right to me. I went into the 'sport resort' trace you provided and extracted the calibration data pulled from the motion plus by searching for:
    17 04 a4 00 50 00 40
    There are four different sets of these data in the trace (each one is grabbed twice; so you know the calibration was complete and stable). I converted the data as per your description but the values don't seem sensible. For example, if you take the first two single precision floats from the first set of data, you get 7.4253E-11 and -5.9397E-2. If you take the same data from the second set of data, you get 6.5148E13 and 9.0060E19. Those numbers are so drastically different. Even if you swap endianness, it doesn't seem to help.
    So I guess I'm just curious as to what convinced you to split it up this way.

    ReplyDelete
  2. This was how data got splitted in PPC dissassembly and put into a predefined structure(function1, no modification of the data itself yet). This is just part.1, however final datatypes are correct, the values don't have to be correct yet since they could be still changed(and are), but this is how it's starts. In step 2(2nd function, which works directly with those values), data gets read from that structure and a few operation are applied on those values like sign-bit flipping, multiplying, division, addition and/or substraction. Apart from that, I noticed somewhere else, that 3 different float values got each multiplicated with the yellow block s32. It might be some sort of scale/degrees as well. I will try to finish this @weekend, since im busy during the week. Unfortunately, i couldn't find anything yet which directly works with data from 0x20-0x3f dissassemblywise.
    It seems rather that there more than just 1-2 functions that read/modify this data, or I was just too blind to find the corresponding dissassembly.

    ReplyDelete
  3. In Addition, if u want to have a chat on this, you can find me on server irc.efnet.nl nick: sanchez

    ReplyDelete
  4. Huh. Clever. Interesting that there would be 12 floats and 2 signed ints, when the 0x20 section looks like it has 12 unsigned shorts and 2 floats.
    Unfortunately, my ability to connect to IRC has been sketchy here. I think there may be some blocking around my network. I am curious though: in the traces that you provide, is the wiimote always lying face down on a flat surface during the calibration period?
    In terms of how the data are eventually used, creating an orientation matrix from the dynamic calibration data seems like an odd thing to do because, as you mentioned, as soon as you can see the IR bar and the wiimote is relatively still, the software can grab a more accurate and current approximation of the actual orientation. What the system really needs is a transformation matrix to map the numbers provided by each gyro into a consistent set of units (e.g., radians or degrees). The behavior of the gyros is most likely somewhat temperature sensitive and possibly voltage dependent (changing units as the battery dies); so recalibration of that is important, as is grabbing an estimate of where the zero is. Then the system needs some way to combine these data with the accelerometer data. This could be messy since they're separated by 9 cm or so. However, I suppose that if you treat location of the accelerometers as the reference point, then the data are largely independent.
    So it seems to me that what the wii really needs is some way to transform the 3 accel values and the 3 gyro values into a matrix that updates their current orientation matrix. If they're using a Kalman filter, which would make sense, they'll also want an estimate of the variance/noise of the system.

    ReplyDelete
  5. I have done several traces, each in various positions even standing on the head or upside down, just check the google spreadsheet for those different cases with dynamic calibration d ata. Creating an orientation matrix works, since we re only doing calibrations when the wiimote stands still which is a requirement for the success of this method, the game usually checks if theres any rotation meanwhile, as long it rotates it wont start recalibration. tbh I haven't worked on this any further since the last time. I haven't had time last weekend, and I have also 1-2 other projects running parallel which require as well some maintaining. :(
    ps i dont think the wiimote is doing any temperate drift correction, and since its that messy theres no wonder nintendo will release a new wiimote with integrated motionplus to address that problem with all those drifts, temperature etc. And i dont think the wii is doing the calculation of the matrix itself, it will just simply update the obtained matrix by the motionplus everytime it gets fresh gyro data'(so having a kalman filter would have made sense). I found some symbols that are suggesting that the wii is also applying gyrodata that has happenend meanwhile, between requesting the 0x50 data structure and obtaining it. But I have to take a second look at it, I haven't yet due the lack of time.
    However my offer is still up for having a chat and some further data exchange, it's way more efficient than always posting back and for.
    Webirc client:
    http://chat.mibbit.com/

    ReplyDelete