|
|
AIBO Motion File
Format
Contents of this website are freeware and/or copyrighted material, and may not be sold
under any circumstances.
Email: dogsbody@dogsbodynet.com
Home:
https://dogsbodynet.com
Table
of Contents
- Introduction
- Block 0 - File Header
- Block 1 - Header Strings
- Block 2 - Joint List
- Block 3 - Keyframes
- Example
1. Introduction
AIBO Motion files consist of a signature, followed by multiple sections
or
blocks. The
blocks describe which servos are to be used, and provide keyframes
giving positional
information for those servos.
The file signature is the string "OMTN". The blocks are
sequentially numbered, and provide a block length
(inclusive of the block header itself).
struct block_header_type { unsigned blocknum; unsigned blocklen; // Block lengths are normally 8 byte aligned. };
|
Blocks are zero padded to align them to 8 byte lengths typically (not
sure Aibo actually requires it though).
ERS-110 special cases:
Block 2 length is often not aligned.
Block 3 blocklen field is unsigned short (two bytes
instead of four).
2. MTN BLOCK 0
The first block immediately follows the 4-byte signature, and contains
the file version number, number of keyframes, and playback frame rate.
struct block0_type { unsigned block_num; // always 0x00000000 block number unsigned block_size; // always 0x00000018 block size unsigned num_sections; // always 0x00000004 num blocks unsigned short major_ver; // always 0x0001 major version unsigned short minor_ver; // minor version unsigned short tile_count; // keyframe count unsigned short frame_rate; // frame rate (msec/frame) unsigned options; // always 0? options };
|
|
3. MTN BLOCK 1
The next block contains the three variable sized header strings,
consisting of a single-byte length field, followed by the string
contents (ie: Pascal style). The three strings must be in
the
following order:
- Action "chunk" name.
- Author/Creator name
- Format (aibo-platform)
Chunk Name String
The first string, the chunk name, is parsed by AIBO and must be
specially formatted. ie:
a_sit#stand_description
The first character can be:
- a = all servos
- h = head servos only
- l = leg servos only
- m = mouth servo only
- e = ear servos only
- t = tail servos only
The '#' separated
words
tell AIBO the start & stop predefined postures. These
vary by
AIBO model, but at a minimum include "sleep", "sit" and "stand".
The description can be anything alphanumeric. Skitter just
sets this equal to the skit name.
Format
Platform String
The format varies by platform as follows:
- ERS-110:
"DRX-700"
- ERS-210:
"DRX-910"
- ERS-220:
"DRX-900"
- ERS-310:
"DRX-801"
- ERS-7:
"DRX-1000"
|
4. MTN BLOCK 2
The next block contains a servo count, followed by the servo PRM joint
names
(Pascal style strings again).
struct block2_type { unsigned block_num; unsigned block_size; unsigned short num_joints; };
|
The joint names vary by
AIBO model, and are listed below. The order the joints are
listed defines the order of entries in keyframes (defined in next
block).
ERS-110: HEAD_PITCH "PRM:/r0/c0-Joint:j0" HEAD_YAW "PRM:/r0/c0/c1-Joint:j1" HEAD_ROLL "PRM:/r0/c0/c1/c2-Joint:j2" MOUTH "PRM:/r0/c0/c1/c2/c3-Joint:j3" FR_LEG_VERT "PRM:/r2/c0-Joint:j0" FR_LEG_LAT "PRM:/r2/c0/c1-Joint:j1" FR_LEG_KNEE "PRM:/r2/c0/c1/c2-Joint:j2" FL_LEG_VERT "PRM:/r3/c0-Joint:j0" FL_LEG_LAT "PRM:/r3/c0/c1-Joint:j1" FL_LEG_KNEE "PRM:/r3/c0/c1/c2-Joint:j2" BR_LEG_VERT "PRM:/r4/c0-Joint:j0" BR_LEG_LAT "PRM:/r4/c0/c1-Joint:j1" BR_LEG_KNEE "PRM:/r4/c0/c1/c2-Joint:j2" BL_LEG_VERT "PRM:/r5/c0-Joint:j0" BL_LEG_LAT "PRM:/r5/c0/c1-Joint:j1" BL_LEG_KNEE "PRM:/r5/c0/c1/c2-Joint:j2" TAIL_VERT "PRM:/r1/c0-Joint:j0" TAIL_HORZ "PRM:/r1/c1-Joint:j1" ERS-210/220: HEAD_PITCH "PRM:/r1/c1-Joint2:j1" HEAD_YAW "PRM:/r1/c1/c2-Joint2:j2" HEAD_ROLL "PRM:/r1/c1/c2/c3-Joint2:j3" MOUTH "PRM:/r1/c1/c2/c3/c4-Joint2:j4" LEFT_EAR "PRM:/r1/c1/c2/c3/e1-Joint3:j5" RIGHT_EAR "PRM:/r1/c1/c2/c3/e2-Joint3:j6" FL_LEG_VERT "PRM:/r2/c1-Joint2:j1" FL_LEG_LAT "PRM:/r2/c1/c2-Joint2:j2" FL_LEG_KNEE "PRM:/r2/c1/c2/c3-Joint2:j3" BL_LEG_VERT "PRM:/r3/c1-Joint2:j1" BL_LEG_LAT "PRM:/r3/c1/c2-Joint2:j2" BL_LEG_KNEE "PRM:/r3/c1/c2/c3-Joint2:j3" FR_LEG_VERT "PRM:/r4/c1-Joint2:j1" FR_LEG_LAT "PRM:/r4/c1/c2-Joint2:j2" FR_LEG_KNEE "PRM:/r4/c1/c2/c3-Joint2:j3" BR_LEG_VERT "PRM:/r5/c1-Joint2:j1" BR_LEG_LAT "PRM:/r5/c1/c2-Joint2:j2" BR_LEG_KNEE "PRM:/r5/c1/c2/c3-Joint2:j3" TAIL_HORZ "PRM:/r6/c1-Joint2:j1" TAIL_VERT "PRM:/r6/c2-Joint2:j2" ERS-310: HEAD_PITCH "PRM:/r1/c1-Joint2:11" HEAD_PITCH2 "PRM:/r1/c1/c2-Joint2:12" HEAD_YAW "PRM:/r1/c1/c2/c3-Joint2:13" FL_LEG_VERT "PRM:/r2/c1-Joint2:21" FL_LEG_LAT "PRM:/r2/c1/c2-Joint2:22" FL_LEG_KNEE "PRM:/r2/c1/c2/c3-Joint2:23" BL_LEG_VERT "PRM:/r3/c1-Joint2:31" BL_LEG_LAT "PRM:/r3/c1/c2-Joint2:32" BL_LEG_KNEE "PRM:/r3/c1/c2/c3-Joint2:33" FR_LEG_VERT "PRM:/r4/c1-Joint2:41" FR_LEG_LAT "PRM:/r4/c1/c2-Joint2:42" FR_LEG_KNEE "PRM:/r4/c1/c2/c3-Joint2:43" BR_LEG_VERT "PRM:/r5/c1-Joint2:51" BR_LEG_LAT "PRM:/r5/c1/c2-Joint2:52" BR_LEG_KNEE "PRM:/r5/c1/c2/c3-Joint2:53" ERS-7: HEAD_PITCH "PRM:/r1/c1-Joint2:11" HEAD_YAW "PRM:/r1/c1/c2-Joint2:12" HEAD_PITCH2 "PRM:/r1/c1/c2/c3-Joint2:13" MOUTH "PRM:/r1/c1/c2/c3/c4-Joint2:14" LEFT_EAR "PRM:/r1/c1/c2/c3/e5-Joint4:15" RIGHT_EAR "PRM:/r1/c1/c2/c3/e6-Joint4:16" FL_LEG_VERT "PRM:/r2/c1-Joint2:21" FL_LEG_LAT "PRM:/r2/c1/c2-Joint2:22" FL_LEG_KNEE "PRM:/r2/c1/c2/c3-Joint2:23" BL_LEG_VERT "PRM:/r3/c1-Joint2:31" BL_LEG_LAT "PRM:/r3/c1/c2-Joint2:32" BL_LEG_KNEE "PRM:/r3/c1/c2/c3-Joint2:33" FR_LEG_VERT "PRM:/r4/c1-Joint2:41" FR_LEG_LAT "PRM:/r4/c1/c2-Joint2:42" FR_LEG_KNEE "PRM:/r4/c1/c2/c3-Joint2:43" BR_LEG_VERT "PRM:/r5/c1-Joint2:51" BR_LEG_LAT "PRM:/r5/c1/c2-Joint2:52" BR_LEG_KNEE "PRM:/r5/c1/c2/c3-Joint2:53" TAIL_VERT "PRM:/r6/c1-Joint2:61" TAIL_HORZ "PRM:/r6/c2-Joint2:62"
|
|
5. MTN BLOCK 3
The last block contains the keyframes. The keyframe
count was given back in block 0. Each keyframe consists of
a time delta, three words of zeros, then the various servo
positions in micro-radian (uradian) coordinates.
struct keyframe_header_type { unsigned time_delta; unsigned dummy[3]; };
|
To convert between uradians and degrees, use the following:
angle_degrees = angle_uradians * 180.0 /
(1000000.0*3.141592654)
angle_uradians = angle_degrees *
(1000000.0*3.141592654) / 180.0
To compute elapsed time between keyframes, use:
time_msecs = (keyframe_time_delta+1) * frame_rate
|
6. Example
000000: 4f 4d 54 4e 00 00 00 00 18 00 00 00 04 00 00 00 |OMTN............| Block 0 000010: 01 00 02 00 02 00 10 00 00 00 00 00 01 00 00 00 |................| File Header 000020: 34 00 00 00 18 61 5f 73 6c 65 65 70 23 73 69 74 |4....a_sleep#sit| 000030: 5f 53 6c 65 65 70 5f 54 6f 5f 53 69 74 07 53 6b |_Sleep_To_Sit.Sk| Block 1 000040: 69 74 74 65 72 07 44 52 58 2d 39 31 30 00 00 00 |itter.DRX-910...| Header Strings 000050: 02 00 00 00 f8 01 00 00 14 00 14 50 52 4d 3a 2f |...........PRM:/| 000060: 72 31 2f 63 31 2d 4a 6f 69 6e 74 32 3a 6a 31 17 |r1/c1-Joint2:j1.| Block 2 000070: 50 52 4d 3a 2f 72 31 2f 63 31 2f 63 32 2d 4a 6f |PRM:/r1/c1/c2-Jo| Joint List 000080: 69 6e 74 32 3a 6a 32 1a 50 52 4d 3a 2f 72 31 2f |int2:j2.PRM:/r1/| 000090: 63 31 2f 63 32 2f 63 33 2d 4a 6f 69 6e 74 32 3a |c1/c2/c3-Joint2:| 0000a0: 6a 33 1d 50 52 4d 3a 2f 72 31 2f 63 31 2f 63 32 |j3.PRM:/r1/c1/c2| 0000b0: 2f 63 33 2f 63 34 2d 4a 6f 69 6e 74 32 3a 6a 34 |/c3/c4-Joint2:j4| 0000c0: 1d 50 52 4d 3a 2f 72 31 2f 63 31 2f 63 32 2f 63 |.PRM:/r1/c1/c2/c| 0000d0: 33 2f 65 31 2d 4a 6f 69 6e 74 33 3a 6a 35 1d 50 |3/e1-Joint3:j5.P| 0000e0: 52 4d 3a 2f 72 31 2f 63 31 2f 63 32 2f 63 33 2f |RM:/r1/c1/c2/c3/| 0000f0: 65 32 2d 4a 6f 69 6e 74 33 3a 6a 36 14 50 52 4d |e2-Joint3:j6.PRM| 000100: 3a 2f 72 32 2f 63 31 2d 4a 6f 69 6e 74 32 3a 6a |:/r2/c1-Joint2:j| 000110: 31 17 50 52 4d 3a 2f 72 32 2f 63 31 2f 63 32 2d |1.PRM:/r2/c1/c2-| 000120: 4a 6f 69 6e 74 32 3a 6a 32 1a 50 52 4d 3a 2f 72 |Joint2:j2.PRM:/r| 000130: 32 2f 63 31 2f 63 32 2f 63 33 2d 4a 6f 69 6e 74 |2/c1/c2/c3-Joint| 000140: 32 3a 6a 33 14 50 52 4d 3a 2f 72 33 2f 63 31 2d |2:j3.PRM:/r3/c1-| 000150: 4a 6f 69 6e 74 32 3a 6a 31 17 50 52 4d 3a 2f 72 |Joint2:j1.PRM:/r| 000160: 33 2f 63 31 2f 63 32 2d 4a 6f 69 6e 74 32 3a 6a |3/c1/c2-Joint2:j| 000170: 32 1a 50 52 4d 3a 2f 72 33 2f 63 31 2f 63 32 2f |2.PRM:/r3/c1/c2/| 000180: 63 33 2d 4a 6f 69 6e 74 32 3a 6a 33 14 50 52 4d |c3-Joint2:j3.PRM| 000190: 3a 2f 72 34 2f 63 31 2d 4a 6f 69 6e 74 32 3a 6a |:/r4/c1-Joint2:j| 0001a0: 31 17 50 52 4d 3a 2f 72 34 2f 63 31 2f 63 32 2d |1.PRM:/r4/c1/c2-| 0001b0: 4a 6f 69 6e 74 32 3a 6a 32 1a 50 52 4d 3a 2f 72 |Joint2:j2.PRM:/r| 0001c0: 34 2f 63 31 2f 63 32 2f 63 33 2d 4a 6f 69 6e 74 |4/c1/c2/c3-Joint| 0001d0: 32 3a 6a 33 14 50 52 4d 3a 2f 72 35 2f 63 31 2d |2:j3.PRM:/r5/c1-| 0001e0: 4a 6f 69 6e 74 32 3a 6a 31 17 50 52 4d 3a 2f 72 |Joint2:j1.PRM:/r| 0001f0: 35 2f 63 31 2f 63 32 2d 4a 6f 69 6e 74 32 3a 6a |5/c1/c2-Joint2:j| 000200: 32 1a 50 52 4d 3a 2f 72 35 2f 63 31 2f 63 32 2f |2.PRM:/r5/c1/c2/| 000210: 63 33 2d 4a 6f 69 6e 74 32 3a 6a 33 14 50 52 4d |c3-Joint2:j3.PRM| 000220: 3a 2f 72 36 2f 63 31 2d 4a 6f 69 6e 74 32 3a 6a |:/r6/c1-Joint2:j| 000230: 31 14 50 52 4d 3a 2f 72 36 2f 63 32 2d 4a 6f 69 |1.PRM:/r6/c2-Joi| 000240: 6e 74 32 3a 6a 32 00 00 03 00 00 00 c8 00 00 00 |nt2:j2..........| Block 3 000250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| Keyframes 000260: 3c 56 fd ff 00 00 00 00 00 00 00 00 79 33 ff ff |<V..........y3..| 000270: 00 00 00 00 00 00 00 00 9d fa 0f 00 00 00 00 00 |................| 000280: 4e fd 07 00 a8 5f e1 ff 00 00 00 00 a7 9d 26 00 |N...._........&.| 000290: 9d fa 0f 00 00 00 00 00 4e fd 07 00 a8 5f e1 ff |........N...._..| 0002a0: 00 00 00 00 a7 9d 26 00 00 00 00 00 00 00 00 00 |......&.........| 0002b0: 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |'...............| 0002c0: 94 57 f9 ff 00 00 00 00 00 00 00 00 79 33 ff ff |.W..........y3..| 0002d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 0002e0: c4 a9 02 00 14 08 e8 ff 00 00 00 00 e2 f3 23 00 |..............#.| 0002f0: 00 00 00 00 00 00 00 00 c4 a9 02 00 14 08 e8 ff |................| 000300: 00 00 00 00 e2 f3 23 00 00 00 00 00 00 00 00 00 |......#.........|
Download Example
|
|