For a project I have, I control a BLDC motor with it's own current controller.
To design a controller for the motor I fitted some time traces to the flowing function:
to capture the dynamics of the entire system, namely, motor, current controller/driver and load.
J is the rotor inertia, [kg*m^2]
r a dampening constant (linear friction)
tau is a torque constant [Nm/A]
u[t] a current input
der(der(phi)) is the angular acceleration
der(phi) the angular velocity
The fitted values represent the entire system more than good enough for a 'continuous' approximation of the motor, the load and the current controller/driver of the motor. With the control scheme, I give a signal u(t) in Amps, and I expect a torque and an angular velocity as an output. At the time I only needed the angular velocity, but I digress, this method worked fantastically, but was fitted and designed in mathematica.
I would like to build a much larger, and significantly more complex robotic system within modelica (Systemmodeler specifcally, however, modelica library 3.2.x), however I am having some issues.
My first attempt was:
However, when simulating this with another outside load (an external model), I have a lot of issues, from some those more experienced than I, I am told this form of modelling is 'one way' and not the 'modelica method' but more simulink in form.
Namely, it should be bi-directional, not just numerical outputs, in order to correctly react with the multibody external model, this will connect to.
My second attempt was:
Which when connecting to my larger multibody model, it does indeed work more like it's expected to, there is a reaction from this model, when external torques/loads are applied. However, when simulating this model to see how it fairs compared to the pure block model, they arn't the same by any means. I had to spend a lot of time trying to fit the inertia and friction data to get similar results.
SO my question is, what is the best method, to turn pure block models (mathematical ones) or atleast,my pure block model, into a more realistic model or atleast, the connecting outputs into more realistic, or I guess 'acasual' ones.
I would prefer not to use my second attempt, since I can't trust the values I had to adjust compared to the block to actually be correct, since they arn't fitted values to real world data, compared to my first model.
Difficult to answer in general. Basically you need to understand which model corresponds to which part of the system/equation you want to model and then combine them to result in the same overall behavior.
The original model/equation seems consist of (correct me if I'm misunderstanding the equation):
J * dot(dot(phi))
r * dot(phi)
tau * u(t)
If you don't know the components I think there is no way besides investing time into understanding the Modelica code or at least the documentation of each component.
I would use the following components to describe the behavior
Modelica.Mechanics.Rotational.Components.Inertia
Modelica.Mechanics.Rotational.Components.Damper
Modelica.Blocks.Math.Gain
and Modelica.Mechanics.Rotational.Sources.Torque
As an extension I would suggest to use the physical quantity (current) as an input. This can be done by changing the model to:
Extending the model with two more meaningful components (Resistance and Inductance as asked for in the first comment) results in:
Note: The model is actually a 1~ representation of a 3~ motor. I think the parameters for terminal resistance/inductance should still be valid, but I would strongly suggest to validate the model by e.g. computing speeds at no-load operation and nominal load.
In case you need the code from which the above screenshots were generated (using MSL 4.0.0):
package MotorExamples
model SignalControlledMotor
extends Modelica.Electrical.Machines.Icons.Machine;
parameter Real k "Gain value multiplied with input signal";
parameter Modelica.Units.SI.Inertia J "Moment of inertia";
parameter Modelica.Units.SI.RotationalDampingConstant d "Damping constant";
Modelica.Blocks.Interfaces.RealInput u(final unit="A")
annotation (Placement(transformation(extent={{-140,-20},{-100,20}}), iconTransformation(extent={{-140,-20},{-100,20}})));
Modelica.Blocks.Math.Gain gain(k=k)
annotation (Placement(transformation(extent={{-80,-10},{-60,10}})));
Modelica.Mechanics.Rotational.Sources.Torque torque
annotation (Placement(transformation(extent={{-40,-10},{-20,10}})));
Modelica.Mechanics.Rotational.Components.Inertia inertia(J=J)
annotation (Placement(transformation(extent={{0,-10},{20,10}})));
Modelica.Mechanics.Rotational.Components.Damper damper(d=d)
annotation (Placement(transformation(
extent={{-10,-10},{10,10}},
rotation=270,
origin={60,-30})));
Modelica.Mechanics.Rotational.Interfaces.Flange_a flange "Mechanical flange of motor"
annotation (Placement(transformation(extent={{90,-10},{110,10}})));
Modelica.Mechanics.Rotational.Components.Fixed fixed
annotation (Placement(transformation(extent={{50,-70},{70,-50}})));
equation
connect(gain.u, u) annotation (Line(points={{-82,0},{-120,0}}, color={0,0,127}));
connect(torque.tau, gain.y) annotation (Line(points={{-42,0},{-59,0}}, color={0,0,127}));
connect(inertia.flange_a, torque.flange) annotation (Line(points={{0,0},{-20,0}}, color={0,0,0}));
connect(inertia.flange_b, damper.flange_a) annotation (Line(points={{20,0},{60,0},{60,-20}},
color={0,0,0}));
connect(damper.flange_a, flange) annotation (Line(points={{60,-20},{60,0},{100,0}},
color={0,0,0}));
connect(damper.flange_b, fixed.flange) annotation (Line(points={{60,-40},{60,-60}}, color={0,0,0}));
annotation (Icon(graphics={Line(points={{-60,0},{-100,0}}, color={0,0,0})}));
end SignalControlledMotor;
model CurrentControlledMotor
extends Modelica.Electrical.Machines.Icons.Machine;
parameter Modelica.Units.SI.ElectricalTorqueConstant k "Transformation coefficient";
parameter Modelica.Units.SI.Inertia J "Moment of inertia";
parameter Modelica.Units.SI.RotationalDampingConstant d "Damping constant";
Modelica.Units.SI.Voltage v = p.v - n.v "Terminal voltage";
Modelica.Electrical.Analog.Basic.RotationalEMF
emf(k=k)
annotation (Placement(transformation(extent={{-40,-10},{-20,10}})));
Modelica.Mechanics.Rotational.Components.Inertia inertia(J=J)
annotation (Placement(transformation(extent={{0,-10},{20,10}})));
Modelica.Mechanics.Rotational.Components.Damper damper(d=d)
annotation (Placement(transformation(
extent={{-10,-10},{10,10}},
rotation=270,
origin={60,-30})));
Modelica.Mechanics.Rotational.Interfaces.Flange_a flange "Mechanical flange of motor"
annotation (Placement(transformation(extent={{90,-10},{110,10}})));
Modelica.Mechanics.Rotational.Components.Fixed fixed
annotation (Placement(transformation(extent={{50,-70},{70,-50}})));
Modelica.Electrical.Analog.Interfaces.PositivePin p "Positive electrical pin"
annotation (Placement(transformation(extent={{-110,50},{-90,70}})));
Modelica.Electrical.Analog.Interfaces.NegativePin n "Negative electrical pin"
annotation (Placement(transformation(extent={{-110,-70},{-90,-50}})));
equation
connect(inertia.flange_a, emf.flange) annotation (Line(points={{0,0},{-20,0}}, color={0,0,0}));
connect(inertia.flange_b, damper.flange_a) annotation (Line(points={{20,0},{60,0},{60,-20}},
color={0,0,0}));
connect(damper.flange_a, flange) annotation (Line(points={{60,-20},{60,0},{100,0}},
color={0,0,0}));
connect(damper.flange_b, fixed.flange) annotation (Line(points={{60,-40},{60,-60}}, color={0,0,0}));
connect(emf.p, p) annotation (Line(points={{-30,10},{-30,60},{-100,60}}, color={0,0,255}));
connect(emf.n, n) annotation (Line(points={{-30,-10},{-30,-60},{-100,-60}}, color={0,0,255}));
annotation ( Icon(graphics={Line(points={{-60,40},{-80,40},{-80,60},{-100,60}},
color={28,108,200}),
Line(points={{-60,-40},{-80,-40},{-80,-60},{-100,-60}},
color={28,108,200})}));
end CurrentControlledMotor;
model DC_Motor
extends Modelica.Electrical.Machines.Icons.Machine;
parameter Modelica.Units.SI.ElectricalTorqueConstant k "Transformation coefficient";
parameter Modelica.Units.SI.Resistance R "Terminal Resistance";
parameter Modelica.Units.SI.Inductance L "Terminal Inductance";
parameter Modelica.Units.SI.Inertia J "Moment of inertia";
parameter Modelica.Units.SI.RotationalDampingConstant d "Damping constant";
Modelica.Units.SI.Voltage v = p.v - n.v "Terminal voltage";
Modelica.Electrical.Analog.Basic.RotationalEMF
emf(k=k)
annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
Modelica.Mechanics.Rotational.Components.Inertia inertia(J=J)
annotation (Placement(transformation(extent={{30,-10},{50,10}})));
Modelica.Mechanics.Rotational.Components.Damper damper(d=d)
annotation (Placement(transformation(
extent={{-10,-10},{10,10}},
rotation=270,
origin={70,-30})));
Modelica.Mechanics.Rotational.Interfaces.Flange_a flange "Mechanical flange of motor"
annotation (Placement(transformation(extent={{90,-10},{110,10}})));
Modelica.Mechanics.Rotational.Components.Fixed fixed
annotation (Placement(transformation(extent={{60,-70},{80,-50}})));
Modelica.Electrical.Analog.Interfaces.PositivePin p "Positive electrical pin"
annotation (Placement(transformation(extent={{-110,50},{-90,70}})));
Modelica.Electrical.Analog.Interfaces.NegativePin n "Negative electrical pin"
annotation (Placement(transformation(extent={{-110,-70},{-90,-50}})));
Modelica.Electrical.Analog.Basic.Resistor resistor(R=R) annotation (Placement(transformation(extent={{-80,50},{-60,70}})));
Modelica.Electrical.Analog.Basic.Inductor inductor(L=L) annotation (Placement(transformation(extent={{-40,50},{-20,70}})));
equation
connect(inertia.flange_a, emf.flange) annotation (Line(points={{30,0},{10,0}}, color={0,0,0}));
connect(inertia.flange_b, damper.flange_a) annotation (Line(points={{50,0},{70,0},{70,-20}},
color={0,0,0}));
connect(damper.flange_a, flange) annotation (Line(points={{70,-20},{70,0},{100,0}},
color={0,0,0}));
connect(damper.flange_b, fixed.flange) annotation (Line(points={{70,-40},{70,-60}}, color={0,0,0}));
connect(emf.n, n) annotation (Line(points={{0,-10},{0,-60},{-100,-60}}, color={0,0,255}));
connect(resistor.p, p) annotation (Line(points={{-80,60},{-100,60}}, color={0,0,255}));
connect(emf.p, inductor.n) annotation (Line(points={{0,10},{0,60},{-20,60}}, color={0,0,255}));
connect(inductor.p, resistor.n) annotation (Line(points={{-40,60},{-60,60}}, color={0,0,255}));
annotation ( Icon(graphics={Line(points={{-60,40},{-80,40},{-80,60},{-100,60}},
color={28,108,200}),
Line(points={{-60,-40},{-80,-40},{-80,-60},{-100,-60}},
color={28,108,200})}));
end DC_Motor;
model Test
extends Modelica.Icons.Example;
MotorExamples.SignalControlledMotor signalControlledMotor(
k=1,
J=0.1,
d=1) annotation (Placement(transformation(extent={{-12,70},{8,90}})));
Modelica.Blocks.Sources.Step step(height=10, startTime=0.1) annotation (Placement(transformation(extent={{-90,70},{-70,90}})));
CurrentControlledMotor currentControlledMotor(
k=1,
J=0.1,
d=1) annotation (Placement(transformation(extent={{-12,-10},{8,10}})));
Modelica.Electrical.Analog.Sources.SignalCurrent signalCurrent
annotation (Placement(transformation(
extent={{-10,-10},{10,10}},
rotation=0,
origin={-40,6})));
Modelica.Electrical.Analog.Basic.Ground ground annotation (Placement(transformation(extent={{-70,-28},{-50,-6}})));
DC_Motor dC_Motor(
k=1,
R=1.39,
L=0.572e-3,
J=0.1,
d=1) annotation (Placement(transformation(extent={{-12,-76},{8,-56}})));
Modelica.Electrical.Analog.Sources.SignalCurrent signalCurrentDC
annotation (Placement(transformation(
extent={{-10,-10},{10,10}},
rotation=0,
origin={-40,-60})));
Modelica.Electrical.Analog.Basic.Ground ground1
annotation (Placement(transformation(extent={{-70,-94},{-50,-72}})));
Modelica.Blocks.Continuous.FirstOrder firstOrder(T=1e-3) annotation (Placement(transformation(extent={{-60,74},{-48,86}})));
equation
connect(signalCurrent.n, currentControlledMotor.p) annotation (Line(points={{-30,6},{-12,6}}, color={0,0,255}));
connect(signalCurrent.p, currentControlledMotor.n)
annotation (Line(points={{-50,6},{-60,6},{-60,-6},{-12,-6}}, color={0,0,255}));
connect(signalCurrent.p, ground.p) annotation (Line(points={{-50,6},{-60,6},{-60,-6}}, color={0,0,255}));
connect(signalCurrentDC.p, dC_Motor.n) annotation (Line(points={{-50,-60},{-60,-60},{-60,-72},{-12,-72}}, color={0,0,255}));
connect(signalCurrentDC.p, ground1.p) annotation (Line(points={{-50,-60},{-60,-60},{-60,-72}}, color={0,0,255}));
connect(signalCurrentDC.n, dC_Motor.p) annotation (Line(points={{-30,-60},{-12,-60}}, color={0,0,255}));
connect(step.y, firstOrder.u) annotation (Line(points={{-69,80},{-61.2,80}}, color={0,0,127}));
connect(firstOrder.y, signalControlledMotor.u) annotation (Line(points={{-47.4,80},{-14,80}}, color={0,0,127}));
connect(firstOrder.y, signalCurrent.i) annotation (Line(points={{-47.4,80},{-40,80},{-40,18}}, color={0,0,127}));
connect(firstOrder.y, signalCurrentDC.i)
annotation (Line(points={{-47.4,80},{-40,80},{-40,40},{-80,40},{-80,-40},{-40,-40},{-40,-48}}, color={0,0,127}));
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(coordinateSystem(preserveAspectRatio=false)));
end Test;
annotation (uses(Modelica(version="4.0.0")));
end MotorExamples;