<?xml version="1.0" ?>
<!--

   XML Schema for URDF v1.0

   This is a proposal XML Schema to validate the original URDF file
   format. It supports PR2 extensions (transmission) but not the
   Gazebo ones.

  -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
	   targetNamespace="http://www.ros.org"
	   xmlns="http://www.ros.org"
	   elementFormDefault="qualified">

  <!-- pose node type -->
  <xs:complexType name="pose">
    <xs:attribute name="xyz" type="xs:string" default="0 0 0" />
    <xs:attribute name="rpy" type="xs:string" default="0 0 0" />
  </xs:complexType>

  <!-- pose node type -->
  <xs:complexType name="color">
    <xs:attribute name="rgba" type="xs:string" default="0 0 0 0" />
  </xs:complexType>

  <!-- verbose node type -->
  <xs:complexType name="verbose">
    <xs:attribute name="value" type="xs:string" />
  </xs:complexType>

  <!-- name only node type -->
  <xs:complexType name="name">
    <xs:attribute name="name" type="xs:string" />
  </xs:complexType>


  <!-- mass node type -->
  <xs:complexType name="mass">
    <!-- FIXME: is value optional? -->
    <xs:attribute name="value" type="xs:double" default="0" />
  </xs:complexType>

  <!-- inertia node type -->
  <xs:complexType name="inertia">
    <!-- FIXME: is it optional? default value? -->
    <xs:attribute name="ixx" type="xs:double" default="0" />
    <xs:attribute name="ixy" type="xs:double" default="0" />
    <xs:attribute name="ixz" type="xs:double" default="0" />
    <xs:attribute name="iyy" type="xs:double" default="0" />
    <xs:attribute name="iyz" type="xs:double" default="0" />
    <xs:attribute name="izz" type="xs:double" default="0" />
  </xs:complexType>

  <!-- inertial node type -->
  <xs:complexType name="inertial">
    <xs:all>
      <xs:element name="origin"
		  type="pose" minOccurs="0" maxOccurs="1" />
      <xs:element name="mass"
		  type="mass" minOccurs="0" maxOccurs="1" />
      <xs:element name="inertia"
		  type="inertia" minOccurs="0" maxOccurs="1" />
    </xs:all>
  </xs:complexType>

  <!-- box node type -->
  <xs:complexType name="box">
    <xs:attribute name="size" type="xs:string" default="0 0 0" />
  </xs:complexType>

  <!-- cylinder node type -->
  <xs:complexType name="cylinder">
    <xs:attribute name="radius" type="xs:double" use="required" />
    <xs:attribute name="length" type="xs:double" use="required" />
  </xs:complexType>

  <!-- sphere node type -->
  <xs:complexType name="sphere">
    <xs:attribute name="radius" type="xs:double" use="required" />
  </xs:complexType>

  <!-- mesh node type -->
  <xs:complexType name="mesh">
    <xs:attribute name="filename" type="xs:anyURI" use="required" />
    <xs:attribute name="scale" type="xs:string" default="1 1 1" />
  </xs:complexType>

  <!-- geometry node type -->
  <xs:complexType name="geometry">
    <xs:choice>
      <xs:element name="box" type="box" />
      <xs:element name="cylinder" type="cylinder" />
      <xs:element name="sphere" type="sphere" />
      <xs:element name="mesh" type="mesh" />
    </xs:choice>
  </xs:complexType>

  <!-- texture node type -->
  <xs:complexType name="texture">
    <xs:attribute name="filename" type="xs:anyURI" />
  </xs:complexType>

  <!-- material node type -->
  <xs:complexType name="material">
    <xs:sequence>
      <xs:element name="color" type="color" minOccurs="0" maxOccurs="1" />
      <xs:element name="texture" type="texture" minOccurs="0" maxOccurs="1" />
    </xs:sequence>
    <xs:attribute name="name" type="xs:string" />
  </xs:complexType>

  <!-- material (global) node type -->
  <xs:complexType name="material_global">
    <xs:sequence>
      <xs:element name="color" type="color" minOccurs="0" maxOccurs="1" />
      <xs:element name="texture" type="texture" minOccurs="0" maxOccurs="1" />
    </xs:sequence>
    <xs:attribute name="name" type="xs:string" use="required" />
  </xs:complexType>


  <!-- visual node type -->
  <xs:complexType name="visual">
    <xs:sequence>
      <xs:element name="origin"
		  type="pose" minOccurs="0" maxOccurs="1" />
      <xs:element name="geometry"
		  type="geometry" minOccurs="1" maxOccurs="1" />
      <xs:element name="material"
		  type="material" minOccurs="0" maxOccurs="1" />
    </xs:sequence>
  </xs:complexType>

  <!-- collision node type -->
  <xs:complexType name="collision">
    <xs:sequence>
      <xs:element name="origin"
		  type="pose" minOccurs="0" maxOccurs="1" />
      <xs:element name="geometry"
		  type="geometry" minOccurs="1" maxOccurs="1" />
      <xs:element name="verbose"
		  type="verbose" minOccurs="0" maxOccurs="1" />
    </xs:sequence>
    <!-- FIXME: used but not documented -->
    <xs:attribute name="name" type="xs:string" />
  </xs:complexType>

  <!-- link node type -->
  <xs:complexType name="link">
    <xs:all>
      <xs:element name="inertial"
		  type="inertial" minOccurs="0" maxOccurs="1" />
      <xs:element name="visual"
		  type="visual" minOccurs="0"/>
      <xs:element name="collision"
		  type="collision" minOccurs="0"/>
    </xs:all>
    <xs:attribute name="name" type="xs:string" use="required" />

    <!-- FIXME: undocumented but used by PR2 -->
    <xs:attribute name="type" type="xs:string" />
  </xs:complexType>


  <!-- parent node type -->
  <xs:complexType name="parent">
    <xs:attribute name="link" type="xs:string" use="required" />
  </xs:complexType>

  <!-- child node type -->
  <xs:complexType name="child">
    <xs:attribute name="link" type="xs:string" use="required" />
  </xs:complexType>

  <!-- axis node type -->
  <xs:complexType name="axis">
    <xs:attribute name="xyz" type="xs:string" default="1 0 0" />
  </xs:complexType>

  <!-- calibration node type -->
  <xs:complexType name="calibration">
    <xs:attribute name="reference_position" type="xs:double"/>
    <xs:attribute name="rising" type="xs:double"/>
    <xs:attribute name="falling" type="xs:double"/>
  </xs:complexType>

  <!-- dynamics node type -->
  <xs:complexType name="dynamics">
    <xs:attribute name="damping" type="xs:double" default="0" />
    <xs:attribute name="friction" type="xs:double" default="0" />
  </xs:complexType>

  <!-- limit node type -->
  <xs:complexType name="limit">
    <xs:attribute name="lower" type="xs:double" default="0" />
    <xs:attribute name="upper" type="xs:double" default="0" />
    <xs:attribute name="effort" type="xs:double" default="0" />
    <xs:attribute name="velocity" type="xs:double" default="0" />
  </xs:complexType>

  <!-- safety controller node type -->
  <xs:complexType name="safety_controller">
    <xs:attribute name="soft_lower_limit" type="xs:double" default="0" />
    <xs:attribute name="soft_upper_limit" type="xs:double" default="0" />
    <xs:attribute name="k_position" type="xs:double" default="0" />
    <xs:attribute name="k_velocity" type="xs:double" use="required" />
  </xs:complexType>

  <!-- mimic node type -->
  <xs:complexType name="mimic">
    <xs:attribute name="joint" type="xs:string" use="required" />
    <xs:attribute name="multiplier" type="xs:double" default="1" />
    <xs:attribute name="offset" type="xs:double" default="0" />
  </xs:complexType>

  <!-- actuator transmission node type -->
  <xs:complexType name="actuator_transmission">
    <xs:attribute name="mechanicalReduction" type="xs:double" use="required" />
    <xs:attribute name="name" type="xs:string" use="required" />
  </xs:complexType>

  <!-- gap joint transmission node type -->
  <xs:complexType name="gap_joint_transmission">
    <xs:attribute name="L0" type="xs:double" use="required" />
    <xs:attribute name="a" type="xs:double" use="required" />
    <xs:attribute name="b" type="xs:double" use="required" />
    <xs:attribute name="gear_ratio" type="xs:double" use="required" />
    <xs:attribute name="h" type="xs:double" use="required" />
    <xs:attribute name="mechanical_reduction" type="xs:double" use="required" />
    <xs:attribute name="name" type="xs:string" use="required" />
    <xs:attribute name="phi0" type="xs:double" use="required" />
    <xs:attribute name="r" type="xs:double" use="required" />
    <xs:attribute name="screw_reduction" type="xs:double" use="required" />
    <xs:attribute name="t0" type="xs:double" use="required" />
    <xs:attribute name="theta0" type="xs:double" use="required" />
  </xs:complexType>

  <!-- passive joint transmission node type -->
  <xs:complexType name="passive_joint_transmission">
    <xs:attribute name="name" type="xs:string" use="required" />
  </xs:complexType>

  <!-- transmission node type -->
  <xs:complexType name="transmission">
    <xs:sequence minOccurs="0" maxOccurs="unbounded">
      <xs:element name="leftActuator"
		  type="actuator_transmission" minOccurs="0" maxOccurs="1" />
      <xs:element name="rightActuator"
		  type="actuator_transmission" minOccurs="0" maxOccurs="1" />
      <xs:element name="flexJoint"
		  type="actuator_transmission" minOccurs="0" maxOccurs="1" />
      <xs:element name="rollJoint"
		  type="actuator_transmission" minOccurs="0" maxOccurs="1" />
      <xs:element name="gap_joint"
		  type="gap_joint_transmission" minOccurs="0" maxOccurs="1" />
      <xs:element name="passive_joint"
		  type="passive_joint_transmission" minOccurs="0" maxOccurs="unbounded" />
      <xs:element name="use_simulated_gripper_joint" minOccurs="0" maxOccurs="1">
	<xs:complexType>
	</xs:complexType>
      </xs:element>
      <xs:element name="mechanicalReduction" type="xs:double"
		  minOccurs="0" maxOccurs="1" />

      <xs:element name="actuator" type="name" minOccurs="0" maxOccurs="1" />
      <xs:element name="joint" type="name" minOccurs="0" maxOccurs="1" />
    </xs:sequence>
    <xs:attribute name="name" type="xs:string" use="required" />
    <xs:attribute name="type" type="xs:string" use="required" />
  </xs:complexType>

  <!-- joint node type -->
  <xs:complexType name="joint">
    <xs:all>
      <xs:element name="origin"
		  type="pose" minOccurs="0" maxOccurs="1" />
      <xs:element name="parent"
		  type="parent" minOccurs="1" maxOccurs="1" />
      <xs:element name="child"
		  type="child" minOccurs="1" maxOccurs="1" />
      <xs:element name="axis"
		  type="axis" minOccurs="0" maxOccurs="1" />
      <xs:element name="calibration"
		  type="calibration" minOccurs="0" maxOccurs="1" />
      <xs:element name="dynamics"
		  type="dynamics" minOccurs="0" maxOccurs="1" />
      <xs:element name="limit"
		  type="limit" minOccurs="0" maxOccurs="1" />
      <xs:element name="safety_controller"
		  type="safety_controller" minOccurs="0" maxOccurs="1" />
      <xs:element name="mimic"
		  type="mimic" minOccurs="0" maxOccurs="1" />
    </xs:all>
    <xs:attribute name="name" type="xs:string" use="required" />
    <xs:attribute name="type" type="xs:string" use="required" />
  </xs:complexType>

  <!-- root node is always robot -->
  <xs:element name="robot">
    <xs:complexType>
      <xs:sequence minOccurs="0" maxOccurs="unbounded">
	<xs:element name="joint"
		    type="joint" minOccurs="0" maxOccurs="unbounded" />
	<xs:element name="link"
		    type="link" minOccurs="0" maxOccurs="unbounded" />

	<!-- FIXME: this is used but undocumented -->
	<xs:element name="material"
		    type="material_global" minOccurs="0" maxOccurs="unbounded" />

	<!-- FIXME: this is used but undocumented -->
	<xs:element name="transmission"
		    type="transmission" minOccurs="0" maxOccurs="unbounded" />

	<!-- FIXME: gazebo extension not supported -->
      </xs:sequence>
      <xs:attribute name="name" type="xs:string" use="required" />

      <!-- TM: I suggest adding the following attribute. -->
      <xs:attribute name="version" type="xs:string" default="1.0" />
    </xs:complexType>
  </xs:element>
</xs:schema>
