Extending the Real-Time Toolkit

									
					<!--Couldn't selectively extract content, Imported Full Body :(-->
					
					<div class="article" lang="en" xml:lang="en"><div class="titlepage"><div><div></div><div><div class="authorgroup"><div class="author"><h3 class="author"><span class="firstname">Peter</span> <span class="surname">Soetens</span></h3><div class="affiliation"><span class="orgname">FMTC/K.U.Leuven<br></br></span><div class="address"><p><span class="country">Belgium</span></p></div></div></div></div></div><div><p class="copyright">Copyright &#xA9; 2006 Peter Soetens, FMTC</p></div><div><div class="legalnotice"><a id="id2505325"></a><p>
	Permission is granted to copy, distribute and/or modify this document
	under the terms of the GNU Free Documentation License, Version 1.1 or
	any later version published by the Free Software Foundation, with no
	Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
	Texts. A copy of this license can be found at
	<a href="http://www.fsf.org/copyleft/fdl.html" target="_top">http://www.fsf.org/copyleft/fdl.html</a>.
      </p></div></div><div><div class="revhistory"><table border="1" width="100%" summary="Revision history"><tr><th align="left" valign="top" colspan="3"><b>Revision History</b></th></tr><tr><td align="left">Revision 1.0.1</td><td align="left">24 Nov 2006</td><td align="left">ps</td></tr><tr><td align="left" colspan="3">Separated from the Developer's Manual.</td></tr></table></div></div><div><div class="abstract"><p class="title"><b>Abstract</b></p><p>
	This document is an introduction to making user defined types
	(classes) visible within <span class="acronym">Orocos</span>. You need to read this
	document when you want to see the value of an object you
	defined yourself, for example in the TaskBrowser component or
	in an Orocos script. Other uses are reading and writing
	objects to and from XML and generally, anything a built-in
	Orocos type can do, so can yours.
      </p></div></div></div><hr></hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id2482806">1. The Orocos Type System : Toolkits</a></span></dt><dd><dl><dt><span class="section"><a href="#id2482820">1.1. The Real-Time Toolkit</a></span></dt><dt><span class="section"><a href="#id2482877">1.2. Telling Orocos about your data</a></span></dt><dt><span class="section"><a href="#id2481988">1.3. Building your own Toolkit</a></span></dt></dl></dd></dl></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id2482806"></a>1.&#xA0;The Orocos Type System : Toolkits</h2></div></div></div><p>
      Most applications define their own classes or structs to exchange
      data between objects. It is possible to tell Orocos about these
      user defined types such that they can be displayed, stored to XML,
      used in the scripting engine or even transfered over a network
      connection.
    </p><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="id2482820"></a>1.1.&#xA0;The Real-Time Toolkit</h3></div></div></div><p>
	Orocos uses the 'Toolkit' principle to make it aware of user
	types. Orocos' Real-Time Toolkit already provides support for
	the C++ types <code xmlns:str="http://xsltsl.org/string" class="classname">int</code>,<code xmlns:str="http://xsltsl.org/string" class="classname">unsigned
	int</code>,<code xmlns:str="http://xsltsl.org/string" class="classname">double</code>,
	<code xmlns:str="http://xsltsl.org/string" class="classname">char</code>,<code xmlns:str="http://xsltsl.org/string" class="classname">bool</code>,<code xmlns:str="http://xsltsl.org/string" class="classname">float</code>,
	<code xmlns:str="http://xsltsl.org/string" class="classname">vector&lt;double&gt;</code> and
	<code xmlns:str="http://xsltsl.org/string" class="classname">string</code>.
      </p><p>
	A toolkit can be imported into the application by writing:
	</p><pre class="programlisting">  #include &lt;rtt/RealTimeToolkit.hpp&gt;
  // ...
  RTT::Toolkit::Import( RTT::RealTimeToolkit );	</pre><p>
	This is however done automatically, unless you disabled that
	option in the configuration system. After this line is executed,
	Orocos is able to display, transfer over a network or recognise
	these types in scripts.
      </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="id2482877"></a>1.2.&#xA0;Telling Orocos about your data</h3></div></div></div><p>
	Say that you have an application which transfers data
	in a struct <code xmlns:str="http://xsltsl.org/string" class="classname">ControlData</code> :
	</p><pre class="programlisting">  struct ControlData {
    double x, y, z;
    int sample_nbr;
  }</pre><p>
        How can you tell Orocos how to handle this type ? A helper
	class is provided which you can extend to fit your needs,
	<a xmlns="http://www.w3.org/TR/xhtml1/transitional" href="../api/html/classRTT_1_1TemplateTypeInfo.html">TemplateTypeInfo</a>.
	</p><pre class="programlisting">  #include &lt;rtt/TemplateTypeInfo.hpp&gt;
  // ...
  struct ControlDataTypeInfo
    : public RTT::TemplateTypeInfo&lt;ControlData&gt;
  {
     ControlDataTypeInfo()
        : RTT::TemplateTypeInfo&lt;ControlData&gt;("ControlData")
     {}
  };
  // Tell Orocos the name and type of this struct:
  RTT::TypeInfoRepository::Instance()-&gt;addType( new ControlDataTypeInfo() );
	</pre><p>
	From now on, Orocos knows the 'ControlData' type name and allows
	you to create a scripting variable of that type. It does however
	not know yet how to display it or write it to an XML file.
      </p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="Note" src="../../../../../stable/documentation/rtt/v1.0.x/doc-xml/images/icons/note.png"></img></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>
	  The type is now usable as a 'var' in a script, however,
	  in order to initialise a variable, you need to add a constructor as
	  well. See <a href="#overloading-constructors" title="1.3.2. Loading Constructors">Section&#xA0;1.3.2, &#x201C;Loading Constructors&#x201D;</a>. 
	</p></td></tr></table></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id2483044"></a>1.2.1.&#xA0;Displaying</h4></div></div></div><p>
	  In order to tell Orocos how to display your type, you
	  may overload the <code class="function">TemplateTypeInfo::write</code> fuction
	  or define <code class="function">operator&lt;&lt;()</code> for your type:
	</p><pre class="programlisting">  #include &lt;rtt/TemplateTypeInfo.hpp&gt;
  #include &lt;ostream&gt;
  std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const ControlData&amp; cd) {
     return os &lt;&lt; '('&lt;&lt; cd.x &lt;&lt; cd.y &lt;&lt; cd.z &lt;&lt; '): ' &lt;&lt; cd.sample_nbr;
  }
  // ...
  // 'true' argument: <span class="emphasis"><em> it has operator&lt;&lt;</em></span>
  struct ControlDataTypeInfo
    : public RTT::TemplateTypeInfo&lt;ControlData,<span class="emphasis"><em>true</em></span>&gt;
  {
     ControlDataTypeInfo()
        : RTT::TemplateTypeInfo&lt;ControlData,<span class="emphasis"><em>true</em></span>&gt;("ControlData")
     {}
  };
  // Tell Orocos the name and type of this struct
  RTT::TypeInfoRepository::Instance()-&gt;addType( new ControlDataTypeInfo() );
	</pre><p>
	  If you use the above line of code to add the type, Orocos will be
	  able to display it as well, for example in the TaskBrowser or
	  in the ReportingComponent.
	</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id2483102"></a>1.2.2.&#xA0;Writing to XML</h4></div></div></div><p>
	  In order to inform Orocos of the structure of your data type,
	  it must be given a 'decompose' function: Of which primitive types
	  does the struct consists ? Representing structured data is what
	  Orocos <a xmlns="http://www.w3.org/TR/xhtml1/transitional" href="../api/html/classRTT_1_1Property.html">Property</a> objects do.
	  Here is how to tell Orocos how the "ControlData" is structured:
	</p><pre class="programlisting">  // ...
  struct ControlDataTypeInfo
    : public TemplateTypeInfo&lt;ControlData,true&gt;
  {
     // ... other functions omitted
     virtual bool decomposeTypeImpl(const ControlData&amp; in, PropertyBag&amp; targetbag ) const {
         targetbag.setType("ControlData");
         targetbag.add( new Property&lt;double&gt;("X", "X value of my Data", in.x ) );
         targetbag.add( new Property&lt;double&gt;("Y", "Y value of my Data", in.y ) );
         targetbag.add( new Property&lt;double&gt;("Z", "Z value of my Data", in.z ) );
         targetbag.add( new Property&lt;int&gt;("Sample", "The sample number of the Data", in.sample_nbr ) );
         return true;
     }
  }</pre><p>
	  That was easy ! For each member of your struct, add a
	  <a xmlns="http://www.w3.org/TR/xhtml1/transitional" href="../api/html/classRTT_1_1Property.html">Property</a> of the correct
	  type to the targetbag and you're done !
	  <code class="function">setType()</code> can be used lateron to
	  determine the version or type of your XML representation.  Next,
	  if Orocos tries to write an XML file with ControlData in it,
	  it will look like:
	</p><pre class="programlisting">
  &lt;struct name="MyData" type="ControlData"&gt;
    &lt;simple name="X" type="double"&gt;
       &lt;description&gt;X value of my Data&lt;/description&gt;
       &lt;value&gt;0.12&lt;/value&gt;
    &lt;/simple&gt;
    &lt;simple name="Y" type="double"&gt;
       &lt;description&gt;Y value of my Data&lt;/description&gt;
       &lt;value&gt;1.23&lt;/value&gt;
    &lt;/simple&gt;
    &lt;simple name="Z" type="double"&gt;
       &lt;description&gt;Z value of my Data&lt;/description&gt;
       &lt;value&gt;3.21&lt;/value&gt;
    &lt;/simple&gt;
    &lt;simple name="Sample" type="short"&gt;
       &lt;description&gt;The sample number of the Data&lt;/description&gt;
       &lt;value&gt;3123&lt;/value&gt;
    &lt;/simple&gt;
  &lt;/struct&gt;
	</pre></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id2483170"></a>1.2.3.&#xA0;Reading from XML</h4></div></div></div><p>
	  Orocos does not know yet how to convert an XML format back
	  to the ControlData object. This operation is called 'composition'
	  and is fairly simple as well:
	  Here is how to tell Orocos how the "ControlData" is read:
	</p><pre class="programlisting">  // ...
  struct ControlDataTypeInfo
    : public TemplateTypeInfo&lt;ControlData,true&gt;
  {
     // ... other functions omitted
     virtual bool composeTypeImpl(const PropertyBag&amp; bag, ControlData&amp; out ) const 
     {
        if ( bag.getType() == std::string("ControlData") ) // check the type
        {  
          Property&lt;double&gt;* x = targetbag.getProperty&lt;double&gt;("X");
          Property&lt;double&gt;* y = targetbag.getProperty&lt;double&gt;("Y");
          Property&lt;double&gt;* z = targetbag.getProperty&lt;double&gt;("Z");
          Property&lt;int&gt;* t = targetbag.getProperty&lt;int&gt;("Sample");
	  if ( !x || !y || !z || !t )
	     return false;
          out.x = x-&gt;get();
          out.y = y-&gt;get();
          out.z = z-&gt;get();
          out.sample_nbr = t-&gt;get();
          return true;
        }
        return false; // unknown type !
     }
  }</pre><p>
	  First the properties are located in the bag, it should look just
	  like we stored them. If not, return false, otherwise, read the
	  values and store them in the out variable.
	</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id2483233"></a>1.2.4.&#xA0;Network transfer (CORBA)</h4></div></div></div><p>
	  In order to transfer your data between components over a
	  network, Orocos requires that you provide the conversion
	  from your type to a CORBA::Any type and back, quite similar
	  to the 'composition' and 'decomposition' of your data.
	  Look at the <a xmlns="http://www.w3.org/TR/xhtml1/transitional" href="../api/html/classRTT_1_1TemplateTypeInfo.html">TemplateTypeInfo</a>
	  interface for the functions you need to implement.
	</p><p>
	  The first step is describing your struct in IDL and generate
	  the 'client' headers with 'Any' support. Next you
	  create such a struct, fill it with your data type's data
	  and next 'stream' it to an Any. The other way around is
	  required as well.
	</p><p>
	  In addition, you will need the CORBA support of Orocos
	  enabled in your build configuration.
	</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id2481974"></a>1.2.5.&#xA0;Advanced types</h4></div></div></div><p>
	  In order to add more complex types, take a look at the
	  code of the RealTimeToolkit and the KDL Toolkit Plugin of Orocos.
	</p></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="id2481988"></a>1.3.&#xA0;Building your own Toolkit</h3></div></div></div><p>
	The number of types may grow in your application to such
	a number or diversity that it may be convenient to 
	build your own toolkit and import them when appropriate.
	Non-Orocos libraries benefit from this system as well because
	they can introduce their data types into Orocos.
      </p><p>
	Each toolkit must inherit from the
	<a xmlns="http://www.w3.org/TR/xhtml1/transitional" href="../api/html/classRTT_1_1ToolkitPlugin.html">ToolkitPlugin</a> class and implement
	four functions: <code class="function">loadTypes()</code>,
	<code class="function">loadConstructors</code>,
	<code class="function">loadOperators()</code> and
	<code class="function">getName()</code>.
      </p><p>
	The name of a toolkit must be unique. Each toolkit will be loaded
	no more than once. The loadTypes function contains all 
	'TemplateTypeInfo' constructs to tell Orocos about the types
	of your toolkit. The loadOperators function contains all
	operations that can be performed on your data such as addition ('+'),
	indexing ('i'), comparison ('==') etc. Finally, type constructors
	are added in the loadConstructors function. They allow a newly
	created script variable to be initialised with a (set of) values.
      </p><p>
	Mimick the code of the
	<a xmlns="http://www.w3.org/TR/xhtml1/transitional" href="../api/html/classRTT_1_1RealTimeToolkitPlugin.html">RealTimeToolkitPlugin</a> and
	<a xmlns="http://www.w3.org/TR/xhtml1/transitional" href="../../../kdl/v0.2.x/api/html/classKDL_1_1KDLToolkitPlugin.html">KDLToolkitPlugin</a> to build
	your own.
      </p><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="overloading-operators"></a>1.3.1.&#xA0;Loading Operators</h4></div></div></div><p>
	  Operator are stored in the class <a xmlns="http://www.w3.org/TR/xhtml1/transitional" href="../api/html/classRTT_1_1OperatorRepository.html">OperatorRepository</a>
	  in <code class="filename">Operators.hpp</code>.  The list of
	  supported operators is set by the toolkit and added to the OperatorRepository
	  It looks something like this:
	  </p><pre class="programlisting">

bool loadOperators() {

  OperatorRepository::shared_ptr or = OperatorRepository::Instance();
  // boolean stuff:
  or-&gt;add( newUnaryOperator( "!", std::logical_not&lt;bool&gt;() ) );
  or-&gt;add( newBinaryOperator( "&amp;&amp;", std::logical_and&lt;bool&gt;() ) );
  or-&gt;add( newBinaryOperator( "||", std::logical_or&lt;bool&gt;() ) );
  or-&gt;add( newBinaryOperator( "==", std::equal_to&lt;bool&gt;() ) );
  or-&gt;add( newBinaryOperator( "!=", std::not_equal_to&lt;bool&gt;() ) );
  return true;

} </pre><p>

	  Adding your own should not be terribly hard.  The hardest
	  part is that as the second argument to newUnaryOperator,
	  newBinaryOperator or newTernaryOperator, you need to specify
	  a STL Adaptable Functor, and even though the STL provides
	  many predefined one's, it does not provide all possible
	  combinations, and you might end up having to write your
	  own.  The STL does not at all provide any "ternary
	  operators", so if you need one of those, you'll definitely
	  have to write it yourself.
	</p><p>
	  Note that this section is only about adding overloads for
	  existing operators, if you want to add new operators to
	  the scripting engine, the parsers need to be extended as well.
	</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="overloading-constructors"></a>1.3.2.&#xA0;Loading Constructors</h4></div></div></div><p>
	  Constructors can only be added <span class="emphasis"><em>after</em></span> a 
	  type has been loaded using <code class="function">addType</code>.
	  Say that the ControlData struct has a constructor:
	</p><pre class="programlisting">  struct ControlData {
    ControlData(double a, double b, double c) 
      : x(a), y(b), z(c), sample_nbr(0)
    {}
    double x, y, z;
    int sample_nbr;
  }</pre><p>
	  This constructor is not automatically known to the type system.
	  You need to write a constructor function and add that to the
	  type info:
        </p><pre class="programlisting">
  ControlData createCD(double a, double b, double c) {
    return ControlData(a,b,c);
  }
  // Tell Orocos a constructor is available:
  // Attention: "ControlData" must have been added before with 'addType' !
  RTT::TypeInfoRepository::Instance()-&gt;type("ControlData")-&gt;addConstructor( &amp;createCD );
	</pre><p>
	  From now on, one can write in a script:
	</p><pre class="programlisting">  var ControlData cd = ControlData(3.4, 5.0, 1.7);</pre><p>
	  Multiple constructors can be added for the same type. The first
	  one that matches with the given arguments is then taken.
	</p></div></div></div></div>