<?xml version="1.0" encoding="UTF-8"?>

<!--================================================================-->
<!-- Copyright 2003 P&P Software GmbH                               -->
<!--================================================================-->

<!--===================================================================
Generator meta-component for the Matlab wrapper for the OBS Framework.
A "Matlab wrapper" wraps code that generated by the autocode facility of
Matlab and makes it possible to integrate that code within an application
instantiated from the OBS Framework. The Matlab wrapper is given the
form of a component that extends the OBS Framework class
"ControlBlock".

This XSLT program generates the header file of the Matlab wrapper class.

This XSLT program assumes that the Real-Time Workshop code generation tool
with which the wrapped code was generated used the "RTW Embedded Coder" target
file. The storage class of all inputs, outputs and parameters is assumed to have
been set to "ExportedGlobal".

Version 3.0 of the Real-Time Workshop Embedded Coder is assumed.
===================================================================-->

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.1"    xmlns:lxslt="http://xml.apache.org/xslt"
    xmlns:redirect="org.apache.xalan.lib.Redirect"
    extension-element-prefixes="redirect">

<xsl:strip-space elements="*"/>
<xsl:output omit-xml-declaration="yes" method="text"/>

<!--===================================================================
       Include general utility rules
===================================================================-->
 <xsl:include href="ClassNameFromPath.xsl"/>
<!--===================================================================
      Top-level rule 
===================================================================-->
<xsl:template match="/ObsApplication/ControllerManagement/ControlAction/ControlBlock">
<!--===================================================================
      Define general-purpose variables
 ===================================================================-->  
  <xsl:variable name="ClassName">
        <xsl:call-template name="ClassNameFromPath">
              <xsl:with-param name="path" select="MatlabWrapper/@type"/>
        </xsl:call-template>
  </xsl:variable>
  <xsl:variable name="Desc" select="MatlabWrapper/Description"/>
  <xsl:variable name="NumberOfInputs" select="count(Input)"/>
  <xsl:variable name="NumberOfOutputs" select="count(Output)"/>
  <xsl:variable name="NumberOfParameters" select="count(Parameter)"/>
  <xsl:variable name="StepFunct" select="MatlabWrapper/StepFunction/@value"/>
  <xsl:variable name="InitFunct" select="MatlabWrapper/InitFunction/@value"/>
  <xsl:variable name="MatlabHeader" select="MatlabWrapper/MatlabCodeHeaderFile/@value"/>
  <xsl:variable name="CodeDir" select="'../'"/>
  <xsl:variable name="TargetFile" select="concat('/Projects/ObsFramework/src/cpp/',MatlabWrapper/@type)"/>     
            
  Generating code for class <xsl:value-of select="$ClassName"/> in files <xsl:value-of select="$TargetFile"/>.h

  <!-- Check whether writing to an output file is possible -->
  <xsl:if test="not(element-available('xsl:document'))">
        FATAL ERROR: the xsl:document element is not supported. Header files cannot be written! This element
        is normally supported only in version 1.1 of XSL.
  </xsl:if>
            
  <!-- ===================================================================================
         Create the output file  
          ===================================================================================-->
  <xsl:document href="{$TargetFile}.h" omit-xml-declaration="yes" method="text">  
<!--===================================================================
      Start Code Generation
      ===================================================================-->  
//
// Copyright 2003 P&amp;P Software GmbH - All Rights Reserved
//
// <xsl:value-of select="$ClassName"/>.h
//
// This file was generated automatically

#ifndef <xsl:value-of select="$ClassName"/>H
#define <xsl:value-of select="$ClassName"/>H

#include "<xsl:value-of select="$CodeDir"/>GeneralInclude/ForwardDeclarations.h"
#include "<xsl:value-of select="$CodeDir"/>GeneralInclude/BasicTypes.h"
#include "<xsl:value-of select="$CodeDir"/>Data/<xsl:text/>
<xsl:choose>
  <xsl:when test="CopyLink">CopyControlBlock</xsl:when>
  <xsl:when test="PointerLink">PointerControlBlock</xsl:when>
  <xsl:when test="DataItemLink">DataItemControlBlock</xsl:when>
  <xsl:when test="DataPoolLink">DataPoolControlBlock</xsl:when>
</xsl:choose>.h"

#ifdef HAVE_SIMULINK
extern "C" {
#include "<xsl:value-of select="$MatlabHeader"/>"
}
#endif

/**
 * <xsl:value-of select="$Desc"/>.
 * This class assumes that the Real-Time
 * Workshop code generation tool with which the wrapped code was generated
 * using the
 * "RTW Embedded Coder" target file. The storage class of all inputs,
 * outputs and parameters is assumed to have been set to "ExportedGlobal".
 * &lt;p&gt;
 * This class was tested only with code generated by Real-Time Workshop
 * Embedded Coder version 3.0.
 * &lt;p&gt;
 * The Matlab-generated code is not part of the OBS
 * Framework. It must be provided by the user. This class assumes that
 * the code is placed in directory: "../MatlabAutocode" where the path
 * is relative to the directory where this class is stored.
 * &lt;p&gt;
 * Since not all users will be able to provide this code, a compiler switch
 * is provided to disable use of the
 * matlab-generated code. If the macro <code>HAVE_SIMULINK</code> is
 * not defined, then the class behaves like a dummy class that
 * implements a trivial transfer function.
 * &lt;p&gt;
 * The wrapper is implemented as a form of &lt;i&gt;control block&lt;/i&gt;.
 * The control block has <xsl:value-of select="$NumberOfInputs"/> inputs and
 * <xsl:value-of select="$NumberOfOutputs"/> outputs.<xsl:if test="Parameter">
 * The control block has the following parameters:
 * &lt;ul&gt;<xsl:for-each select="Parameter">
 * &lt;li&gt;<xsl:value-of select="ParameterName/@value"/>: <xsl:value-of select="Description"/>&lt;/li&gt;</xsl:for-each>
 * &lt;/ul&gt;</xsl:if>
 * The model "step" and "initialization" functions are:
 * &lt;code&gt;<xsl:value-of select="$StepFunct"/>&lt;/code&gt; and 
 * &lt;code&gt;<xsl:value-of select="$InitFunct"/>&lt;/code&gt;.
 * The model "terminate" function is never invoked (OBS classes are never
 * destroyed). The<xsl:text/>
<xsl:choose>
  <xsl:when test="CopyLink">
 * <i>copy link</i> 
  </xsl:when>
  <xsl:when test="PointerLink">
 * <i>pointer link</i> 
  </xsl:when>
  <xsl:when test="DataItemLink">
 * <i>data item link</i> 
  </xsl:when>
  <xsl:when test="DataPoolLink">
 * <i>data pool link</i> 
  </xsl:when>
</xsl:choose> 
 * mechanism is used to link the Matlab inputs and outputs 
 * to their external inputs and outputs.
 * &lt;p&gt;
 * This class should be used as a singleton because the matlab-generated
 * code is not re-entrant. 
 * @see HAVE_SIMULINK
 * @author R. Totaro (code template) / A. Pasetti (code generator)
 * @version 1.0
 */
class <xsl:value-of select="$ClassName"/> : public <xsl:text/>
<xsl:choose>
  <xsl:when test="CopyLink">CopyControlBlock</xsl:when>
  <xsl:when test="PointerLink">PointerControlBlock</xsl:when>
  <xsl:when test="DataItemLink">DataItemControlBlock</xsl:when>
  <xsl:when test="DataPoolLink">DataPoolControlBlock</xsl:when>
</xsl:choose> {

  private:
    static unsigned int numberOfInstances;

    unsigned int numberOfOutputs;
    unsigned int numberOfInputs;
    unsigned int numberOfParameters;

#ifdef HAVE_SIMULINK
   /**
    * The following arrays contain pointers to the globally visible
    * input/output/parameter variables in the Simulink model.
    * The type real_T is defined in Simulink's header files.
    */
   real_T **modelInputs;
   real_T **modelOutputs;
   real_T **modelParameters;

   /**
    * Pointers to the Simulink model update and initialization function
    * The type boolean_T is defined in Simulink's header files.
    */
    void (*modelStep)(void);
    void (*modelInitialize)(boolean_T);
#endif

  protected:

    /**
     * Implement the state propagation function. State propagation is performed
     * internally to the matlab-generated code. This method therefore performs
     * only the following two housekeeping tasks:&lt;ul&gt;
     * &lt;li&gt;Copy the values of the parameters from the buffer 
     * maintained by the control block class into the parameter buffer maintained by the
     * Matlab code&lt;/li&gt;
     * &lt;li&gt;Load the values of the inputs into the input buffer maintained by the
     * Matlab code&lt;/li&gt;
     * &lt;/ul&gt;
     * @see ControlBlockFloatDbPar#propagate
     */
     virtual void propagateState();

    /**
     * Implement the output update function. This method performs
     * the following two tasks:&lt;ul&gt;
     * &lt;li&gt;Call the matlab-generated step function&lt;/li&gt;
     * &lt;li&gt;Write the values of the outputs computed
     * by the matlab-generated code to the control block outputs&lt;/li&gt;
     * &lt;/ul&gt;
     * @see ControlBlock#propagate
     */
     virtual void updateOutput();

public:

    /**
     * Configure the PID control block. The control block is configured to have one
     * input, one outputs, three parameters. The three parameters represent
     * the proportional, integral and derivative gain. The number of states is
     * set to zero because the state is maintained internally to the
     * Simulink-generated code. The Simulink model is initialized by calling
     * the &lt;code&gt;reset&lt;/code&gt; method.
     * The class identifier is set.
     * A pseudo-code implementation of this method therefore is:&lt;pre&gt;
     *    . . . // set up internal data structures to link to matlab code
     *    . . . // set class identifier
     *    setNumberOfStates(0);
     *    setNumberOfInputs(<xsl:value-of select="$NumberOfInputs"/>);
     *    setNumberOfOutputs(<xsl:value-of select="$NumberOfOutputs"/>);
     *    setNumberOfParameters(<xsl:value-of select="$NumberOfParameters"/>);
     *    reset(); &lt;/pre&gt;
     * Note that the number of states is set to zero because the matlab
     * code already provides a data structure to save the propagation state.
     * &lt;p&gt;
     * This class should only be instantiated once.
     */
     <xsl:value-of select="$ClassName"/>();

    /**
     * Reset the control block by invoking the matlab-generated initialize function.
     */
    virtual void reset();
};

#endif
</xsl:document>
</xsl:template>

</xsl:stylesheet>

