wiki:MURML

MURML

AsapRealizer's MURML extension encompasses the detailed description of facial animation and gesture. It does not encompas MURML's synchronization mechanisms and speech description, since these can be specified in BML and its core description levels. The namespace for MURML is  http://www.techfak.uni-bielefeld.de/ags/soa/murml.

Design changes (compared to MURML as used in ACE)

  • Speech, gaze and pointing are no longer supported; use their BML equivalent behaviors (<speech>, <gaze>, <pointing>) instead. (TODO: figure out an elegant way to align the timing of such behavior to timing inside MURML when needed)
  • Facial animation and gesture can no longer be mixed inside a single murml-description
  • Absolulte coordinates are now specified in an OpenGL/Ogre compatible coordinate system (+y is up, +x is to the right, +z is going outside the screen).

MURML hand gesture

A hand gesture can be specified using the <murmlgesture> behavior.

<bml xmlns="http://www.bml-initiative.org/bml/bml-1.0"  id="bml1" > 
<murmlgesture id="gesture1" xmlns="http://www.techfak.uni-bielefeld.de/ags/soa/murml"> 
  <murml-description>    
    <parallel>
      <dynamic slot="HandLocation" scope="left_arm">
	<dynamicElement type="linear" scope="left_arm">
          <value type="start" name="LocLowerChest LocCCenter LocNorm"/>
          <value type="end" name="LocStomach LocPeripheryLeft LocFFar"/>
	</dynamicElement>
      </dynamic>
      <dynamic slot="HandShape" scope="left_arm">
        <dynamicElement>
	  <value type="start" name="ASLa"/>            
	  <value type="end" name="ASL5"/>            
	</dynamicElement>
      </dynamic>
      <dynamic slot="ExtFingerOrientation" scope="left_arm">
	<dynamicElement>
            <value type="start" name="DirRA"/>
            <value type="end" name="DirALAA"/>
	</dynamicElement>
      </dynamic>
      <dynamic slot="PalmOrientation" scope="left_arm">
	<dynamicElement>
            <value type="start" name="PalmRU"/>
            <value type="end" name="PalmU"/>
	</dynamicElement>
      </dynamic>
    </parallel> 
  </murml-description>
</murmlgesture> 
</bml>

or, preferably, using the MURML description extension:

<gesture id="g1" mode="LEFT_HAND" lexeme="BEAT"> 
  <description priority="1" type="murmlgesture"> 
    <murmlgesture xmlns="http://www.techfak.uni-bielefeld.de/ags/soa/murml" id="g1">
    <murml-description> 
    ...
    </murml-description> 
    </murmlgesture>
  </description> 
</gesture> 

MURML face gesture

MURML face gestures can similarly be described by the <murmlface> element (examples below assume the use of the Armandia avatar)

<bml xmlns="http://www.bml-initiative.org/bml/bml-1.0"  id="bml1" > 
<murmlface xmlns="http://www.techfak.uni-bielefeld.de/ags/soa/murml" id="face1"> 
<murml-description>
<dynamic> 
	<keyframing easescale="5" easeturningpoint="0.7"> 
		<phase> 
		<frame ftime="0.5"> 
		<posture>Humanoid (Body_NG-mesh-morpher-yeux_NG01-1 1 100)</posture> 
		</frame> 
		<frame ftime="1"> 
		<posture>Humanoid (Body_NG-mesh-morpher-yeux_NG01-1 1 0)</posture> 
		</frame> 
		<frame ftime="1.5"> 
		<posture>Humanoid (Body_NG-mesh-morpher-yeux_NG01-1 1 100)</posture> 
		</frame> 
		<frame ftime="2"> 
		<posture>Humanoid (Body_NG-mesh-morpher-yeux_NG01-1 1 0)</posture> 
		</frame> 
		</phase> 
	</keyframing> 
</dynamic> 
</murml-description>
</murmlface> 
</bml> 

Or preferably as an extension of e.g. <faceLexeme>:

<bml xmlns="http://www.bml-initiative.org/bml/bml-1.0"  id="bml1" > 
<faceLexeme id="face1" lexeme="eyeblink"> 
	<description priority="1" type="murmlface"> 
        <murmlface xmlns="http://www.techfak.uni-bielefeld.de/ags/soa/murml" id="face1">
	<murml-description xmlns="http://www.techfak.uni-bielefeld.de/ags/soa/murml">	 
	<dynamic> 
	<keyframing easescale="5" easeturningpoint="0.7"> 
		<phase> 
		<frame ftime="0.5"> 
		<posture>Humanoid (Body_NG-mesh-morpher-yeux_NG01-1 1 100)</posture> 
		</frame> 
		<frame ftime="1"> 
		<posture>Humanoid (Body_NG-mesh-morpher-yeux_NG01-1 1 0)</posture> 
		</frame> 
		<frame ftime="1.5"> 
		<posture>Humanoid (Body_NG-mesh-morpher-yeux_NG01-1 1 100)</posture> 
		</frame> 
		<frame ftime="2"> 
		<posture>Humanoid (Body_NG-mesh-morpher-yeux_NG01-1 1 0)</posture> 
		</frame> 
		</phase> 
	</keyframing> 
	</dynamic> 	 
	</murml-description> 
        </murmlface>
	</description> 
</faceLexeme>
</bml> 

From MURML to BML, an example

The example below shows how a MURML description can be translated to BML: MURML

<definition>
  <utterance>
    <specification>
    And now take <time id=“t1”/> this <time id=”t2”/> bar <time id=“t3”' chunkborder=“true”/>
    and make it <time id=“t4”/> this big. <time id=“t5”/>
    </specification>
    <focus onset=”t1” end=”t2” accent=”H*”/>
    <behaviorspec id=”gesture_1”>
      <gesture id=”pointing_to”>
        <affiliate onset=”t1” end=”t3”/>
        <param name=”refloc” value=”$Loc-Bar_1”/>
      </gesture>
    </behaviorspec>
    <behaviorspec id=”gesture_2”>
      <gesture>
        <affiliate onset=”t4” end=“t5”/>
        <constraints>
          <symmetrical dominant=”right_arm” symmetry=”SymMS”>
          <parallel>
            <static slot="HandShape" value="BSflat (FBround all o) (ThCpart o)"/>
            <static slot="PalmOrientation" value="DirL"/>
            <static slot="ExtFingerOrientation" value="DirA"/>
            <dynamic slot="HandLocation">
              <dynamicElement type="linear">
                <value type="start" name="LocShoulder LocCenterRight LocNorm"/>
                <value type="direction" name="DirR''/>
                <value type="distance" name="125.0''/>
              </dynamicElement>
            </dynamic>
          </parallel>
          </symmetrical>
        </constraints>
      </gesture>
    </behaviorspec>
  </utterance>
</definition>

BML


<bml id="bml1" xmlns="http://www.bml-initiative.org/bml/bml-1.0">
  <speech id="speech1">
    <text>
	And now take <sync id="t1"/> this <sync id="t2"/> bar
    </text>
    <description priority="1" type="maryxml">
      <maryxml xmlns="http://mary.dfki.de/2002/MaryXML">
        And now take <mark name="t1"/> <t accent="H*">this</t> <mark name="t2"/> bar
      </maryxml>    
    </description>
  </speech> 
 <pointing id="pointing_to" target="Loc-Bar_1" strokeStart="speech1:t1" strokeEnd="speech1:t3"/>   
</bml>
<bml id="bml2" xmlns="http://www.bml-initiative.org/bml/bml-1.0" xmlns:bmla="http://www.asap-project.org/bmla" bmla:chunkAfter="bml1">
  <speech id="speech1">
    <text>
    	and make it <sync id="t4"/> this big. <sync id="t5"/>
    </text>
  </speech>  
  <gesture id="gesture_2" strokeStart="speech1:t4" strokeEnd="speech1:t5" lexeme="SIZE" mode="BOTH_HANDS">
    <description priority="1" type="murmlgesture">
       <murmlgesture xmlns="http://www.techfak.uni-bielefeld.de/ags/soa/murml" id="gesture_2"> 
       <murml-description> 
       <symmetrical dominant="right_arm" symmetry="SymMS">
         <parallel>
          <static slot="HandShape" value="ASLa"/>
          <static slot="PalmOrientation" value="DirL"/>
          <static slot="ExtFingerOrientation" value="DirA"/>
          <dynamic slot="HandLocation">
            <dynamicElement type="linear">
              <value type="start" name="LocShoulder LocCenterRight LocNorm"/>
              <value type="direction" name="DirR"/>
              <value type="distance" name="125.0"/>
            </dynamicElement>
          </dynamic>
         </parallel>
       </symmetrical>
       </murml-description>
       </murmlgesture>
    </description>
  </gesture>
</bml>

The MURML example contains two chunks, one with the intonation phrase "And now take this bar" + gesture gesture_1 and one with the intonation phrase "and make it this big." + gesture gesture_2. In BML, these chunks can be modeled in two BML blocks that are composed using the CHUNK_AFTER composition. Since core-bml does not contain any specification mechanisms for the MURML focus, we model the focus in speech using the  Mary XML core description extension. The MURML pointing gesture (with id gesture_1) can directly be translated into a BML pointing gesture. gesture_2 is modeled in core BML as a lexicalized gesture. Its finer grained MURML specification is provided within a description extension.

MURML descriptions in detail

<murml-description>

The toplevel element of a murml description is always <murml-description>. It acts on the same level as <constraints> in  pre-BML MURML.

AttributeTypeUseDescription
idStringoptionalmurml-description id (currently not used)
pointStrokeboolean (true, false)optional, defaults to falsetrue if the gesture has its stroke at a specific point (rather than a stroke phase)
scopeStringoptionalthe scope of the gesture

Child elements: (<keyframing> | <dynamic> | <static> | <symmetrical> | <parallel> | <sequence>)

TODO: implement <keyframing>. Keyframing is already supported when wrapped in dynamic. TODO: implement <sequence>

<keyframing>

AttributeTypeUseDescription
scope body | face optional
mode linear | spline | quaternion | raw optional
name string for animation name optional, defaults to KF_Anim_
easescale float from 1.0 to 50.0, reasonable values around 7.0 optional, default 1
easeturningpoint float from 0.0 to 1.0 optional, default 0.5
postpone_startframe double optional, default 0
dont_insert_startframe boolean optional, default false
notifyboolean ?
applymode SUPERPOSE|EXCLUSIVEoptional, default EXCLUSIVE
priority integer from -500 to +500 optional, default value 0
startTime float optional
endTime float optional

Child elements: <phase>+

TODO: check use of notify

TODO: implement SUPERPOSE applymode

<phase>

Used to group a bunch of keyframes into ONE continuous motion. Note: Each phase is timed locally, ie. its timing starts over from 0!

Child elements: (frame+)

<frame>

Encapsulates the description of a frame in a keyframe animation.

AttributeTypeUseDescription
ftimefloatrequiredfloat in secs

Child elements: (posture)

<posture>

Used to encapsulate a string that describes a configuration/posture either for the skeleton in terms of joint angles (the normal case), or for other body parts like the face (e.g. in terms of muscle values).

Child elements: #PCDATA

<dynamic>

AttributeTypeUseDescription
scopeString: typically neck, right_arm, left_armoptionalthe scope of the dynamic block
slotSlot: HandShape | HandLocation | PalmOrientation | ExtFingerOrientation | GazeDirection | Neckoptional

Child elements: ((dynamicElement+)|<keyframing>)

<static>

Specifies a single feature of a gesture that is to be held for a certain period of time.

AttributeTypeUseDescription
valueStringrequired
slotSlot: HandShape | HandLocation | PalmOrientation | ExtFingerOrientation | GazeDirection | Neckoptional
scopeString: typically neck, right_arm, left_armoptional
mode | pointTo optional, defaults to empty

TODO implement mode(?)

<symmetrical>

Enables a convenient way to specify a symmetrical gesture, namely, to define only one (the 'dominant') hand along with the specific symmetry constraints.

AttributeTypeUseDescription
dominant right_arm | left_arm required
symmetry SymM + any combination of up to three characters out of F|T|S (e.g: SymMS, SymMTF, SymMSFT) required see below
center 3 floats for rotation (rpy), followed by 3 floats for translation (xyz) optional

Symmetry constraints:

  • Sym: Mirrorsymmetry
  • SymMS: Mirrorsymmetry, sagittal plane (=l/r).
  • SymMT: Mirrorsymmetry, transverse plane (=up/down)
  • SymMF: Mirrorsymmetry, frontal plane (=forward/backward)

Child elements: (<parallel>|<sequence>|<static>|<dynamic>)

<parallel>

Can comprise any combination of constraints, among which it imposes simultaneity.

Child elements: ((<sequence>|<dynamic>|<static>|<symmetrical>)*)

<sequence>

Child elements: ((<symmetrical>|<dynamic>|<static>|<parallel>)*)

<dynamicElement>

AttributeTypeUseDescription
scopeString optional
typelinear | curve | chop optional

Child elements: (<value>+)

<value>

AttributeTypeUseDescription
typeString required
nameString required

Handshape Definition

handshape: basicHandShape|specificHandshape modification*
modification: (thumbShape)|(fingerSymbol)|(ThCpart [openingParameter])
fingerSymbol: fingerShape fingerParameter [openingParameter]

The default openingParameter is c (=1).

Only basicHandShape is currently supported.

Some examples

BSfist (!ThExt)

Means use the BSFist handshape and overwrite the thumb with the ThExt handshape.

BSffinger (ThExt) (FBroll r) (FBroll l wo)

Means use the BSFist handshape, overwrite thumb with ThExt, and apply FBRoll on the ring finger and for 20% on the pinky.

Defining handshapes

The list of possible handShapes etc is provided in a hns xml file. For example:

<hns>
  <symbols>
    <symbol class="handShapes" name="BSfist" value=""/> 
    <symbol class="handShapes" name="BSflatc" value=""/>  
    ...
    <symbol class="basicHandShapes" name="BSfist" value=""/>
    <symbol class="basicHandShapes" name="BSflat" value=""/> 
    ...
    <symbol class="specificHandShapes" name="BSifinger"  value=""/> 
    <symbol class="specificHandShapes" name="BSimcfinger" value=""/>
    ...
    <symbol class="thumbShapes" name="ThExt" value=""/>
    <symbol class="thumbShapes" name="ThAcr" value=""/>
    ...  
    <symbol class="fingerShapes" name="FBstr" value=""/> 
    <symbol class="fingerShapes" name="FBangle" value=""/>
    ...
    <symbol class="fingerParameter" name="all" value=""/> 
    <symbol class="fingerParameter" name="l" value=""/> <!-- little finger (pinky) -->
    <symbol class="fingerParameter" name="r" value=""/> <!-- ring finger-->
    <symbol class="fingerParameter" name="m" value=""/> <!-- middle finger-->
    <symbol class="fingerParameter" name="p" value=""/> <!-- pointing (index) finger -->
    ...
    <symbol class="openingParameter" name="c" value=""/>   <!-- 1 -->
    <symbol class="openingParameter" name="no" value=""/>  <!-- 0.8 -->
    <symbol class="openingParameter" name="o" value=""/>   <!-- 0.5 -->
    <symbol class="openingParameter" name="wo" value=""/>  <!-- 0.2 -->
  </symbols> 
</hns>

Adding new handshapes

Define the handshape in a SkeletonPose xml file for the right hand, for example by exporting it using the MURMLKeyframeEditor.

Example handshape:

<SkeletonPose id="ASLcsmall" encoding="R" parts="r_index1 r_index2 r_index3 r_middle1 r_middle2 r_middle3 r_pinky1 r_pinky2 r_pinky3 r_ring1 r_ring2 r_ring3 r_thumb1 r_thumb2 r_thumb3">
   0.9981348 0.0 0.0 0.06104854 0.81915206 0.0 0.0 0.57357645 0.9182161 0.0 0.0 0.39607978 0.9981348 0.0 0.0 0.06104854 0.81915206 0.0 0.0 0.57357645 0.9182161 0.0 0.0 0.39607978 0.9981348 0.0 0.0 0.06104854 0.81915206 0.0 0.0 0.57357645 0.9182161 0.0 0.0 0.39607978 0.9981348 0.0 0.0 0.06104854 0.81915206 0.0 0.0 0.57357645 0.9182161 0.0 0.0 0.39607978 0.75553864 0.12643379 0.63397217 -0.106090546 1.0 0.0 0.0 0.0 0.9781476 0.2079117 0.0 0.0
</SkeletonPose>

To export handshapes using the MURMLKeyframeEditor, model them on the right hand and use the "export right hand pose"-button. An id should be added to the SkeletonPose element in the resulting XML pose.

Directories used to look for handshapes are specified using <HnsHandShape> in the VirtualHumanSpec? for the animation engine. E.g.:

<Loader id="animationengine"
          loader="asap.animationengine.loader.MixedAnimationEngineLoader"
          requiredloaders="mixedskeletonembodiment,physicalembodiment">
    <GestureBinding basedir="" resources="Humanoids/billie/gesturebinding/" filename="gesturebinding.xml"/>
    <StartPose resources="Humanoids/billie/restposes/" filename="looselyhangingarms.xml"/>
    <Hns resources="Humanoids/billie/hns" filename="hns_billie.xml"/>
    <HnsHandShape dir="Humanoids/billie/handshapes"/>
    <HnsHandShape dir="customhandshapes"/>
</Loader>

If you place your custom handshapes in a directory specified by HnsHandShape, it will automatically be registered for use. Dir is relative to the classpath. So, in the example above, you can place your custom handshapes in the resource/customhandshape dir of your program.

HandLocation Definition

Specifying location

Hand location is specified using a triple which is either an x y z vector defining the hand location in Cartasian coordinates, or 3 symbolic values (e.g. "LocShoulder LocCenterRight LocNorm"). The symbolic values define the z (in meter), phi (in degrees) and radial distance (rho, in meter) of the hand in a  cylindric coordinate system respectively. The coordinate system is relative to the basejoint specified in the hns xml above the hips (e.g. vl5).

http://upload.wikimedia.org/wikipedia/commons/0/0e/Coord_system_CY_1.svg

The symbolic values are define in the hns xml file. For example:

<hns>
  ...
  <basejoint sid="vl5"/>
  ...
  <symbols>
    <symbol class="handReferences" name="LocAboveHead" value="60"/>
    <symbol class="handReferences" name="LocHead" value="54"/>
    <symbol class="handReferences" name="LocForeHead" value="52"/>
    <symbol class="handReferences" name="LocEyes" value="50"/>
    <symbol class="handReferences" name="LocNose" value="48"/> 
    ...
    <symbol class="handLocators" name="LocCCenter" value="0"/>
    <symbol class="handLocators" name="LocCCenterLeft" value="15"/>
    <symbol class="handLocators" name="LocCenterLeft" value="25"/>
    <symbol class="handLocators" name="LocCenterRight" value="-25"/>
    ...
    <symbol class="handDistances" name="LocContact" value="10"/>
    <symbol class="handDistances" name="LocNear" value="15"/>
    <symbol class="handDistances" name="LocNorm" value="20"/>
    ...
  </symbols> 
</hns>

Specifying static HandLocation

Examples:

<static slot="HandLocation" value="LocShoulder LocCenterRight LocNorm" scope="left_arm"/>
<static slot="HandLocation" value="0.2 1 0.5"/>

Scope (optional) indicates which hand is used. Value is the location triple.

Specifying dynamic HandLocation

A dynamic HandLocation is specified within a dynamic block, using one or more dynamicElements. Each element defines a guiding stroke from the previous point to a new end position. The first dynamicElement also defines a start position for the guiding stroke. Depending on the type of guiding stroke, it might be required to specify other <value>s.

Specifying a linear guiding stroke

Example:

<dynamic slot="HandLocation" scope="left_arm">
  <dynamicElement type="linear" scope="left_arm">
    <value type="start" name="0.2 1.8 0.2"/>
    <value type="end" name="0.5 1.8 0.2"/>
  </dynamicElement>
  <dynamicElement type="linear" scope="left_arm">
    <value type="end" name="0.2 1.5 0.2"/>
  </dynamicElement>
</dynamic>

Specifying a curved guiding stroke

Example:

<dynamic slot="HandLocation" scope="left_arm">
  <dynamicElement type="curve">
    <value type="start"  name="LocShoulder LocCenterLeft LocFar"/>
    <value type="end"    name="LocShoulder LocCenterLeft LocNorm"/>
    <value type="normal" name="DirU"/>
    <value type="shape"  name="LeftC"/>
    <value type="extension" name="0.6"/>
  </dynamicElement>
  <dynamicElement type="curve">
    <value type="end"    name="LocShoulder LocCenterLeft LocFar"/>
    <value type="normal" name="DirU"/>
    <value type="shape"  name="LeftC"/>
    <value type="extension" name="0.6"/>
  </dynamicElement>
  <dynamicElement type="curve">
    <value type="end"    name="LocShoulder LocCenterLeft LocNorm"/>
    <value type="normal" name="DirU"/>
    <value type="shape"  name="LeftC"/>
    <value type="extension" name="0.6"/>
  </dynamicElement>
  <dynamicElement type="curve">
    <value type="end"    name="LocShoulder LocCenterLeft LocFar"/>
    <value type="normal" name="DirU"/>
    <value type="shape"  name="LeftC"/>
    <value type="extension" name="0.6"/>
  </dynamicElement>
</dynamic> 
ValueTypeUseDescription
normalDirectionrequiredTODO
shapeShapeSymbol (RightS, RightC, LeftC, LeftS)optional, defaults to RightSTODO
extensionfloatoptionalTODO
extentfloatoptional, defaults to 0.2TODO
roundnessfloatoptional, defaults to 0TODO
skewednessfloatoptional, defaults to 0TODO

TODO: is extension and extend the same?? Doublecheck original murml code+examples.

PalmOrientation Constraint

A Hand palm orientation constraint is defined either as an absolute direction of the palm in the world or as a local rotation of the wrist.

Absolute Constraint

Absolute constraints are defined using an x y z vector, or using 'Dir', followed by one or more of 'U' (up), 'D' (down), 'R' (right), 'L' (left), 'A' (forward), 'T' (backward).

Examples of absolute palm rotation constraints:

<murml-description xmlns="http://www.techfak.uni-bielefeld.de/ags/soa/murml">
  <static slot="PalmOrientation" scope="left_arm" value="DirU"/> 
</murml-description>

<murml-description xmlns="http://www.techfak.uni-bielefeld.de/ags/soa/murml">
  <dynamicElement>
    <value type="start" name="DirLU"/>
    <value type="end" name="DirU"/>
  </dynamicElement> 
</murml-description>

<murml-description xmlns="http://www.techfak.uni-bielefeld.de/ags/soa/murml">
  <static slot="PalmOrientation" scope="left_arm" value="1 0 1"/> 
</murml-description>

Relative Constraint

Relative constraints are specified either as a single number denoting the local rotation of the left wrist (right wrist rotations are automatically mirrored) around the forward axis in degrees or as a symbolic string. The symbolic string maps to a rotation in degrees via the hns xml; by convention these rotations are of the form 'Palm' followed by one or more of 'U', 'D', 'R', 'L', 'A', 'T'.

Definition of some relative palm orientations in the hns xml.

<hns>
<symbols>
  ...
  <symbol class="palmOrientations" name="PalmL" value="180.0"/>
  <symbol class="palmOrientations" name="PalmLU" value="-135.0"/>
  <symbol class="palmOrientations" name="PalmLD" value="135"/>
  <symbol class="palmOrientations" name="PalmR" value="0.0"/>
  <symbol class="palmOrientations" name="PalmRU" value="-45.0"/>
  <symbol class="palmOrientations" name="PalmRD" value="45.0"/>
  <symbol class="palmOrientations" name="PalmU" value="-90.0"/>
  <symbol class="palmOrientations" name="PalmD" value="90"/>
</symbols>
</hns>

Examples of relative palm rotation constraints:

<murml-description xmlns="http://www.techfak.uni-bielefeld.de/ags/soa/murml">
  <static slot="PalmOrientation" scope="left_arm" value="PalmU"/> 
</murml-description>

<murml-description xmlns="http://www.techfak.uni-bielefeld.de/ags/soa/murml">
  <dynamicElement slot="PalmOrientation" scope="right_arm">
    <value type="start" name="PalmU"/>
    <value type="end" name="PalmD"/>
  </dynamicElement> 
</murml-description>

<murml-description xmlns="http://www.techfak.uni-bielefeld.de/ags/soa/murml">
  <static slot="PalmOrientation" scope="left_arm" value="50"/> 
</murml-description>

ExtFingerOrientation Constraint

The ExtFingerOrientation constraint defines the absolute direction of the fingers in the same way as the absolute PalmOrientation constraint.

Examples of absolute ExtFingerOrientation constraints:

<murml-description xmlns="http://www.techfak.uni-bielefeld.de/ags/soa/murml">
  <static slot="ExtFingerOrientation " scope="left_arm" value="DirTUULL"/> 
</murml-description>

<murml-description xmlns="http://www.techfak.uni-bielefeld.de/ags/soa/murml">
  <dynamicElement slot="ExtFingerOrientation" scope="right_arm">
    <value type="start" name="DirLU"/>
    <value type="end" name="DirU"/>
  </dynamicElement> 
</murml-description>

<murml-description xmlns="http://www.techfak.uni-bielefeld.de/ags/soa/murml">
  <static slot="ExtFingerOrientation" scope="left_arm" value="1 0 1"/> 
</murml-description>

Symmetry

The symmetry constraint enables a convenient way to specify a symmetrical gesture, namely, to define only one (the 'dominant') hand along with the specific symmetry constraints.

<symmetrical dominant="right_arm | left_arm" symmetry=sym center=roll pitch yaw x y z>

Center contains 3 floats for rotation, followed by 3 floats for translation. sym is SymM + any combination of up to three characters out of F|T|S (e.g: SymMS, SymMTF, SymMSFT)

Using symmetry always results in mirror symmetry.

Sym: Mirror symmetry
SymMS: Mirror symmetry, sag (=l/r).
SymMT: Mirror symmetry, trans (=up/down)
SymMF: Mirror symmetry, front (=forward/backward)

HFO is Hand palm orientation, FAR: extendend finger orientation

SymmetryHandLocHFO & FAR
SymMS r-l r-l
SymMT up-down r-l & up-down
SymMF forward-backward r-l & forward-backward
SymMST r-l & up-down r-l & up-down
SymMSF r-l & forward-backward r-l & forward-backward
SymMTF up-down & forward-backward r-l & up-down & forward-backward
SymMSTF r-l & up-down & forward-backward r-l & up-down & forward-backward

Example:

<murml-description scope="hand" pointStroke="true">
   <symmetrical dominant="right_arm" symmetry="SymMS">
      <parallel>
        <dynamic slot="HandLocation">
           <dynamicElement type="linear">
               <value type="start" name="LocUpperStomach LocCenterRRight LocNorm"/>
               <value type="direction" name="DirDRD"/>
	       <value type="distance" name="20.0"/>
	     </dynamicElement>
        </dynamic>
        <static slot="PalmOrientation" value="PalmU"/>
      </parallel>
    </symmetrical>
</murml-description>  

Keyframe Animation

Keyframe animations are packed within dynamic elements. The top level element is <keyframing>. The attributes mode, easescale, easeturningpoint and dont_insert_startframe are currently implemented. Keyframes may contain multiple phases [currently not implemented!]. Each phase is locally time, that is, starts at time 0. A phase has multiple animation <frame>s. If dont_insert_startframe is false (default), then an automatic transition from the current pose to the start of the keyframe is generated, in such a way that the first keyframe is attained at its specified ftime. Each frame contains a posture, which is written as

posture -> Humanoid posturespec*
postureSpec -> (jointid nrofdofvalues dofvalues)

For joint rotations this boils down to

(jointid 3 rolldegrees pitchdegrees yawdegrees)

And for morph targets to

(morphid 1 morphpercentage)

where morphpercentage may also be negative.

Example:

<murml-description xmlns="http://www.techfak.uni-bielefeld.de/ags/soa/murml">
  <dynamic>
    <keyframing>
        <phase>
        <frame ftime="1">
          <posture>Humanoid (r_shoulder 3 -33 -25 -25) (r_elbow 3 0 -91 0) (r_sternoclavicular 3 0 -17 -15) </posture>
        </frame>
        <frame ftime="1.4">
          <posture>Humanoid (r_shoulder 3 -33 -25 -25) (r_elbow 3 0 -110 0) (r_sternoclavicular 3 0 -17 -15) </posture>
        </frame>
        <frame ftime="1.8">
          <posture>Humanoid (r_shoulder 3 -33 -25 -25) (r_elbow 3 0 -91 0) (r_sternoclavicular 3 0 -17 -15) </posture>
        </frame>
        <frame ftime="2.2">
          <posture>Humanoid (r_shoulder 3 -33 -25 -25) (r_elbow 3 0 -110 0) (r_sternoclavicular 3 0 -17 -15) </posture>
        </frame>
        <frame ftime="2.6">
          <posture>Humanoid (r_shoulder 3 -33 -25 -25) (r_elbow 3 0 -91 0) (r_sternoclavicular 3 0 -17 -15) </posture>
        </frame>
        <frame ftime="2.8">
          <posture>Humanoid (r_shoulder 3 -33 -25 -25) (r_elbow 3 0 -91 0) (r_sternoclavicular 3 0 -17 -15) </posture>
        </frame>
        </phase>
    </keyframing>
  </dynamic>
</murml-description>