Help - Search - Members - Calendar
Full Version: crankshaft angle generator
Modelica Forum > Modelica > Modelica
Meppel
Hi everyone,

i want to program a "crankshaftangle-generator" therfore i wanted to use an "Saw-Tooth-Block" (from the Modelica Standard Library) and change it like this:

- the parameter "period" isn't anymore an fix parameter it is given from an extra "Real-Input"-Block. This real Input is the engine speed. After all i can produce an engine speed dependend crankangle.

But there is some problem. When i declare the variable "period" as an "parameter" Dymola everytime says the variability of "period" is higher than the declared variable. When i try to declare "period" without the "parameter"-Index Dymola says that the "when"-condition must be discrete.

I would be glad if someone could help me with this problem, or if someone have some idea to program an "crankshaftangle-genarator"...



model frequencySaw
Modelica.Blocks.Interfaces.RealInput n annotation;
Modelica.Blocks.Interfaces.RealOutput y annotation;

parameter Real amplitude=1 "Amplitude of saw tooth";
parameter Real offset=0 "Offset of output signals";
parameter Modelica.SIunits.Time startTime=0
"Output = offset for time < startTime";

protected
Modelica.SIunits.Time T0(final start=startTime)
"Start time of current period";
Modelica.SIunits.Time period(final min=Modelica.Constants.small) = 1/(n*60/amplitude)
"Time for one period";

equation
when sample(startTime, period) then
T0 = time;
end when;
y = offset + (if time < startTime then 0 else (amplitude/period)*(time
- T0));
end frequencySaw;
wagner
Hello Meppel,

a parameter variable is like a constant value that can be assigned only before running the simulation. That's why your model doesn't work with period as parameter.

The problem with the "when-condition must be discrete value" is the sample command. The sample command can only take a constant value as its argument. You have to replace the sample command and implement your own functionality.

I've done it in this sample model.

QUELLTEXT
model FrequencySaw
  annotation (uses(Modelica(version="2.2.1")), Icon);
  Modelica.Blocks.Interfaces.RealInput n annotation (extent=[-100,-10; -80,10]);
  Modelica.Blocks.Interfaces.RealOutput y annotation (extent=[80,-10; 100,10]);
  
  parameter Real amplitude=1 "Amplitude of saw tooth";
  parameter Real offset=0 "Offset of output signals";
  parameter Modelica.SIunits.Time startTime=0.1 "Output = offset for time < startTime";
  Modelica.SIunits.Time T0(final start=startTime) "Start time of current period";
  
  Modelica.SIunits.Time period(final min=Modelica.Constants.small) "Time for one period";
equation
  
  if (abs(1/(n*60/amplitude))>Modelica.Constants.small) then
    period=1/(n*60/amplitude);
  else
    period=Modelica.Constants.small;
  end if;
  
  when time>T0 + period then
    T0 = time;
  end when;
  
  if (time<startTime) then
    y=offset;
  else
    y=offset+semiLinear(amplitude,(time- T0)/period,(time- T0)/period);
  end if;
end FrequencySaw;


I hope it does what you wanted to. You just have to be careful that you don't attach a period of zero because then you get a division by zero error.

Regards

Florian
Meppel
QUOTE(wagner @ Jun 6 2006, 09:40 AM) *

Hello Meppel,

a parameter variable is like a constant value that can be assigned only before running the simulation. That's why your model doesn't work with period as parameter.

The problem with the "when-condition must be discrete value" is the sample command. The sample command can only take a constant value as its argument. You have to replace the sample command and implement your own functionality.

I've done it in this sample model.

CODE
model FrequencySaw
  annotation (uses(Modelica(version="2.2.1")), Icon);
  Modelica.Blocks.Interfaces.RealInput n annotation (extent=[-100,-10; -80,10]);
  Modelica.Blocks.Interfaces.RealOutput y annotation (extent=[80,-10; 100,10]);
  
  parameter Real amplitude=1 "Amplitude of saw tooth";
  parameter Real offset=0 "Offset of output signals";
  parameter Modelica.SIunits.Time startTime=0.1 "Output = offset for time < startTime";
  Modelica.SIunits.Time T0(final start=startTime) "Start time of current period";
  
  Modelica.SIunits.Time period(final min=Modelica.Constants.small) "Time for one period";
equation
  
  if (abs(1/(n*60/amplitude))>Modelica.Constants.small) then
    period=1/(n*60/amplitude);
  else
    period=Modelica.Constants.small;
  end if;
  
  when time>T0 + period then
    T0 = time;
  end when;
  
  if (time<startTime) then
    y=offset;
  else
    y=offset+semiLinear(amplitude,(time- T0)/period,(time- T0)/period);
  end if;
end FrequencySaw;


I hope it does what you wanted to. You just have to be careful that you don't attach a period of zero because then you get a division by zero error.

Regards

Florian



Hello wagner,

many thanks, your version works well... I also found solution during weekend...

Regards Meppel


QUOTE(wagner @ Jun 6 2006, 09:40 AM) *

Hello Meppel,

a parameter variable is like a constant value that can be assigned only before running the simulation. That's why your model doesn't work with period as parameter.

The problem with the "when-condition must be discrete value" is the sample command. The sample command can only take a constant value as its argument. You have to replace the sample command and implement your own functionality.

I've done it in this sample model.

CODE
model FrequencySaw
  annotation (uses(Modelica(version="2.2.1")), Icon);
  Modelica.Blocks.Interfaces.RealInput n annotation (extent=[-100,-10; -80,10]);
  Modelica.Blocks.Interfaces.RealOutput y annotation (extent=[80,-10; 100,10]);
  
  parameter Real amplitude=1 "Amplitude of saw tooth";
  parameter Real offset=0 "Offset of output signals";
  parameter Modelica.SIunits.Time startTime=0.1 "Output = offset for time < startTime";
  Modelica.SIunits.Time T0(final start=startTime) "Start time of current period";
  
  Modelica.SIunits.Time period(final min=Modelica.Constants.small) "Time for one period";
equation
  
  if (abs(1/(n*60/amplitude))>Modelica.Constants.small) then
    period=1/(n*60/amplitude);
  else
    period=Modelica.Constants.small;
  end if;
  
  when time>T0 + period then
    T0 = time;
  end when;
  
  if (time<startTime) then
    y=offset;
  else
    y=offset+semiLinear(amplitude,(time- T0)/period,(time- T0)/period);
  end if;
end FrequencySaw;


I hope it does what you wanted to. You just have to be careful that you don't attach a period of zero because then you get a division by zero error.

Regards

Florian

This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2012 Invision Power Services, Inc.