Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve inheritance in MultiBody using selective model extension #4231

Draft
wants to merge 22 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
c163513
Extend from PartialForce instead of PartialTwoFrames
tobolar Nov 8, 2023
7ef5bfa
Introduce orientation object R_rel (in accordance with class' documen…
tobolar Nov 8, 2023
67eb83a
Extend from PartialElementaryJoint
tobolar Jan 29, 2021
d99fa56
Extend from PartialTwoFrames
tobolar Jan 29, 2021
5d72aa3
PartialXxxBaseSensors depend on corresponding interface definitions
tobolar Mar 14, 2023
139d70b
Inherite from PartialAbsoluteSensor
tobolar Mar 14, 2023
b39daae
Add PartialTwoFramesResolve
tobolar Nov 9, 2023
40975d0
Disable cardinality assertion
tobolar Nov 9, 2023
9aae0ed
Add PartialFrameResolveConditional
tobolar Nov 10, 2023
5a13a89
Icon: delete letters 'a' and 'b'
tobolar Nov 10, 2023
e9354ca
Improve documentation
tobolar Nov 10, 2023
0364d42
Make frame_resolve non-conditional since there is PartialFrameResolve…
tobolar Nov 10, 2023
0098807
Inherit form PartialTwoFramesResolve which adds also frame_resolve
tobolar Nov 10, 2023
9ff2738
Introduce frame_resolve in PartialForce, which requires to redesign i…
tobolar Nov 10, 2023
4152552
Get rid of PartialOneFrame_b
tobolar Nov 10, 2023
544f488
Get rid of PartialOneFrame_b
tobolar Nov 10, 2023
0cebbbd
Inherit from PartialAbsoluteSensor from Interfaces
tobolar Nov 10, 2023
c70b83a
Icon: delete letters 'a' and 'b'
tobolar Nov 10, 2023
43d8c16
Inherit from PartialRelativeSensor from Interfaces
tobolar Nov 10, 2023
5c306d5
Icon: delete Text annotation contained in the baseclass
tobolar Nov 10, 2023
61d2fba
Merge branch 'modelica:master' into issue3739_inheritanceMBSbySelecti…
tobolar Dec 15, 2023
b392a01
Documentation: proper font for Modelica keyword in code snippet
tobolar Dec 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 22 additions & 28 deletions Modelica/Mechanics/MultiBody/Forces/Force.mo
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,17 @@
model Force
"Force acting between two frames, defined by 3 input signals and resolved in frame world, frame_a, frame_b or frame_resolve"
import Modelica.Units.Conversions.to_unit1;
extends Modelica.Mechanics.MultiBody.Interfaces.PartialTwoFrames;
Interfaces.Frame_resolve frame_resolve if
resolveInFrame == Modelica.Mechanics.MultiBody.Types.ResolveInFrameAB.frame_resolve
"The input signals are optionally resolved in this frame"
annotation (Placement(transformation(
origin={40,100},
extent={{-16,-16},{16,16}},
rotation=90)));
extends Interfaces.PartialTwoFramesResolve(
break frame_resolve);

Check failure on line 6 in Modelica/Mechanics/MultiBody/Forces/Force.mo

View workflow job for this annotation

GitHub Actions / syntax_checks

expected identifier but received `break`
extends Interfaces.PartialFrameResolveConditional(
final enableFrameResolve = resolveInFrame==Modelica.Mechanics.MultiBody.Types.ResolveInFrameAB.frame_resolve);

Modelica.Blocks.Interfaces.RealInput force[3](each final quantity="Force", each final unit="N")
"x-, y-, z-coordinates of force resolved in frame defined by resolveInFrame"
annotation (Placement(transformation(
origin={-60,120},
origin={-60,-120},
extent={{-20,-20},{20,20}},
rotation=270)));
rotation=90)));
parameter Boolean animation=true "= true, if animation shall be enabled";
parameter Modelica.Mechanics.MultiBody.Types.ResolveInFrameAB
resolveInFrame=
Expand Down Expand Up @@ -69,43 +66,40 @@
color={95,95,95},
thickness=0.5));
connect(force, basicForce.force) annotation (Line(
points={{-60,120},{-60,40},{4,40},{4,12}}, color={0,0,127}));
points={{-60,-120},{-60,40},{4,40},{4,-12}},
color={0,0,127}));
connect(basicForce.frame_resolve, frame_resolve) annotation (Line(
points={{14,10},{14,40},{40,40},{40,100}},
points={{10,-10},{10,40},{0,40},{0,-100}},
color={95,95,95},
pattern=LinePattern.Dot));
connect(zeroPosition.frame_resolve, basicForce.frame_resolve) annotation (
Line(
points={{40,20},{27,20},{27,10},{14,10}},
points={{40,20},{27,20},{27,-10},{10,-10}},
color={95,95,95},
pattern=LinePattern.Dot));
annotation (
Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{100,
100}}), graphics={
Text(
extent={{-80,70},{100,40}},
textColor={192,192,192},
textString="resolve"),
Text(
extent={{-150,-55},{150,-95}},
textString="%name",
textColor={0,0,255}),
Line(
points={{40,100},{40,0}},
points={{40,0},{40,-100},{-60,-100}},
color={95,95,95},
pattern=LinePattern.Dot),
Line(points={{-80,0},{-20,0}}),
Line(points={{20,0},{80,0}}),
Polygon(
points={{-94,0},{-64,11},{-64,-10},{-94,0}},
fillPattern=FillPattern.Solid),
Line(
points={{-60,100},{40,100}},
color={95,95,95},
pattern=LinePattern.Dot),
Polygon(
points={{94,0},{65,12},{65,-11},{94,0}},
fillPattern=FillPattern.Solid),
Line(points={{-64,0},{-20,0}}),
Line(points={{20,0},{65,0}})}),
Text(
extent={{-100,-40},{80,-70}},
textColor={192,192,192},
textString="resolve"),
Text(
extent={{-150,80},{150,40}},
textString="%name",
textColor={0,0,255})}),
Documentation(info="<html>
<p>
The <strong>3</strong> signals of the <strong>force</strong> connector are interpreted
Expand Down
86 changes: 38 additions & 48 deletions Modelica/Mechanics/MultiBody/Forces/Internal/BasicForce.mo
Original file line number Diff line number Diff line change
@@ -1,84 +1,74 @@
within Modelica.Mechanics.MultiBody.Forces.Internal;
model BasicForce
"Force acting between two frames, defined by 3 input signals"
extends Modelica.Mechanics.MultiBody.Interfaces.PartialTwoFrames;
extends Interfaces.PartialForce(
break world);

Check failure on line 5 in Modelica/Mechanics/MultiBody/Forces/Internal/BasicForce.mo

View workflow job for this annotation

GitHub Actions / syntax_checks

expected identifier but received `break`
import Modelica.Mechanics.MultiBody.Types.ResolveInFrameAB;
Interfaces.Frame_resolve frame_resolve
"The input signals are optionally resolved in this frame"
annotation (Placement(transformation(
origin={40,100},
extent={{-16,-16},{16,16}},
rotation=90)));

Modelica.Blocks.Interfaces.RealInput force[3](each final quantity="Force", each final unit="N")
"x-, y-, z-coordinates of force resolved in frame defined by resolveInFrame"
annotation (Placement(transformation(
origin={-60,120},
extent={{-20,-20},{20,20}},
rotation=270)));
extent={{20,-20},{-20,20}},
rotation=270,
origin={-60,-120})));
parameter Modelica.Mechanics.MultiBody.Types.ResolveInFrameAB
resolveInFrame=
Modelica.Mechanics.MultiBody.Types.ResolveInFrameAB.frame_b
"Frame in which force is resolved (1: world, 2: frame_a, 3: frame_b, 4: frame_resolve)";

SI.Position r_0[3]
"Position vector from origin of frame_a to origin of frame_b resolved in world frame";
SI.Force f_b_0[3] "frame_b.f resolved in world frame";
SI.Force f_b_0[3] "Force frame_b.f resolved in world frame";

equation
assert(cardinality(frame_resolve) > 0, "Connector frame_resolve must be connected at least once and frame_resolve.r_0/.R must be set");
frame_resolve.f = zeros(3);
frame_resolve.t = zeros(3);

if resolveInFrame == ResolveInFrameAB.frame_a then
f_b_0 = -Frames.resolve1(frame_a.R, force);
frame_b.f = Frames.resolve2(frame_b.R, f_b_0);
elseif resolveInFrame == ResolveInFrameAB.frame_b then
f_b_0 = -Frames.resolve1(frame_b.R, force);
frame_b.f = -force;
elseif resolveInFrame == ResolveInFrameAB.world then
f_b_0 = -force;
frame_b.f = Frames.resolve2(frame_b.R, f_b_0);
elseif resolveInFrame == ResolveInFrameAB.frame_resolve then
f_b_0 = -Frames.resolve1(frame_resolve.R, force);
frame_b.f = Frames.resolve2(frame_b.R, f_b_0);
else
assert(false, "Wrong value for parameter resolveInFrame");
f_b_0 = zeros(3);
frame_b.f = zeros(3);
end if;
frame_b.t = zeros(3);
r_0 = frame_b.r_0 - frame_a.r_0;
frame_b.t = zeros(3);

if resolveInFrame == ResolveInFrameAB.frame_a then
f_b_0 = -Frames.resolve1(frame_a.R, force);
frame_b.f = Frames.resolve2(frame_b.R, f_b_0);
elseif resolveInFrame == ResolveInFrameAB.frame_b then
f_b_0 = -Frames.resolve1(frame_b.R, force);
frame_b.f = -force;
elseif resolveInFrame == ResolveInFrameAB.world then
f_b_0 = -force;
frame_b.f = Frames.resolve2(frame_b.R, f_b_0);
elseif resolveInFrame == ResolveInFrameAB.frame_resolve then
f_b_0 = -Frames.resolve1(frame_resolve.R, force);
frame_b.f = Frames.resolve2(frame_b.R, f_b_0);
else
assert(false, "Wrong value for parameter resolveInFrame");
f_b_0 = zeros(3);
frame_b.f = zeros(3);
end if;

// Force and torque balance
r_0 = frame_b.r_0 - frame_a.r_0;
zeros(3) = frame_a.f + Frames.resolve2(frame_a.R, f_b_0);
zeros(3) = frame_a.t + Frames.resolve2(frame_a.R, cross(r_0, f_b_0));
annotation (
Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{
100,100}}), graphics={
Text(
extent={{-80,70},{100,40}},
textColor={192,192,192},
textString="resolve"),
Text(
extent={{-150,-55},{150,-95}},
textString="%name",
textColor={0,0,255}),
Line(
points={{40,100},{40,0}},
points={{40,0},{40,-100},{-60,-100}},
color={95,95,95},
pattern=LinePattern.Dot),
Line(points={{-80,0},{-20,0}}),
Line(points={{20,0},{80,0}}),
Polygon(
points={{-94,0},{-64,11},{-64,-10},{-94,0}},
fillPattern=FillPattern.Solid),
Line(
points={{-60,100},{40,100}},
color={95,95,95},
pattern=LinePattern.Dot),
Polygon(
points={{94,0},{65,12},{65,-11},{94,0}},
fillPattern=FillPattern.Solid),
Line(points={{-64,0},{-20,0}}),
Line(points={{20,0},{65,0}})}),
Text(
extent={{-100,-40},{80,-70}},
textColor={192,192,192},
textString="resolve"),
Text(
extent={{-150,80},{150,40}},
textString="%name",
textColor={0,0,255})}),
Documentation(info="<html>
<p>
The <strong>3</strong> signals of the <strong>force</strong> connector are interpreted
Expand Down
76 changes: 32 additions & 44 deletions Modelica/Mechanics/MultiBody/Forces/Internal/BasicTorque.mo
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
within Modelica.Mechanics.MultiBody.Forces.Internal;
model BasicTorque
"Torque acting between two frames, defined by 3 input signals"
extends Interfaces.PartialForce(
break world);

Check failure on line 5 in Modelica/Mechanics/MultiBody/Forces/Internal/BasicTorque.mo

View workflow job for this annotation

GitHub Actions / syntax_checks

expected identifier but received `break`
import Modelica.Mechanics.MultiBody.Types.ResolveInFrameAB;
extends Modelica.Mechanics.MultiBody.Interfaces.PartialTwoFrames;
Interfaces.Frame_resolve frame_resolve
"The input signals are optionally resolved in this frame"
annotation (Placement(transformation(
origin={40,100},
extent={{-16,-16},{16,16}},
rotation=90)));

Modelica.Blocks.Interfaces.RealInput torque[3](each final quantity="Torque", each final unit="N.m")
"x-, y-, z-coordinates of torque resolved in frame defined by resolveInFrame"
annotation (Placement(transformation(
origin={-60,120},
extent={{-20,-20},{20,20}},
origin={-60,-120},
extent={{20,-20},{-20,20}},
rotation=270)));
parameter Modelica.Mechanics.MultiBody.Types.ResolveInFrameAB
resolveInFrame=
Expand All @@ -23,37 +18,34 @@

SI.Position r_0[3]
"Position vector from origin of frame_a to origin of frame_b resolved in world frame";
SI.Torque t_b_0[3] "frame_b.t resolved in world frame";
SI.Torque t_b_0[3] "Torque frame_b.t resolved in world frame";

equation
assert(cardinality(frame_resolve) > 0, "Connector frame_resolve must be connected at least once and frame_resolve.r_0/.R must be set");
frame_resolve.f = zeros(3);
frame_resolve.t = zeros(3);

r_0 = frame_b.r_0 - frame_a.r_0;
frame_a.f = zeros(3);
frame_b.f = zeros(3);

if resolveInFrame == ResolveInFrameAB.frame_a then
t_b_0 = -Frames.resolve1(frame_a.R, torque);
frame_b.t = Frames.resolve2(frame_b.R, t_b_0);
elseif resolveInFrame == ResolveInFrameAB.frame_b then
t_b_0 = -Frames.resolve1(frame_b.R, torque);
frame_b.t = -torque;
elseif resolveInFrame == ResolveInFrameAB.world then
t_b_0 = -torque;
frame_b.t = Frames.resolve2(frame_b.R, t_b_0);
elseif resolveInFrame == ResolveInFrameAB.frame_resolve then
t_b_0 = -Frames.resolve1(frame_resolve.R, torque);
frame_b.t = Frames.resolve2(frame_b.R, t_b_0);
else
assert(false, "Wrong value for parameter resolveInFrame");
t_b_0 = zeros(3);
frame_b.t = zeros(3);
end if;
if resolveInFrame == ResolveInFrameAB.frame_a then
t_b_0 = -Frames.resolve1(frame_a.R, torque);
frame_b.t = Frames.resolve2(frame_b.R, t_b_0);
elseif resolveInFrame == ResolveInFrameAB.frame_b then
t_b_0 = -Frames.resolve1(frame_b.R, torque);
frame_b.t = -torque;
elseif resolveInFrame == ResolveInFrameAB.world then
t_b_0 = -torque;
frame_b.t = Frames.resolve2(frame_b.R, t_b_0);
elseif resolveInFrame == ResolveInFrameAB.frame_resolve then
t_b_0 = -Frames.resolve1(frame_resolve.R, torque);
frame_b.t = Frames.resolve2(frame_b.R, t_b_0);
else
assert(false, "Wrong value for parameter resolveInFrame");
t_b_0 = zeros(3);
frame_b.t = zeros(3);
end if;

// torque balance
zeros(3) = frame_a.t + Frames.resolve2(frame_a.R, t_b_0);
annotation (
Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{
100,100}}), graphics={
Expand All @@ -69,28 +61,24 @@
startAngle=40,
endAngle=80,
closure=EllipseClosure.None),
Text(
extent={{-80,90},{100,60}},
textColor={192,192,192},
textString="resolve"),
Text(
extent={{-150,-30},{150,-70}},
textString="%name",
textColor={0,0,255}),
Polygon(
points={{92,0},{82,36},{60,22},{92,0}},
fillPattern=FillPattern.Solid),
Line(
points={{40,100},{80,20}},
color={95,95,95},
pattern=LinePattern.Dot),
Polygon(
points={{-92,0},{-82,36},{-60,22},{-92,0}},
fillPattern=FillPattern.Solid),
Line(
points={{-60,100},{40,100}},
points={{-60,-100},{80,-100},{80,20}},
color={95,95,95},
pattern=LinePattern.Dot)}),
pattern=LinePattern.Dot),
Text(
extent={{-100,-40},{80,-70}},
textColor={192,192,192},
textString="resolve"),
Text(
extent={{-150,100},{150,60}},
textString="%name",
textColor={0,0,255})}),
Documentation(info="<html>
<p>
The <strong>3</strong> signals of the <strong>torque</strong> connector are interpreted
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
model BasicWorldForce
"External force acting at frame_b, defined by 3 input signals"
import Modelica.Mechanics.MultiBody.Types.ResolveInFrameB;
extends Interfaces.PartialOneFrame_b;
extends Interfaces.PartialTwoFrames(
break frame_a);

Check failure on line 6 in Modelica/Mechanics/MultiBody/Forces/Internal/BasicWorldForce.mo

View workflow job for this annotation

GitHub Actions / syntax_checks

expected identifier but received `break`
Interfaces.Frame_resolve frame_resolve
"The input signals are optionally resolved in this frame"
annotation (Placement(transformation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ within Modelica.Mechanics.MultiBody.Forces.Internal;
model BasicWorldTorque
"External torque acting at frame_b, defined by 3 input signals"
import Modelica.Mechanics.MultiBody.Types.ResolveInFrameB;
extends Interfaces.PartialOneFrame_b;
extends Interfaces.PartialTwoFrames(
break frame_a);
Interfaces.Frame_resolve frame_resolve
"The input signals are optionally resolved in this frame"
annotation (Placement(transformation(
Expand Down
13 changes: 5 additions & 8 deletions Modelica/Mechanics/MultiBody/Forces/WorldForce.mo
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
within Modelica.Mechanics.MultiBody.Forces;
model WorldForce
"External force acting at frame_b, defined by 3 input signals and resolved in frame world, frame_b or frame_resolve"
extends Interfaces.PartialTwoFramesResolve(
break frame_a,

Check failure on line 5 in Modelica/Mechanics/MultiBody/Forces/WorldForce.mo

View workflow job for this annotation

GitHub Actions / syntax_checks

expected identifier but received `break`
break frame_resolve);
extends Interfaces.PartialFrameResolveConditional(
final enableFrameResolve = resolveInFrame==Modelica.Mechanics.MultiBody.Types.ResolveInFrameB.frame_resolve);

extends Interfaces.PartialOneFrame_b;
Interfaces.Frame_resolve frame_resolve if
resolveInFrame == Modelica.Mechanics.MultiBody.Types.ResolveInFrameB.frame_resolve
"The input signals are optionally resolved in this frame"
annotation (Placement(transformation(
origin={0,-100},
extent={{-16,-16},{16,16}},
rotation=270)));
Modelica.Blocks.Interfaces.RealInput force[3](each final quantity="Force", each final unit="N")
"x-, y-, z-coordinates of force resolved in frame defined by resolveInFrame"
annotation (Placement(transformation(extent={{-140,-20},{-100,20}})));
Expand Down
Loading