Archived OpenModelica forums. Posting is disabled.

Alternative forums include GitHub discussions or StackOverflow (make sure to read the Stack Overflow rules; you need to have well-formed questions)


Forgot password? | Forgot username? | Register

Implement a class (constructor, destructor) in a block

Implement a class (constructor, destructor) in a block

Hey,
I try to create a sampled block PI-Controller (using external C-Code).
Besides, I want to use a class containing constructor and destructor as function, which causes the following problem.
I did it very similar to this describtion.
https://build.openmodelica.org/Document … bject.html

The main difference is, that I don't use a model, but a block, which I will use in a model later on.

When I simulate my block, I get this error:
"Looking for a function .MyController but found a class"

Here you can see my block:

block RegelungC3
  parameter Real pgain(unit = "1") = 1 "Proportional gain";
  parameter Real igain(unit = "1") = 1 "Integral gain";
  parameter Real dTime(unit = "s", final min = Modelica.Constants.small, start = 0.01) = 0.01 "Sample period";
  MyController controller = MyController(pgain = pgain, igain = igain, dTime = dTime);
  parameter Real t_start(unit = "s") = 0 "starttime";
  parameter Real target(unit = "rad/s") = 1 "Target angular velocity";
  Modelica.Blocks.Interfaces.RealInput current(unit = "rad/s") "Absolut angular velocity as input signal"
equation
  when sample(t_start, dTime) then
    y = Func3(target, current);
  end when;
end RegelungC3;

I tried to change the marked sentence to " MyController controller = MyController.constructor(...); without success.

How can I make sure that Modelica does not look for a function at this point or do I have to use a diffrent kind of class-declaration?

Here you can see the class:

class MyController
  extends ModelicaReference.Classes.ExternalObject;

  function constructor
    input Real pgain;
    input Real igain;
    input Real dTime;
    output MyController controller;
 
    external "C" controller = RegelungInit(pgain, igain, dTime) annotation(Library = "libRegler3.a", Include = "#include \"Regler3.h\"");
  end constructor;

  function destructor
    input MyController controller;
 
    external "C" RegelungExit(controller) annotation(Library = "libRegler3.a", Include = "#include \"Regler3.h\"");
  end destructor;
end MyController;


Thanks for your help.

Re: Implement a class (constructor, destructor) in a block

You must not extend "ModelicaReference...ExternalObject". External objects extend from "ExternalObject".

Re: Implement a class (constructor, destructor) in a block

Thanks for your quick reply.

I deleted "extends ModelicaReference.Classes.ExternalObject;" in class MyController, but without success.
Still I get the error: "Looking for a function MyController but found a class."

Do you have another idea?

Re: Implement a class (constructor, destructor) in a block

You shouldn't have deleted the entire line, just changed it to "extends ExternalObject;"

Re: Implement a class (constructor, destructor) in a block

Sorry for my missunderstanding.

Now I have another problem about the input arguments of my C-Code:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "Regler3.h"

void* RegelungInit( double pgain, double igain, double dTime, MyController * p )
{
    p->i_anteil = 0.0;
    p->pgain = pgain;
    p->igain = igain;
    p->dTime = dTime;
    return(NULL);
}

void* RegelungExit( MyController * p )
{
    return(NULL);
}

double Regler3( double target, double current, MyController * p )
{
    p->error = (target - current);
    p->p_anteil = p->error * p->pgain;
    p->i_anteil += (p->igain * p->error * p->dTime);
    p->out = p->p_anteil + p->i_anteil;

    return (p->out);
}

The Header:

typedef struct
{
    double error;
    double p_anteil;
    double pgain;
    double igain;
    double out;
    double i_anteil;
    double dTime;
} MyController;


void* RegelungInit(double pgain, double igain, double dTime, MyController * p );
void* RegelungExit( MyController * p);
double Regler3(double target, double current, MyController * p );


Obviously, I have to fit the headers. They have to have the same arguments as the functions in Modelica.

The Problem is, that I don't know how to make sure that the C-Code works, when I change the functions like this, because of the structure I use in all the C-functions:

void* RegelungInit( double pgain, double igain, double dTime );
void* RegelungExit();
double Regler3( double target, double current );


Sorry I am no expert at C-Code current/wink

Re: Implement a class (constructor, destructor) in a block

Well, you shouldn't need any include in the constructor or destructor (this makes OpenModelica tool automatically generate the header, which uses void*).

The constructor/destructors should be:

Code:

void* RegelungInit( double pgain, double igain, double dTime ) 

{
   MyController *p = (MyController*) malloc(sizeof(MyController));
    p->i_anteil = 0.0;
    p->pgain = pgain;
    p->igain = igain;
    p->dTime = dTime;
    return p;
}

void RegelungExit( MyController * p )
{
  free(p);
}

Re: Implement a class (constructor, destructor) in a block

Thanks for your help.
I did it a little bit diffrent, but now everything works fine.

There are 0 guests and 0 other users also viewing this topic
You are here: