diff --git a/_2D/package.mo b/BondGraph/_2D/package.mo similarity index 74% rename from _2D/package.mo rename to BondGraph/_2D/package.mo index 282b90b..b623f0c 100644 --- a/_2D/package.mo +++ b/BondGraph/_2D/package.mo @@ -7,46 +7,57 @@ package _2D Icon(graphics = {Rectangle(lineColor = {0, 85, 0}, fillColor = {0, 85, 0},fillPattern = FillPattern.Solid, extent = {{-60, 60}, {60, -60}})})); end BondPort; - model J1 "Bond graph 2D 1-junction (common flow, efforts sum to zero)" - parameter Integer N(min=1) = 2 "# of power ports"; - parameter Real s[N] = fill(1.0, N) - "Bond orientation signs used in the effort balance"; - BondPort P[N] "Power ports" annotation( + model J1 "Bond graph 1-junction (common flow, efforts sum to zero)" + parameter Integer N(min=1) = 2 "# of power ports"; + parameter Real s[N] = fill(1.0, N) "Bond orientation signs used in the effort balance"; + + BondPort P[N] "Power ports" + annotation( Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(extent = {{-10, -10}, {10, 10}}))); - Real f[2]; + Modelica.Blocks.Interfaces.RealVectorOutput f[2] "Flow in junction" + annotation( + Placement(transformation(origin = {-100, -6}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {60, -60}, extent = {{-10, -10}, {10, 10}}))); equation // Efforts sum to zero, with signs from bond directions for j in 1:2 loop sum(s[i] * P[i].e[j] for i in 1:N) = 0; end for; - + // Flows are all equal for i in 2:N loop P[i].f = P[i-1].f; end for; - f = P[1].f; + + f = -1 * P[1].f * s[1]; + annotation( Icon(graphics = {Text(extent = {{-100, 100}, {100, -100}}, textString = "1", textStyle = {TextStyle.Bold, TextStyle.UnderLine}), Text(origin = {50, 80}, textColor = {0, 0, 255}, extent = {{-50, 20}, {50, -20}}, textString = "%name")})); end J1; - model J0 "Bond graph 2D 0-junction (common effort, flows sum to zero)" - parameter Integer N(min=1) = 2 "# of power ports"; - parameter Real s[N] = fill(1.0, N) - "Bond orientation signs used in the effort balance"; - BondPort P[N] "Power ports" annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(extent = {{-10, -10}, {10, 10}}))); - Real e[2]; - equation - // Flows sum to zero, with signs from bond directions - for j in 1:2 loop - sum(s[i] * P[i].f[j] for i in 1:N) = 0; - end for; - - // Efforts are all equal - for i in 2:N loop - P[i].e = P[1].e; - end for; - e = P[1].e; + model J0 "Bond graph 1-junction (common effort, flows sum to zero)" + parameter Integer N(min=1) = 2 "# of power ports"; + parameter Real s[N] = fill(1.0, N) "Bond orientation signs used in the effort balance"; + + BondPort P[N] "Power ports" + annotation( + Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(extent = {{-10, -10}, {10, 10}}))); + + Modelica.Blocks.Interfaces.RealVectorOutput e[2] "Flow in junction" + annotation( + Placement(transformation(origin = {-100, -6}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {60, -60}, extent = {{-10, -10}, {10, 10}}))); + equation + // Flows sum to zero, with signs from bond directions + for j in 1:2 loop + sum(s[i] * P[i].f[j] for i in 1:N) = 0; + end for; + + // Efforts are all equal + for i in 2:N loop + P[i].e = P[i-1].e; + end for; + + e = P[1].e; + annotation( Icon(graphics = {Text(extent = {{-100, 100}, {100, -100}}, textString = "0", textStyle = {TextStyle.Bold, TextStyle.UnderLine}), Text(origin = {50, 80}, textColor = {0, 0, 255}, extent = {{-50, 20}, {50, -20}}, textString = "%name")}), Diagram(graphics)); @@ -206,62 +217,6 @@ package _2D Icon(graphics = {Text(extent = {{-60, 100}, {60, -100}}, textString = "mGY", textStyle = {TextStyle.Bold, TextStyle.UnderLine}), Text(origin = {50, 80}, textColor = {0, 0, 255}, extent = {{-50, 20}, {50, -20}}, textString = "%name")})); end mGY; - package TransRotUtils - - model mTFrot2lin - _1D.BondPort pR annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {-80, 0}, extent = {{-10, -10}, {10, 10}}))); - BondPort pT annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {80, 0}, extent = {{-10, -10}, {10, 10}}))); - parameter Real r_body[2] = {1,0}; - protected - Real B[2]; - equation - B = {-r_body[2], r_body[1]}; - pT.f = B * pR.f; - pR.e = B[1]*pT.e[1] + B[2]*pT.e[2]; - annotation( - Icon(graphics = {Text(extent = {{-70, 100}, {70, -100}}, textString = "rlTF", textStyle = {TextStyle.Bold, TextStyle.UnderLine})})); - end mTFrot2lin; - - model rTF - BondPort p1 "Port 1" annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {-80, 0}, extent = {{-10, -10}, {10, 10}}))); - BondPort p2 "Port 2" annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {80, 0}, extent = {{-10, -10}, {10, 10}}))); - Modelica.Blocks.Interfaces.RealInput phi "angle" annotation( - Placement(transformation(origin = {-8, -64}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {0, -78}, extent = {{-8, -8}, {8, 8}}, rotation = 90))); - protected - Real R[2,2]; - equation - R = [cos(phi), -sin(phi); - sin(phi), cos(phi)]; - p1.e = R * p2.e; - transpose(R) * p1.f = p2.f; - annotation( - Diagram(graphics), - Icon(graphics = {Text(extent = {{-60, 100}, {60, -100}}, textString = "rTF", textStyle = {TextStyle.Bold, TextStyle.UnderLine}) })); - end rTF; - - end TransRotUtils; - - model fsensor2d - BondPort p annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {-52, 0}, extent = {{-10, -10}, {10, 10}}))); - Modelica.Blocks.Interfaces.RealOutput f0 "Flow output" annotation( - Placement(transformation(origin = {-8, -64}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {54, 20}, extent = {{-8, -8}, {8, 8}}))); - Modelica.Blocks.Interfaces.RealOutput f1 "Flow output" annotation( - Placement(transformation(origin = {-8, -64}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {54, -20}, extent = {{-8, -8}, {8, 8}}))); - equation - // Ideal flow sensor in bond-graph form: zero effort loading. - p.e = {0,0}; - f0 = p.f[1]; - f1 = p.f[2]; - annotation( - Icon(graphics = {Text(origin = {-10, 0}, extent = {{-50, 60}, {50, -60}}, textString = "f", textStyle = {TextStyle.Italic}), Ellipse(origin = {-2, 0}, lineThickness = 5, extent = {{-50, 50}, {50, -50}})})); - end fsensor2d; - - annotation( Icon(graphics = {Text(origin = {50, 0}, extent = {{-50, 100}, {50, -100}}, textString = "R", textStyle = {TextStyle.Bold}), Line(origin = {-45.22, 20.19}, points = {{-58.7774, -20.1934}, {21.2226, -20.1934}, {-38.7774, 19.8066}}, thickness = 5), Line(origin = {-9.81, -8.19}, points = {{-10.1934, 48.1934}, {-10.1934, -31.8066}}, thickness = 5), Line(origin = {-78, 16}, points = {{-26, 0}, {30, 0}}, thickness = 5)}), uses(Modelica(version = "4.1.0")), diff --git a/_2D/package.order b/BondGraph/_2D/package.order similarity index 77% rename from _2D/package.order rename to BondGraph/_2D/package.order index b105b6b..c07213a 100644 --- a/_2D/package.order +++ b/BondGraph/_2D/package.order @@ -14,5 +14,3 @@ mSe mSf mTF mGY -TransRotUtils -fsensor2d diff --git a/BondGraph/package.mo b/BondGraph/package.mo index 58d62f2..30e72c9 100644 --- a/BondGraph/package.mo +++ b/BondGraph/package.mo @@ -9,32 +9,31 @@ package BondGraph Icon(graphics = {Rectangle(lineColor = {0, 0, 127}, fillColor = {0, 0, 127},fillPattern = FillPattern.Solid, extent = {{-60, 60}, {60, -60}})})); end BondPort; - model J1 "Bond graph 1-junction (common flow, efforts sum to zero)" - parameter Integer N(min=1) = 2 "# of power ports"; - parameter Real s[N] = fill(1.0, N) "Bond orientation signs used in the effort balance"; - - BondPort P[N] "Power ports" - annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(extent = {{-10, -10}, {10, 10}}))); - - Modelica.Blocks.Interfaces.RealOutput f "Flow in junction" - annotation( - Placement(transformation(origin = {-100, -6}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {60, -60}, extent = {{-10, -10}, {10, 10}}))); - equation - // Efforts sum to zero, with signs from bond directions - sum(s[i] * P[i].e for i in 1:N) = 0; - - // Flows are all equal - for i in 2:N loop - P[i].f = P[i-1].f; - end for; - - f = P[1].f * s[1]; - - annotation( - Icon(graphics = {Text(extent = {{-100, 100}, {100, -100}}, textString = "1"), Text(origin = {50, 80}, textColor = {0, 0, 255}, extent = {{-50, 20}, {50, -20}}, textString = "%name")}), - Diagram(graphics)); - end J1; + model J1 "Bond graph 1-junction (common flow, efforts sum to zero)" + parameter Integer N(min=1) = 2 "# of power ports"; + parameter Real s[N] = fill(1.0, N) "Bond orientation signs used in the effort balance"; + + BondPort P[N] "Power ports" + annotation( + Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(extent = {{-10, -10}, {10, 10}}))); + Modelica.Blocks.Interfaces.RealOutput f "Flow in junction" + annotation( + Placement(transformation(origin = {-100, -6}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {60, -60}, extent = {{-10, -10}, {10, 10}}))); + equation + // Efforts sum to zero, with signs from bond directions + sum(s[i] * P[i].e for i in 1:N) = 0; + + // Flows are all equal + for i in 2:N loop + P[i].f = P[i-1].f; + end for; + + f = -1 * P[1].f * s[1]; + + annotation( + Icon(graphics = {Text(extent = {{-100, 100}, {100, -100}}, textString = "1"), Text(origin = {50, 80}, textColor = {0, 0, 255}, extent = {{-50, 20}, {50, -20}}, textString = "%name")}), + Diagram(graphics)); + end J1; model J0 "Bond graph 1-junction (common effort, flows sum to zero)" parameter Integer N(min=1) = 2 "# of power ports"; @@ -53,7 +52,7 @@ package BondGraph // Efforts are all equal for i in 2:N loop - P[i].f = P[i-1].f; + P[i].e = P[i-1].e; end for; e = P[1].e * s[1]; @@ -221,4 +220,4 @@ package BondGraph Diagram(graphics), Icon(graphics = {Line(origin = {-45.22, 20.19}, points = {{-50.7774, -20.1934}, {21.2226, -20.1934}, {-38.7774, 19.8066}}, thickness = 5), Line(origin = {-9.81, -8.19}, points = {{-10.1934, 48.1934}, {-10.1934, -31.8066}}, thickness = 5), Line(origin = {156.78, 20.19}, points = {{-60.7774, -20.1934}, {-134.777, -20.1934}, {-76.7774, 19.8066}}, thickness = 5), Line(origin = {28.19, -8.19}, points = {{-10.1934, 48.1934}, {-10.1934, -31.8066}}, thickness = 5), Line(origin = {66, 12}, points = {{-26, 0}, {30, 0}}, thickness = 5)}), uses(Modelica(version = "4.1.0"))); -end BondGraph; +end BondGraph; \ No newline at end of file diff --git a/BondGraph/package.order b/BondGraph/package.order index abc4b4a..e8d70b0 100644 --- a/BondGraph/package.order +++ b/BondGraph/package.order @@ -1 +1,17 @@ -_1D +BondPort +J1 +J0 +OnePortPassive +OnePortEnergetic +C +I +R +Se +Sf +TF +GY +mSe +mSf +mTF +mGY +_2D diff --git a/_3D/package.mo b/_3D/package.mo deleted file mode 100644 index 6b24c73..0000000 --- a/_3D/package.mo +++ /dev/null @@ -1,275 +0,0 @@ -within BondGraph; - -package _3D - connector BondPort "Bond graph 3D multibond power port" - Real e[3] "Effort vector"; - flow Real f[3] "Flow vector"; - annotation( - Icon(graphics = {Rectangle(lineColor = {170, 0, 0}, fillColor = {170, 0, 0}, fillPattern = FillPattern.Solid, extent = {{-60, 60}, {60, -60}})})); - end BondPort; - - model J1 "Bond graph 3D 1-junction (common flow, efforts sum to zero)" - parameter Integer N(min = 1) = 2 "# of power ports"; - parameter Real s[N] = fill(1.0, N) "Bond orientation signs used in the effort balance"; - BondPort P[N] "Power ports" annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(extent = {{-10, -10}, {10, 10}}))); - Real f[3]; - equation -// Efforts sum to zero, with signs from bond directions - for j in 1:3 loop - sum(s[i]*P[i].e[j] for i in 1:N) = 0; - end for; -// Flows are all equal - for i in 2:N loop - P[i].f = P[i - 1].f; - end for; - f = P[1].f; - annotation( - Icon(graphics = {Text(extent = {{-100, 100}, {100, -100}}, textString = "1", textStyle = {TextStyle.Bold, TextStyle.UnderLine, TextStyle.Italic}), Text(origin = {50, 80}, textColor = {0, 0, 255}, extent = {{-50, 20}, {50, -20}}, textString = "%name", textStyle = {TextStyle.Italic})})); - end J1; - - model J0 "Bond graph 3D 0-junction (common effort, flows sum to zero)" - parameter Integer N(min = 1) = 2 "# of power ports"; - parameter Real s[N] = fill(1.0, N) "Bond orientation signs used in the effort balance"; - BondPort P[N] "Power ports" annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(extent = {{-10, -10}, {10, 10}}))); - Real e[3]; - equation -// Flows sum to zero, with signs from bond directions - for j in 1:3 loop - sum(s[i]*P[i].f[j] for i in 1:N) = 0; - end for; -// Efforts are all equal - for i in 2:N loop - P[i].e = P[1].e; - end for; - e = P[1].e; - annotation( - Icon(graphics = {Text(extent = {{-100, 100}, {100, -100}}, textString = "0", textStyle = {TextStyle.Bold, TextStyle.UnderLine, TextStyle.Italic}), Text(origin = {50, 80}, textColor = {0, 0, 255}, extent = {{-50, 20}, {50, -20}}, textString = "%name", textStyle = {TextStyle.Italic})}), - Diagram(graphics)); - end J0; - - partial model OnePortPassive "One-port passive 3D multibond element" - BondPort p "Generic power port" annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(extent = {{-10, -10}, {10, 10}}))); - end OnePortPassive; - - partial model OnePortEnergetic "One-port 3D multibond storage element" - extends OnePortPassive annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {0, 80}, extent = {{-10, -10}, {10, 10}}))); - Real state[3] "Conserved quantity"; - end OnePortEnergetic; - - model C "Bond graph 3D C element" - extends OnePortEnergetic(state(start = q0, each fixed = true)); - parameter Real c[3, 3] = [1, 0, 0; 0, 1, 0; 0, 0, 1] "Capacitance matrix inverse denominator form"; - parameter Real q0[3] = {0, 0, 0} "Initial stored quantity (charge)"; - equation - der(state) = p.f; - c*p.e = state; - annotation( - Icon(graphics = {Text(extent = {{-100, 100}, {100, -100}}, textString = "C", textStyle = {TextStyle.Bold, TextStyle.UnderLine, TextStyle.Italic}), Text(origin = {50, 80}, textColor = {0, 0, 255}, extent = {{-50, 20}, {50, -20}}, textString = "%name", textStyle = {TextStyle.Italic})}), - Diagram(graphics)); - end C; - - model I "Bond graph 3D I element" - extends OnePortEnergetic(state(start = p0, each fixed = true)); - parameter Real I[3, 3] = [1, 0, 0; 0, 1, 0; 0, 0, 1] "Inertance / inductance / mass matrix"; - parameter Real p0[3] = {0, 0, 0} "Initial stored quantity (momentum / flux)"; - equation - der(state) = p.e; - I*p.f = state; - annotation( - Icon(graphics = {Text(extent = {{-100, 100}, {100, -100}}, textString = "I", textStyle = {TextStyle.Bold, TextStyle.UnderLine, TextStyle.Italic}), Text(origin = {50, 80}, textColor = {0, 0, 255}, extent = {{-50, 20}, {50, -20}}, textString = "%name", textStyle = {TextStyle.Italic})}), - Diagram(graphics)); - end I; - - model R "Bond graph 3D resistor" - extends OnePortPassive; - parameter Real R[3, 3] = [1, 0, 0; 0, 1, 0; 0, 0, 1] "Resistance matrix"; - equation - p.e = R*p.f; - annotation( - Icon(graphics = {Text(extent = {{-100, 100}, {100, -100}}, textString = "R", textStyle = {TextStyle.Bold, TextStyle.UnderLine, TextStyle.Italic}), Text(origin = {50, 80}, textColor = {0, 0, 255}, extent = {{-50, 20}, {50, -20}}, textString = "%name", textStyle = {TextStyle.Italic})}), - Diagram(graphics)); - end R; - - model Se "Effort source" - BondPort p annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {80, 0}, extent = {{-10, -10}, {10, 10}}))); - parameter Real e0[3] "Imposed effort"; - equation - p.e = e0; - annotation( - Icon(graphics = {Text(origin = {-20, 0}, extent = {{-80, 100}, {80, -100}}, textString = "Se", textStyle = {TextStyle.Bold, TextStyle.UnderLine, TextStyle.Italic}), Text(origin = {50, 80}, textColor = {0, 0, 255}, extent = {{-50, 20}, {50, -20}}, textString = "%name", textStyle = {TextStyle.Italic})}), - Diagram(graphics)); - end Se; - - model Sf "Flow source" - BondPort p annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {80, 0}, extent = {{-10, -10}, {10, 10}}))); - parameter Real f0[3] "Imposed flow"; - equation - p.f = f0; - annotation( - Icon(graphics = {Text(origin = {-20, 0}, extent = {{-80, 100}, {80, -100}}, textString = "Sf", textStyle = {TextStyle.Bold, TextStyle.UnderLine, TextStyle.Italic}), Text(origin = {50, 80}, textColor = {0, 0, 255}, extent = {{-50, 20}, {50, -20}}, textString = "%name", textStyle = {TextStyle.Italic})}), - Diagram(graphics)); - end Sf; - - model TF "Bond graph 3D transformer" - BondPort p1 "Port 1" annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {-80, 0}, extent = {{-10, -10}, {10, 10}}))); - BondPort p2 "Port 2" annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {80, 0}, extent = {{-10, -10}, {10, 10}}))); - parameter Real n[3, 3] = [1, 0, 0; 0, 1, 0; 0, 0, 1] "Transformer ratio matrix"; - equation - p1.e = n*p2.e; - transpose(n)*p1.f = p2.f; - annotation( - Icon(graphics = {Text(extent = {{-80, 100}, {80, -100}}, textString = "TF", textStyle = {TextStyle.Bold, TextStyle.UnderLine, TextStyle.Italic}), Text(origin = {50, 80}, textColor = {0, 0, 255}, extent = {{-50, 20}, {50, -20}}, textString = "%name", textStyle = {TextStyle.Italic})}), - Diagram(graphics)); - end TF; - - model GY "Bond graph 3D gyrator" - BondPort p1 "Port 1" annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {-80, 0}, extent = {{-10, -10}, {10, 10}}))); - BondPort p2 "Port 2" annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {80, 0}, extent = {{-10, -10}, {10, 10}}))); - parameter Real r[3, 3] = [1, 0, 0; 0, 1, 0; 0, 0, 1] "Gyrator modulus matrix"; - equation - p1.e = r*p2.f; - p2.e = transpose(r)*p1.f; - annotation( - Icon(graphics = {Text(extent = {{-80, 100}, {80, -100}}, textString = "GY", textStyle = {TextStyle.Bold, TextStyle.UnderLine, TextStyle.Italic}), Text(origin = {50, 80}, textColor = {0, 0, 255}, extent = {{-50, 20}, {50, -20}}, textString = "%name", textStyle = {TextStyle.Italic})}), - Diagram(graphics)); - end GY; - - model mSe "Bond graph modulated effort source" - BondPort p annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {80, 0}, extent = {{-10, -10}, {10, 10}}))); - Modelica.Blocks.Interfaces.RealInput e0 "Imposed effort" annotation( - Placement(transformation(origin = {-8, -64}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {-30, -78}, extent = {{-8, -8}, {8, 8}}, rotation = 90))); - Modelica.Blocks.Interfaces.RealInput e1 "Imposed effort" annotation( - Placement(transformation(origin = {-8, -64}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {0, -78}, extent = {{-8, -8}, {8, 8}}, rotation = 90))); - Modelica.Blocks.Interfaces.RealInput e2 "Imposed effort" annotation( - Placement(transformation(origin = {-8, -64}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {30, -78}, extent = {{-8, -8}, {8, 8}}, rotation = 90))); - equation - p.e = {e0, e1, e2}; - annotation( - Icon(graphics = {Text(origin = {-20, 0}, extent = {{-80, 100}, {80, -100}}, textString = "mSe", textStyle = {TextStyle.Bold, TextStyle.UnderLine, TextStyle.Italic}), Text(origin = {50, 80}, textColor = {0, 0, 255}, extent = {{-50, 20}, {50, -20}}, textString = "%name", textStyle = {TextStyle.Italic})}), - Diagram(graphics)); - end mSe; - - model mSf "Bond graph modulated flow source" - BondPort p annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {80, 0}, extent = {{-10, -10}, {10, 10}}))); - Modelica.Blocks.Interfaces.RealInput f0 "Imposed flow" annotation( - Placement(transformation(origin = {-8, -64}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {-30, -78}, extent = {{-8, -8}, {8, 8}}, rotation = 90))); - Modelica.Blocks.Interfaces.RealInput f1 "Imposed flow" annotation( - Placement(transformation(origin = {-8, -64}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {0, -78}, extent = {{-8, -8}, {8, 8}}, rotation = 90))); - Modelica.Blocks.Interfaces.RealInput f2 "Imposed flow" annotation( - Placement(transformation(origin = {-8, -64}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {30, -78}, extent = {{-8, -8}, {8, 8}}, rotation = 90))); - equation - p.f = {f0, f1, f2}; - annotation( - Icon(graphics = {Text(origin = {-20, 0}, extent = {{-80, 100}, {80, -100}}, textString = "mSf", textStyle = {TextStyle.Bold, TextStyle.UnderLine, TextStyle.Italic}), Text(origin = {50, 80}, textColor = {0, 0, 255}, extent = {{-50, 20}, {50, -20}}, textString = "%name", textStyle = {TextStyle.Italic})}), - Diagram(graphics)); - end mSf; - - model mTF "Bond graph modulated transformer" - BondPort p1 "Port 1" annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {-80, 0}, extent = {{-10, -10}, {10, 10}}))); - BondPort p2 "Port 2" annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {80, 0}, extent = {{-10, -10}, {10, 10}}))); - Modelica.Blocks.Interfaces.RealInput m[3, 3] "Modulation" annotation( - Placement(transformation(origin = {-8, -64}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {0, -78}, extent = {{-8, -8}, {8, 8}}, rotation = 90))); - equation - p1.e = m*p2.e; - transpose(m)*p1.f = p2.f; - annotation( - Diagram(graphics), - Icon(graphics = {Text(extent = {{-60, 100}, {60, -100}}, textString = "mTF", textStyle = {TextStyle.Bold, TextStyle.UnderLine, TextStyle.Italic}), Text(origin = {50, 80}, textColor = {0, 0, 255}, extent = {{-50, 20}, {50, -20}}, textString = "%name", textStyle = {TextStyle.Italic})})); - end mTF; - - model mGY "Bond graph modulated gyrator" - BondPort p1 "Port 1" annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {-80, 0}, extent = {{-10, -10}, {10, 10}}))); - BondPort p2 "Port 2" annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {80, 0}, extent = {{-10, -10}, {10, 10}}))); - Modelica.Blocks.Interfaces.RealInput m[3, 3] "Modulation" annotation( - Placement(transformation(origin = {-8, -64}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {0, -78}, extent = {{-8, -8}, {8, 8}}, rotation = 90))); - equation - p1.e = m*p2.f; - p2.e = transpose(m)*p1.f; - annotation( - Diagram(graphics), - Icon(graphics = {Text(extent = {{-60, 100}, {60, -100}}, textString = "mGY", textStyle = {TextStyle.Bold, TextStyle.UnderLine, TextStyle.Italic}), Text(origin = {50, 80}, textColor = {0, 0, 255}, extent = {{-50, 20}, {50, -20}}, textString = "%name", textStyle = {TextStyle.Italic})})); - end mGY; - - package TransRotUtils - model mTFrot3lin - BondPort pR annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {-80, 0}, extent = {{-10, -10}, {10, 10}}))); - BondPort pT annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {80, 0}, extent = {{-10, -10}, {10, 10}}))); - parameter Real r_body[3] = {1, 0, 0} "Vector from rotational reference to translational point (body frame)"; - protected - Real S[3, 3]; - equation -// Skew matrix such that S*x = r_body x x - S = [0, -r_body[3], r_body[2]; r_body[3], 0, -r_body[1]; -r_body[2], r_body[1], 0]; -// v = w x r_body = -S*w - pT.f = transpose(S)*pR.f; -// tau = r_body x F = S*F - pR.e = S*pT.e; - annotation( - Icon(graphics = {Text(extent = {{-70, 100}, {70, -100}}, textString = "rlTF", textStyle = {TextStyle.Bold, TextStyle.UnderLine, TextStyle.Italic})})); - end mTFrot3lin; - - model rTF3D - BondPort p1 "Port 1" annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {-80, 0}, extent = {{-10, -10}, {10, 10}}))); - BondPort p2 "Port 2" annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {80, 0}, extent = {{-10, -10}, {10, 10}}))); - Modelica.Blocks.Interfaces.RealInput phi "roll angle" annotation( - Placement(transformation(origin = {-8, -64}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {-30, -78}, extent = {{-8, -8}, {8, 8}}, rotation = 90))); - Modelica.Blocks.Interfaces.RealInput theta "pitch angle" annotation( - Placement(transformation(origin = {-8, -64}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {0, -78}, extent = {{-8, -8}, {8, 8}}, rotation = 90))); - Modelica.Blocks.Interfaces.RealInput psi "yaw angle" annotation( - Placement(transformation(origin = {-8, -64}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {30, -78}, extent = {{-8, -8}, {8, 8}}, rotation = 90))); - protected - Real R[3, 3]; - equation -// ZYX rotation matrix from body to inertial frame. - R = [cos(psi)*cos(theta), cos(psi)*sin(theta)*sin(phi) - sin(psi)*cos(phi), cos(psi)*sin(theta)*cos(phi) + sin(psi)*sin(phi); sin(psi)*cos(theta), sin(psi)*sin(theta)*sin(phi) + cos(psi)*cos(phi), sin(psi)*sin(theta)*cos(phi) - cos(psi)*sin(phi); -sin(theta), cos(theta)*sin(phi), cos(theta)*cos(phi)]; - p1.e = R*p2.e; - transpose(R)*p1.f = p2.f; - annotation( - Diagram(graphics), - Icon(graphics = {Text(extent = {{-60, 100}, {60, -100}}, textString = "rTF", textStyle = {TextStyle.Bold, TextStyle.Italic, TextStyle.UnderLine})})); - end rTF3D; - end TransRotUtils; - - model fsensor3d - BondPort p annotation( - Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {-52, 0}, extent = {{-10, -10}, {10, 10}}))); - Modelica.Blocks.Interfaces.RealOutput f0 "Flow output" annotation( - Placement(transformation(origin = {-8, -64}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {54, 26}, extent = {{-8, -8}, {8, 8}}))); - Modelica.Blocks.Interfaces.RealOutput f1 "Flow output" annotation( - Placement(transformation(origin = {-8, -64}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {54, 0}, extent = {{-8, -8}, {8, 8}}))); - Modelica.Blocks.Interfaces.RealOutput f2 "Flow output" annotation( - Placement(transformation(origin = {-8, -64}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {54, -26}, extent = {{-8, -8}, {8, 8}}))); - equation -// Ideal flow sensor in bond-graph form: zero effort loading. - p.e = {0, 0, 0}; - f0 = p.f[1]; - f1 = p.f[2]; - f2 = p.f[3]; - annotation( - Icon(graphics = {Text(origin = {-10, 0}, extent = {{-50, 60}, {50, -60}}, textString = "f", textStyle = {TextStyle.Italic}), Ellipse(origin = {-2, 0}, lineThickness = 5, extent = {{-50, 50}, {50, -50}})})); - end fsensor3d; - annotation( - Icon(graphics = {Text(origin = {50, 0}, extent = {{-50, 100}, {50, -100}}, textString = "R", textStyle = {TextStyle.Bold, TextStyle.Italic}), Line(origin = {-45.22, 20.19}, points = {{-58.7774, -20.1934}, {21.2226, -20.1934}, {-38.7774, 19.8066}}, thickness = 5), Line(origin = {-9.81, -8.19}, points = {{-10.1934, 48.1934}, {-10.1934, -31.8066}}, thickness = 5), Line(origin = {-78, 16}, points = {{-26, 0}, {30, 0}}, thickness = 5), Line(origin = {-78, -16}, points = {{-26, 0}, {30, 0}}, thickness = 5)}), - uses(Modelica(version = "4.1.0")), - Diagram(graphics)); -end _3D; \ No newline at end of file diff --git a/_3D/package.order b/_3D/package.order deleted file mode 100644 index 4e0fc4f..0000000 --- a/_3D/package.order +++ /dev/null @@ -1,18 +0,0 @@ -BondPort -J1 -J0 -OnePortPassive -OnePortEnergetic -C -I -R -Se -Sf -TF -GY -mSe -mSf -mTF -mGY -TransRotUtils -fsensor3d diff --git a/suggest_junction_signs.py b/suggest_junction_signs.py new file mode 100644 index 0000000..7e34f6d --- /dev/null +++ b/suggest_junction_signs.py @@ -0,0 +1,185 @@ +#!/usr/bin/env python3 +""" +Suggest BondGraph junction s-arrays from connect argument order. + +Rule used: +- connect(a, b) means a is source and b is sink. +- Junction port in first argument => +1 vote +- Junction port in second argument => -1 vote + +This is a heuristic helper. It does not modify files. +""" + +from __future__ import annotations + +import argparse +import re +from dataclasses import dataclass, field +from pathlib import Path +from typing import Dict, List, Optional, Tuple + + +CONNECT_RE = re.compile(r"connect\s*\(\s*([^,]+?)\s*,\s*([^)]+?)\s*\)\s*(?:annotation\s*\(|;)", re.S) +JUNCTION_DECL_RE = re.compile( + r"\b(BondGraph(?:\._2D)?\.J[01])\s+([A-Za-z_]\w*)\s*(\((.*?)\))?\s*annotation\s*\(", + re.S, +) +PORT_RE = re.compile(r"^([A-Za-z_]\w*)\.P\[(\d+)\]$") +N_RE = re.compile(r"\bN\s*=\s*(\d+)") +S_RE = re.compile(r"\bs\s*=\s*\{([^}]*)\}") + + +@dataclass +class Junction: + cls: str + name: str + n: Optional[int] + current_s: Optional[List[str]] + votes: Dict[int, List[int]] = field(default_factory=dict) + + def add_vote(self, port_idx: int, vote: int) -> None: + self.votes.setdefault(port_idx, []).append(vote) + + +def parse_current_s(params: str) -> Optional[List[str]]: + m = S_RE.search(params) + if not m: + return None + return [x.strip() for x in m.group(1).split(",") if x.strip()] + + +def parse_junctions(text: str) -> Dict[str, Junction]: + result: Dict[str, Junction] = {} + for m in JUNCTION_DECL_RE.finditer(text): + cls, name, _, params = m.groups() + params = params or "" + n_m = N_RE.search(params) + n = int(n_m.group(1)) if n_m else None + result[name] = Junction(cls=cls, name=name, n=n, current_s=parse_current_s(params)) + return result + + +def normalize_endpoint(ep: str) -> str: + return re.sub(r"\s+", "", ep) + + +def extract_junction_port(endpoint: str) -> Optional[Tuple[str, int]]: + m = PORT_RE.match(endpoint) + if not m: + return None + return m.group(1), int(m.group(2)) + + +def suggest_sign(votes: List[int]) -> str: + pos = sum(1 for v in votes if v < 0) + neg = sum(1 for v in votes if v > 0) + if pos and neg: + return "?" + if pos: + return "-1" + if neg: + return "+1" + return "0" + + +def fmt_current(j: Junction, idx: int) -> str: + if not j.current_s: + return "n/a" + if idx - 1 < len(j.current_s): + return j.current_s[idx - 1] + return "n/a" + + +def as_int_sign(token: str) -> Optional[int]: + t = token.strip() + if t in {"+1", "1", "1.0"}: + return 1 + if t in {"-1", "-1.0"}: + return -1 + return None + + +def main() -> int: + ap = argparse.ArgumentParser(description=__doc__) + ap.add_argument("modelica_file", type=Path) + ap.add_argument( + "--emit-patch", + action="store_true", + help="Emit patch-style s-array replacements per junction.", + ) + args = ap.parse_args() + + text = args.modelica_file.read_text(encoding="utf-8") + junctions = parse_junctions(text) + + for m in CONNECT_RE.finditer(text): + left, right = normalize_endpoint(m.group(1)), normalize_endpoint(m.group(2)) + + l = extract_junction_port(left) + if l and l[0] in junctions: + junctions[l[0]].add_vote(l[1], +1) + + r = extract_junction_port(right) + if r and r[0] in junctions: + junctions[r[0]].add_vote(r[1], -1) + + print(f"File: {args.modelica_file}") + print("Rule: connect(a,b) => a:-1, b:+1") + print("") + + patch_lines: List[str] = [] + + for name in sorted(junctions): + j = junctions[name] + max_idx = j.n or (max(j.votes) if j.votes else 0) + suggested = [] + conflicts = [] + + for i in range(1, max_idx + 1): + votes = j.votes.get(i, []) + s = suggest_sign(votes) + suggested.append(s) + if s == "?": + conflicts.append(i) + + current_s = "{" + ", ".join(j.current_s) + "}" if j.current_s else "n/a" + sug_s = "{" + ", ".join(suggested) + "}" if suggested else "{}" + print(f"{j.name} ({j.cls}, N={j.n if j.n is not None else 'n/a'})") + print(f" current s: {current_s}") + print(f" suggested s: {sug_s}") + for i in range(1, max_idx + 1): + votes = j.votes.get(i, []) + vote_str = ",".join("+1" if v > 0 else "-1" for v in votes) if votes else "-" + print(f" P[{i}]: current={fmt_current(j, i)} votes={vote_str} -> {suggested[i-1]}") + if conflicts: + conflict_ports = ", ".join(f"P[{i}]" for i in conflicts) + print(f" conflicts: {conflict_ports} (used as both source and sink)") + print("") + + if args.emit_patch and max_idx > 0: + suggested_int = [] + current_int = [] + ok = True + for i in range(1, max_idx + 1): + s = suggested[i - 1] + if s == "?": + ok = False + break + suggested_int.append("1" if s == "+1" else "-1") + current_int.append(fmt_current(j, i)) + if ok: + old_txt = "{" + ", ".join(current_int) + "}" + new_txt = "{" + ", ".join(suggested_int) + "}" + patch_lines.append(f"- {j.name}.s = {old_txt}") + patch_lines.append(f"+ {j.name}.s = {new_txt}") + + if args.emit_patch: + print("Suggested Patch") + for line in patch_lines: + print(line) + + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/test1d.mo b/test1d.mo index 83a342c..b9b52a4 100644 --- a/test1d.mo +++ b/test1d.mo @@ -2,16 +2,23 @@ model test1d BondGraph.J1 j1(N = 3, s = {-1, -1, 1}) annotation( Placement(transformation(extent = {{-10, -10}, {10, 10}}))); BondGraph.R r1(R = 1) annotation( - Placement(transformation(origin = {0, 40}, extent = {{-10, -10}, {10, 10}}))); - BondGraph.R r2(R = 1) annotation( - Placement(transformation(origin = {0, -40}, extent = {{-10, -10}, {10, 10}}))); - BondGraph.Se se(e0 = 1) annotation( + Placement(transformation(origin = {0, 42}, extent = {{-10, -10}, {10, 10}}))); + BondGraph.mSe mSe annotation( Placement(transformation(origin = {-40, 0}, extent = {{-10, -10}, {10, 10}}))); + BondGraph.C c(c = 0.1) annotation( + Placement(transformation(origin = {0, -40}, extent = {{-10, -10}, {10, 10}}))); + Modelica.Blocks.Sources.Step step(startTime = 0.5) annotation( + Placement(transformation(origin = {-70, 0}, extent = {{-10, -10}, {10, 10}}))); equation connect(j1.P[1], r1.p) annotation( - Line(points = {{0, 0}, {0, 40}}, color = {0, 0, 127})); - connect(j1.P[2], r2.p) annotation( - Line(points = {{0, 0}, {0, -40}}, color = {0, 0, 127})); - connect(se.p, j1.P[3]) annotation( + Line(points = {{0, 0}, {0, 42}}, color = {0, 0, 127})); + connect(mSe.p, j1.P[3]) annotation( Line(points = {{-32, 0}, {0, 0}}, color = {0, 0, 127})); + connect(j1.P[2], c.p) annotation( + Line(points = {{0, 0}, {0, -40}}, color = {0, 0, 127})); + connect(step.y, mSe.e0) annotation( + Line(points = {{-58, 0}, {-40, 0}, {-40, -8}}, color = {0, 0, 127})); + +annotation( + uses(Modelica(version = "4.1.0"))); end test1d; \ No newline at end of file diff --git a/test2d.mo b/test2d.mo index 195e88c..58f7f06 100644 --- a/test2d.mo +++ b/test2d.mo @@ -1,99 +1,127 @@ -model test2d - import _1D = BondGraph._1D; - import _2D = BondGraph._2D; - _1D.J1 w_com(N = 4, s = {1, -1, -1, -1}) annotation( - Placement(transformation(origin = {0, 120}, extent = {{-10, -10}, {10, 10}}))); - _2D.TransRotUtils.mTFrot2lin mTFrot2lin(r_body = {0.5, 0}) annotation( - Placement(transformation(origin = {0, 80}, extent = {{-10, -10}, {10, 10}}, rotation = -90))); - _2D.J0 j0(N = 3, s = {1, 1, -1}) annotation( - Placement(transformation(origin = {0, 40}, extent = {{-10, -10}, {10, 10}}))); - _2D.J1 v_p_bff(N = 2, s = {1, 1}) annotation( - Placement(transformation(origin = {-40, 40}, extent = {{-10, -10}, {10, 10}}))); - _2D.J1 v_com_bff(N = 2, s = {-1, -1}) annotation( - Placement(transformation(origin = {40, 40}, extent = {{-10, -10}, {10, 10}}))); - _2D.TransRotUtils.rTF rTF annotation( - Placement(transformation(origin = {40, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 90))); - _1D.fsensor wsensor annotation( - Placement(transformation(origin = {50, 90}, extent = {{-10, -10}, {10, 10}}))); - Modelica.Blocks.Continuous.Integrator w2phi(k = 1) annotation( - Placement(transformation(origin = {90, 90}, extent = {{-10, -10}, {10, 10}}))); - _2D.J1 v_com_in(N = 4, s = {1, -1, 1, 1}) annotation( - Placement(transformation(origin = {40, -40}, extent = {{-10, -10}, {10, 10}}))); - _2D.I mass(I = [1, 0; 0, 1]) annotation( - Placement(transformation(origin = {80, -40}, extent = {{-10, -10}, {10, 10}}))); - BondGraph._2D.Sf ground(f0 = {0, 0}) annotation( - Placement(transformation(origin = {-80, 40}, extent = {{-10, -10}, {10, 10}}))); - BondGraph._1D.I m_inertial(I = 0.001) annotation( - Placement(transformation(origin = {40, 120}, extent = {{-10, -10}, {10, 10}}))); - BondGraph._1D.Sf ground2(f0 = 0) annotation( - Placement(transformation(origin = {-80, 120}, extent = {{-10, -10}, {10, 10}}))); - BondGraph._1D.J0 j1(N = 3, s = {1, -1, -1}) annotation( - Placement(transformation(origin = {-40, 120}, extent = {{-10, -10}, {10, 10}}))); - BondGraph._1D.J1 w_hinge(N = 2, s = {1, -1}) annotation( - Placement(transformation(origin = {-40, 90}, extent = {{-10, -10}, {10, 10}}))); - BondGraph._1D.R hinge_r(R = 0.08) annotation( - Placement(transformation(origin = {-80, 90}, extent = {{-10, -10}, {10, 10}}))); +package test2d + model test2d + BondGraph.J1 w_com(N = 3, s = {1, 1, 1}) annotation( + Placement(transformation(origin = {0, 100}, extent = {{-10, -10}, {10, 10}}))); + BondGraph.I moi(I = 0.01) annotation( + Placement(transformation(origin = {40, 100}, extent = {{-10, -10}, {10, 10}}))); + mTFrot2lin mTFrot2lin1(r_body = {0.5, 0}) annotation( + Placement(transformation(origin = {0, 70}, extent = {{-10, -10}, {10, 10}}, rotation = -90))); + BondGraph._2D.J0 j0(N = 3, s = {-1, -1, 1}) annotation( + Placement(transformation(origin = {0, 40}, extent = {{-10, -10}, {10, 10}}))); + BondGraph._2D.J1 v_com_i(N = 3, s = {-1, 1, -1}) annotation( + Placement(transformation(origin = {40, -20}, extent = {{-10, -10}, {10, 10}}))); + BondGraph._2D.J1 v_P_bff(N = 2, s = {-1, -1}) annotation( + Placement(transformation(origin = {-40, 40}, extent = {{-10, -10}, {10, 10}}))); + BondGraph._2D.J1 v_com_bff(N = 2, s = {1, 1}) annotation( + Placement(transformation(origin = {40, 40}, extent = {{-10, -10}, {10, 10}}))); + BondGraph._2D.Sf hinge(f0 = {0, 0}) annotation( + Placement(transformation(origin = {-78, 40}, extent = {{-10, -10}, {10, 10}}))); + rTF rTF1 annotation( + Placement(transformation(origin = {40, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 90))); + Modelica.Blocks.Continuous.Integrator w2phi(k = 1) annotation( + Placement(transformation(origin = {30, 70}, extent = {{-10, -10}, {10, 10}}))); + BondGraph._2D.I m(I = [1, 0; 0, 1]) annotation( + Placement(transformation(origin = {80, -20}, extent = {{-10, -10}, {10, 10}}))); BondGraph._2D.Se g(e0 = {0, -9.81}) annotation( - Placement(transformation(origin = {2, -40}, extent = {{-10, -10}, {10, 10}}))); - BondGraph._2D.fsensor2d v_inertial annotation( - Placement(transformation(origin = {40, -60}, extent = {{-10, -10}, {10, 10}}, rotation = -90))); - Modelica.Blocks.Continuous.Integrator vx_to_x(k = 1, y_start = -0.5) annotation( - Placement(transformation(origin = {70, -70}, extent = {{-10, -10}, {10, 10}}))); - Modelica.Blocks.Continuous.Integrator vy_to_y(k = 1) annotation( - Placement(transformation(origin = {70, -100}, extent = {{-10, -10}, {10, 10}}))); + Placement(transformation(origin = {0, -20}, extent = {{-10, -10}, {10, 10}}))); + Modelica.Blocks.Continuous.Integrator vx2x(y_start = -0.5) annotation( + Placement(transformation(origin = {70, -50}, extent = {{-10, -10}, {10, 10}}))); + Modelica.Blocks.Continuous.Integrator vy2y(y_start = 0) annotation( + Placement(transformation(origin = {70, -80}, extent = {{-10, -10}, {10, 10}}))); + BondGraph.J0 j1(N = 3, s = {-1, -1, 1}) annotation( + Placement(transformation(origin = {-40, 100}, extent = {{-10, -10}, {10, 10}}))); + BondGraph.Sf hinge2(f0 = 0) annotation( + Placement(transformation(origin = {-78, 100}, extent = {{-10, -10}, {10, 10}}))); + BondGraph.J1 w_hinge(N = 2, s = {-1, 1}) annotation( + Placement(transformation(origin = {-40, 70}, extent = {{-10, -10}, {10, 10}}))); + BondGraph.R r(R = 0.2) annotation( + Placement(transformation(origin = {-70, 70}, extent = {{-10, -10}, {10, 10}}))); vis2d vis2d1 annotation( - Placement(transformation(origin = {150, -6}, extent = {{-10, -10}, {10, 10}}))); -equation - connect(w_com.P[2], mTFrot2lin.pR) annotation( - Line(points = {{0, 120}, {0, 88}}, color = {0, 0, 127}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); - connect(mTFrot2lin.pT, j0.P[1]) annotation( - Line(points = {{0, 72}, {0, 40}}, color = {0, 85, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); - connect(v_com_bff.P[1], j0.P[2]) annotation( - Line(points = {{40, 40}, {0, 40}}, color = {0, 85, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); - connect(j0.P[3], v_p_bff.P[1]) annotation( - Line(origin = {-1, 0}, points = {{0, 40}, {-40, 40}}, color = {0, 85, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); - connect(wsensor.f, w2phi.u) annotation( - Line(points = {{58, 90}, {78, 90}}, color = {0, 0, 127})); - connect(w2phi.y, rTF.phi) annotation( - Line(points = {{102, 90}, {110, 90}, {110, 0}, {48, 0}}, color = {0, 0, 127}, arrow = {Arrow.None, Arrow.Filled})); - connect(v_com_in.P[2], mass.p) annotation( - Line(points = {{40, -40}, {80, -40}}, color = {0, 85, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); - connect(w_com.P[3], wsensor.p) annotation( - Line(points = {{0, 120}, {44, 90}}, color = {0, 0, 127}, pattern = LinePattern.Dash, thickness = 0.75, arrow = {Arrow.None, Arrow.Open}, arrowSize = 6)); - connect(w_com.P[1], m_inertial.p) annotation( - Line(points = {{0, 120}, {40, 120}}, color = {0, 0, 127}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); - connect(ground2.p, j1.P[1]) annotation( - Line(points = {{-72, 120}, {-40, 120}}, color = {0, 0, 127}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); - connect(j1.P[2], w_com.P[4]) annotation( - Line(points = {{-40, 120}, {0, 120}}, color = {0, 0, 127}, thickness = 0.75, arrow = {Arrow.Half, Arrow.None}, arrowSize = 6)); - connect(ground.p, v_p_bff.P[2]) annotation( - Line(points = {{-72, 40}, {-40, 40}}, color = {0, 85, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); + Placement(transformation(origin = {118, -64}, extent = {{-10, -10}, {10, 10}}))); + equation + connect(w_com.f, w2phi.u) annotation( + Line(points = {{6, 94}, {18, 70}}, color = {0, 0, 127})); + connect(w2phi.y, rTF1.phi) annotation( + Line(points = {{41, 70}, {100, 70}, {100, 10}, {48, 10}}, color = {0, 0, 127})); + connect(w_com.P[1], moi.p) annotation( + Line(points = {{0, 100}, {40, 100}}, color = {0, 0, 127}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); + connect(w_com.P[2], mTFrot2lin1.pR) annotation( + Line(points = {{0, 100}, {0, 78}}, color = {0, 0, 127}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); + connect(v_com_bff.P[1], j0.P[1]) annotation( + Line(points = {{40, 40}, {0, 40}}, color = {0, 85, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); + connect(mTFrot2lin1.pT, j0.P[2]) annotation( + Line(points = {{0, 62}, {0, 40}}, color = {0, 85, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); + connect(j0.P[3], v_P_bff.P[1]) annotation( + Line(points = {{0, 40}, {-40, 40}}, color = {0, 85, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); + connect(hinge.p, v_P_bff.P[2]) annotation( + Line(points = {{-70, 40}, {-40, 40}}, color = {0, 85, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); + connect(v_com_bff.P[2], rTF1.p2) annotation( + Line(points = {{40, 40}, {40, 18}}, color = {0, 85, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); + connect(rTF1.p1, v_com_i.P[1]) annotation( + Line(points = {{40, 2}, {40, -20}}, color = {0, 85, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); + connect(g.p, v_com_i.P[3]) annotation( + Line(points = {{8, -20}, {40, -20}}, color = {0, 85, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); + connect(v_com_i.P[2], m.p) annotation( + Line(points = {{40, -20}, {80, -20}}, color = {0, 85, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); + connect(v_com_i.f[1], vx2x.u) annotation( + Line(points = {{46, -26}, {50, -50}, {58, -50}}, color = {0, 0, 127})); + connect(v_com_i.f[2], vy2y.u) annotation( + Line(points = {{46, -26}, {50, -80}, {58, -80}}, color = {0, 0, 127})); + connect(hinge2.p, j1.P[1]) annotation( + Line(points = {{-70, 100}, {-40, 100}}, color = {0, 0, 127}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); connect(j1.P[3], w_hinge.P[1]) annotation( - Line(points = {{-40, 120}, {-40, 90}}, color = {0, 0, 127}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); - connect(w_hinge.P[2], hinge_r.p) annotation( - Line(points = {{-40, 90}, {-80, 90}}, color = {0, 0, 127}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); - connect(g.p, v_com_in.P[3]) annotation( - Line(points = {{10, -40}, {40, -40}}, color = {0, 85, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); - connect(v_com_bff.P[2], rTF.p2) annotation( - Line(points = {{40, 40}, {40, 8}}, color = {0, 85, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); - connect(rTF.p1, v_com_in.P[1]) annotation( - Line(points = {{40, -8}, {40, -40}}, color = {0, 85, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); - connect(v_com_in.P[4], v_inertial.p) annotation( - Line(points = {{40, -40}, {40, -54}}, color = {0, 85, 0}, pattern = LinePattern.Dash, thickness = 0.75, arrow = {Arrow.None, Arrow.Open}, arrowSize = 6)); - connect(v_inertial.f0, vx_to_x.u) annotation( - Line(points = {{42, -66}, {42, -70}, {58, -70}}, color = {0, 0, 127})); - connect(v_inertial.f1, vy_to_y.u) annotation( - Line(points = {{38, -66}, {38, -100}, {58, -100}}, color = {0, 0, 127})); + Line(points = {{-40, 100}, {-40, 70}}, color = {0, 0, 127}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); + connect(w_hinge.P[2], r.p) annotation( + Line(points = {{-40, 70}, {-70, 70}}, color = {0, 0, 127}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); + connect(vy2y.y, vis2d1.y) annotation( + Line(points = {{82, -80}, {94, -80}, {94, -70}, {108, -70}}, color = {0, 0, 127})); + connect(vx2x.y, vis2d1.x) annotation( + Line(points = {{82, -50}, {94, -50}, {94, -64}, {108, -64}}, color = {0, 0, 127})); connect(w2phi.y, vis2d1.phi) annotation( - Line(points = {{102, 90}, {110, 90}, {110, 0}, {141, 0}}, color = {0, 0, 127})); - connect(vx_to_x.y, vis2d1.x) annotation( - Line(points = {{82, -70}, {110, -70}, {110, -6}, {141, -6}}, color = {0, 0, 127})); - connect(vy_to_y.y, vis2d1.y) annotation( - Line(points = {{82, -100}, {118, -100}, {118, -12}, {141, -12}}, color = {0, 0, 127})); + Line(points = {{42, 70}, {100, 70}, {100, -58}, {108, -58}}, color = {0, 0, 127})); + connect(w_com.P[3], j1.P[2]) annotation( + Line(points = {{0, 100}, {-40, 100}}, color = {0, 0, 127}, thickness = 0.75, arrow = {Arrow.None, Arrow.Half}, arrowSize = 6)); annotation( - uses(Modelica(version = "4.1.0")), - experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-06, Interval = 0.02), - Diagram(coordinateSystem(extent = {{-100, 140}, {160, -120}})), - Icon(coordinateSystem(extent = {{-200, -200}, {200, 200}})), - version = ""); -end test2d; \ No newline at end of file + uses(Modelica(version = "4.1.0")), + experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-06, Interval = 0.02), + Diagram(coordinateSystem(extent = {{-100, 120}, {140, -100}})), + Icon(coordinateSystem(extent = {{-200, -200}, {200, 200}})), + version = ""); + end test2d; + + model mTFrot2lin + BondGraph.BondPort pR annotation( + Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {-80, 0}, extent = {{-10, -10}, {10, 10}}))); + BondGraph._2D.BondPort pT annotation( + Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {80, 0}, extent = {{-10, -10}, {10, 10}}))); + parameter Real r_body[2] = {1, 0}; + protected + Real B[2]; + equation + B = {-r_body[2], r_body[1]}; + pT.f = B*pR.f; + pR.e = B[1]*pT.e[1] + B[2]*pT.e[2]; + annotation( + Icon(graphics = {Text(extent = {{-70, 100}, {70, -100}}, textString = "rlTF", textStyle = {TextStyle.Bold, TextStyle.UnderLine})})); + end mTFrot2lin; + + model rTF + BondGraph._2D.BondPort p1 "Port 1" annotation( + Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {-80, 0}, extent = {{-10, -10}, {10, 10}}))); + BondGraph._2D.BondPort p2 "Port 2" annotation( + Placement(transformation(origin = {-44, 18}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {80, 0}, extent = {{-10, -10}, {10, 10}}))); + Modelica.Blocks.Interfaces.RealInput phi "angle" annotation( + Placement(transformation(origin = {-8, -64}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {0, -78}, extent = {{-8, -8}, {8, 8}}, rotation = 90))); + protected + Real R[2, 2]; + equation + R = [cos(phi), -sin(phi); sin(phi), cos(phi)]; + p1.e = R*p2.e; + transpose(R)*p1.f = p2.f; + annotation( + Diagram(graphics), + Icon(graphics = {Text(extent = {{-60, 100}, {60, -100}}, textString = "rTF", textStyle = {TextStyle.Bold, TextStyle.UnderLine})})); + end rTF; + annotation( + uses(Modelica(version = "4.1.0"))); +end test2d; diff --git a/test3d.mo b/test3d.mo deleted file mode 100644 index e6cf210..0000000 --- a/test3d.mo +++ /dev/null @@ -1,158 +0,0 @@ -model test3d - import _3D = BondGraph._3D; - - // --------------------------------------------------------------------------- - // Parameters - // --------------------------------------------------------------------------- - parameter Real J[3,3] = [0.05, 0, 0; - 0, 0.06, 0; - 0, 0, 0.02] "Body inertia tensor in body frame"; - parameter Real m[3,3] = [1, 0, 0; - 0, 1, 0; - 0, 0, 1] "Translational inertia (mass matrix)"; - parameter Real r_body[3] = {0.5, 0, 0} "Vector from hinge point to COM in body frame"; - parameter Real R_rot[3,3] = [0.02, 0, 0; - 0, 0.02, 0; - 0, 0, 0.02] "Rotational damping matrix"; - parameter Real g = 9.81 "Gravity magnitude"; - - // --------------------------------------------------------------------------- - // Rotational dynamics (body frame) - // --------------------------------------------------------------------------- - _3D.J1 w_com(N = 6, s = {1, -1, -1, -1, -1, -1}) "Common angular velocity junction"; - _3D.I J_inertial(I = J) "Angular momentum storage"; - _3D.R hinge_r(R = R_rot) "Rotational damping"; - _3D.fsensor3d wsensor "Measures body angular velocity omega"; - - // Gyroscopic term implementation (power-conserving structure): - // - TF maps omega -> h = J*omega (angular momentum) - // - mGY with modulation S(omega) generates tau_g = omega x h - _3D.TF Hmap(n = J) "Maps between omega and angular-momentum port"; - _3D.mGY gyro "Modulated gyrator for omega x h coupling"; - - // --------------------------------------------------------------------------- - // Kinematics and frame transforms - // --------------------------------------------------------------------------- - _3D.TransRotUtils.mTFrot3lin mTFrot3lin(r_body = r_body) "v = omega x r_body coupling"; - _3D.J0 j0(N = 3, s = {1, 1, -1}) "Velocity composition at COM in body frame"; - _3D.J1 v_p_bff(N = 2, s = {1, 1}) "Hinge-point velocity (body frame)"; - _3D.J1 v_com_bff(N = 2, s = {-1, -1}) "COM velocity (body frame)"; - _3D.TransRotUtils.rTF3D rTF3D "Body <-> inertial frame transform"; - - // --------------------------------------------------------------------------- - // Translational dynamics (inertial frame) - // --------------------------------------------------------------------------- - _3D.J1 v_com_in(N = 4, s = {1, -1, -1, 1}) "COM velocity in inertial frame"; - _3D.I mass(I = m) "Translational momentum storage"; - _3D.Sf ground(f0 = {0, 0, 0}) "Ground translational velocity"; - _3D.mSe gravity "Gravity effort source"; - _3D.fsensor3d v_inertial "Measures inertial COM velocity"; - - // --------------------------------------------------------------------------- - // States and signals - // --------------------------------------------------------------------------- - Real omega[3] "Body angular velocity"; - Real h[3] "Body angular momentum J*omega"; - Real S_omega[3,3] "Skew matrix of omega"; - - Real phi(start = 0) "Roll"; - Real theta(start = 0.1) "Pitch"; - Real psi(start = 0) "Yaw"; - Real euler_dot[3] "{phi_dot, theta_dot, psi_dot}"; - - Real x(start = -0.5) "COM x (inertial)"; - Real y(start = 0) "COM y (inertial)"; - Real z(start = -0.2) "COM z (inertial)"; - - Modelica.Blocks.Sources.RealExpression xSig(y = x); - Modelica.Blocks.Sources.RealExpression ySig(y = y); - Modelica.Blocks.Sources.RealExpression zSig(y = z); - Modelica.Blocks.Sources.RealExpression phiSig(y = phi); - Modelica.Blocks.Sources.RealExpression thetaSig(y = theta); - Modelica.Blocks.Sources.RealExpression psiSig(y = psi); - vis3d vis3d1; - -equation - // --------------------------------------------------------------------------- - // Rotational network connections - // --------------------------------------------------------------------------- - connect(w_com.P[1], J_inertial.p); - connect(w_com.P[2], mTFrot3lin.pR); - connect(w_com.P[3], wsensor.p); - connect(w_com.P[4], hinge_r.p); - connect(w_com.P[5], gyro.p1); - connect(w_com.P[6], Hmap.p1); - connect(Hmap.p2, gyro.p2); - - // --------------------------------------------------------------------------- - // Body-frame COM kinematics and frame transform - // --------------------------------------------------------------------------- - connect(mTFrot3lin.pT, j0.P[1]); - connect(v_com_bff.P[1], j0.P[2]); - connect(j0.P[3], v_p_bff.P[1]); - connect(ground.p, v_p_bff.P[2]); - - connect(v_com_bff.P[2], rTF3D.p2); - connect(rTF3D.p1, v_com_in.P[1]); - - // Feed frame-transform angles from state variables. - connect(phiSig.y, rTF3D.phi); - connect(thetaSig.y, rTF3D.theta); - connect(psiSig.y, rTF3D.psi); - connect(phiSig.y, vis3d1.phi); - connect(thetaSig.y, vis3d1.theta); - connect(psiSig.y, vis3d1.psi); - - // --------------------------------------------------------------------------- - // Translational dynamics connections - // --------------------------------------------------------------------------- - connect(v_com_in.P[2], mass.p); - connect(gravity.p, v_com_in.P[3]); - connect(v_com_in.P[4], v_inertial.p); - - // Gravity as effort in inertial frame. - gravity.e0 = 0; - gravity.e1 = 0; - gravity.e2 = g; - - // --------------------------------------------------------------------------- - // Gyroscopic modulation and H-map related equations - // --------------------------------------------------------------------------- - omega = {wsensor.f0, wsensor.f1, wsensor.f2}; - h = J * omega; - - // Skew matrix S(omega) so that S(omega)*x = omega x x. - S_omega = [0, -omega[3], omega[2]; - omega[3], 0, -omega[1]; - -omega[2], omega[1], 0]; - gyro.m = S_omega; - - // --------------------------------------------------------------------------- - // 3D attitude kinematics (explicit H(q) mapping form) - // Using ZYX convention with body rates omega -> Euler rates. - // Note: singular at cos(theta)=0. - // --------------------------------------------------------------------------- - euler_dot[1] = omega[1] + sin(phi) * tan(theta) * omega[2] + cos(phi) * tan(theta) * omega[3]; - euler_dot[2] = cos(phi) * omega[2] - sin(phi) * omega[3]; - euler_dot[3] = sin(phi) / cos(theta) * omega[2] + cos(phi) / cos(theta) * omega[3]; - - der(phi) = euler_dot[1]; - der(theta) = euler_dot[2]; - der(psi) = euler_dot[3]; - - // --------------------------------------------------------------------------- - // Position integration - // --------------------------------------------------------------------------- - der(x) = v_inertial.f0; - der(y) = v_inertial.f1; - der(z) = v_inertial.f2; - - connect(xSig.y, vis3d1.x); - connect(ySig.y, vis3d1.y); - connect(zSig.y, vis3d1.z); - - annotation( - uses(Modelica(version = "4.1.0")), - experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-06, Interval = 0.02), - Diagram(coordinateSystem(extent = {{-140, 160}, {200, -160}}))); -end test3d; diff --git a/vis2d.mo b/vis2d.mo index 0e7d067..c12f56b 100644 --- a/vis2d.mo +++ b/vis2d.mo @@ -89,8 +89,9 @@ protected 0, 0, 1], zeros(3))); equation r = {x, y, 0}; - Rz = [cos(phi), -sin(phi), 0; - sin(phi), cos(phi), 0; + // Negate phi here since shapes use inverse frame-mapping + Rz = [cos(-phi), -sin(-phi), 0; + sin(-phi), cos(-phi), 0; 0, 0, 1]; annotation( diff --git a/vis3d.mo b/vis3d.mo deleted file mode 100644 index 4594599..0000000 --- a/vis3d.mo +++ /dev/null @@ -1,103 +0,0 @@ -model vis3d - import Modelica.Mechanics.MultiBody.Visualizers; - import Modelica.Mechanics.MultiBody.Frames; - - parameter Real L = 1; - parameter Real w = 0.02; - parameter Real orbRadius = 0.04; - parameter Real axisLength = 0.25; - parameter Real axisWidth = 0.01; - - Modelica.Blocks.Interfaces.RealInput psi annotation( - Placement(transformation(origin = {-98, -70}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {-94, 20}, extent = {{-10, -10}, {10, 10}}))); - Modelica.Blocks.Interfaces.RealInput theta annotation( - Placement(transformation(origin = {-98, -42}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {-94, 50}, extent = {{-10, -10}, {10, 10}}))); - Modelica.Blocks.Interfaces.RealInput phi annotation( - Placement(transformation(origin = {-98, -14}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {-94, 80}, extent = {{-10, -10}, {10, 10}}))); - Modelica.Blocks.Interfaces.RealInput z annotation( - Placement(transformation(origin = {-98, 14}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {-94, -80}, extent = {{-10, -10}, {10, 10}}))); - Modelica.Blocks.Interfaces.RealInput y annotation( - Placement(transformation(origin = {-98, 42}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {-94, -50}, extent = {{-10, -10}, {10, 10}}))); - Modelica.Blocks.Interfaces.RealInput x annotation( - Placement(transformation(origin = {-98, 70}, extent = {{-20, -20}, {20, 20}}), iconTransformation(origin = {-94, -20}, extent = {{-10, -10}, {10, 10}}))); -protected - Real R[3,3]; - Real r[3]; - - Visualizers.Advanced.Shape link( - shapeType = "cylinder", - length = L, - width = w, - height = w, - r_shape = {-L / 2, 0, 0}, - lengthDirection = {1, 0, 0}, - widthDirection = {0, 1, 0}, - r = r, - R = Frames.from_T(R, zeros(3))); - - Visualizers.Advanced.Shape orb( - shapeType = "sphere", - length = 2 * orbRadius, - width = 2 * orbRadius, - height = 2 * orbRadius, - r_shape = {L / 2 - orbRadius, 0, 0}, - lengthDirection = {1, 0, 0}, - widthDirection = {0, 1, 0}, - r = r, - R = Frames.from_T(R, zeros(3))); - - Visualizers.Advanced.Shape xAxis( - shapeType = "cylinder", - length = axisLength, - width = axisWidth, - height = axisWidth, - color = {255, 0, 0}, - specularCoefficient = 0.1, - r_shape = {axisLength / 2, 0, 0}, - lengthDirection = {1, 0, 0}, - widthDirection = {0, 1, 0}, - r = zeros(3), - R = Frames.from_T([1, 0, 0; - 0, 1, 0; - 0, 0, 1], zeros(3))); - - Visualizers.Advanced.Shape yAxis( - shapeType = "cylinder", - length = axisLength, - width = axisWidth, - height = axisWidth, - color = {0, 200, 0}, - specularCoefficient = 0.1, - r_shape = {0, axisLength / 2, 0}, - lengthDirection = {0, 1, 0}, - widthDirection = {0, 0, 1}, - r = zeros(3), - R = Frames.from_T([1, 0, 0; - 0, 1, 0; - 0, 0, 1], zeros(3))); - - Visualizers.Advanced.Shape zAxis( - shapeType = "cylinder", - length = axisLength, - width = axisWidth, - height = axisWidth, - color = {0, 90, 255}, - specularCoefficient = 0.1, - r_shape = {0, 0, axisLength / 2}, - lengthDirection = {0, 0, 1}, - widthDirection = {1, 0, 0}, - r = zeros(3), - R = Frames.from_T([1, 0, 0; - 0, 1, 0; - 0, 0, 1], zeros(3))); - -equation - r = {x, y, z}; - R = [cos(psi) * cos(theta), cos(psi) * sin(theta) * sin(phi) - sin(psi) * cos(phi), cos(psi) * sin(theta) * cos(phi) + sin(psi) * sin(phi); - sin(psi) * cos(theta), sin(psi) * sin(theta) * sin(phi) + cos(psi) * cos(phi), sin(psi) * sin(theta) * cos(phi) - cos(psi) * sin(phi); - -sin(theta), cos(theta) * sin(phi), cos(theta) * cos(phi)]; - - annotation( - uses(Modelica(version = "4.1.0")), - Icon(graphics = {Rectangle(lineColor = {204, 204, 204}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Sphere, extent = {{-100, 100}, {100, -100}}, radius = 10), Text(extent = {{-100, 100}, {100, -100}}, textString = "VIS")})); -end vis3d; \ No newline at end of file