diff --git a/Modelica/Mechanics/MultiBody/Interfaces/PartialConstraint.mo b/Modelica/Mechanics/MultiBody/Interfaces/PartialConstraint.mo new file mode 100644 index 0000000000..40e501ab13 --- /dev/null +++ b/Modelica/Mechanics/MultiBody/Interfaces/PartialConstraint.mo @@ -0,0 +1,73 @@ +within Modelica.Mechanics.MultiBody.Interfaces; +partial model PartialConstraint + "Base model for elementary constraints" + extends PartialTwoFrames; + + parameter Boolean x_locked=true + "= true, if constraint force in x-direction, resolved in frame_a" + annotation (Dialog(group="Constrain translational motion"), choices(checkBox=true)); + parameter Boolean y_locked=true + "= true, if constraint force in y-direction, resolved in frame_a" + annotation (Dialog(group="Constrain translational motion"), choices(checkBox=true)); + parameter Boolean z_locked=true + "= true, if constraint force in z-direction, resolved in frame_a" + annotation (Dialog(group="Constrain translational motion"), choices(checkBox=true)); + +protected + SI.Position r_rel_a[3] + "Position vector from origin of frame_a to origin of frame_b, resolved in frame_a"; + Frames.Orientation R_rel + "Relative orientation object from frame_a to frame_b"; + SI.InstantaneousPower P "Instantaneous power"; + +equation + // Determine relative position and orientation + r_rel_a = Frames.resolve2(frame_a.R, frame_b.r_0 - frame_a.r_0); + R_rel = Frames.relativeRotation(frame_a.R, frame_b.R); + + // Constraint equations concerning translations + if x_locked then + r_rel_a[1]=0; + else + frame_a.f[1]=0; + end if; + + if y_locked then + r_rel_a[2]=0; + else + frame_a.f[2]=0; + end if; + + if z_locked then + r_rel_a[3]=0; + else + frame_a.f[3]=0; + end if; + + // Force and torque balance + zeros(3) = frame_a.f + Frames.resolve1(R_rel, frame_b.f); + zeros(3) = frame_a.t + Frames.resolve1(R_rel, frame_b.t) - cross(r_rel_a, frame_a.f); + // - cross(r_rel_a, frame_a.f) gives the same result like cross(r_rel_a, Frames.resolve1(R_rel, frame_b.f)) + + // Instantaneous power + P = frame_a.t * Frames.angularVelocity2(frame_a.R) + + frame_b.t * Frames.angularVelocity2(frame_b.R) + + frame_a.f * Frames.resolve2(frame_a.R, der(frame_a.r_0)) + + frame_b.f * Frames.resolve2(frame_b.R, der(frame_b.r_0)); + + annotation (Documentation(info=" +
+All elementary joints defined by constraints should inherit +from this base model, i.e., joints that are directly defined by constraint +equations between the two frames. +
+
+This partial model provides relative kinematic quantities r_rel_a
+and R_rel between the two frame connectors frame_a
+and frame_b, and basic equations constraining translational movement.
+The inheriting class shall additionally provide corresponding equations
+constraining rotational movement.
+
This model does not use explicit variables e.g. state variables in order to describe the relative motion of frame_b with respect to frame_a, but defines kinematic constraints between the frame_a and frame_b. The forces and torques at both frames are then evaluated in such a way that the constraints are satisfied. Sometimes this type of formulation is also called an implicit joint in literature.
As a consequence of the formulation the relative kinematics between frame_a and frame_b cannot be initialized.
In particular in complex multibody systems with closed loops this may help to simplify the system of non-linear equations. Please compare the translation log using the classical joint formulation and the alternative formulation used here in order to check whether this fact applies to the particular system under consideration.
diff --git a/Modelica/Mechanics/MultiBody/Joints/Constraints/Spherical.mo b/Modelica/Mechanics/MultiBody/Joints/Constraints/Spherical.mo index 83e7b39270..e8f3309e8f 100644 --- a/Modelica/Mechanics/MultiBody/Joints/Constraints/Spherical.mo +++ b/Modelica/Mechanics/MultiBody/Joints/Constraints/Spherical.mo @@ -1,18 +1,7 @@ within Modelica.Mechanics.MultiBody.Joints.Constraints; model Spherical "Spherical cut joint and translational directions may be constrained or released" - extends Modelica.Mechanics.MultiBody.Interfaces.PartialTwoFrames; - import MBS = Modelica.Mechanics.MultiBody; - - parameter Boolean x_locked=true - "= true: constraint force in x-direction, resolved in frame_a" - annotation (Dialog(group="Constraints"), choices(checkBox=true)); - parameter Boolean y_locked=true - "= true: constraint force in y-direction, resolved in frame_a" - annotation (Dialog(group="Constraints"), choices(checkBox=true)); - parameter Boolean z_locked=true - "= true: constraint force in z-direction, resolved in frame_a" - annotation (Dialog(group="Constraints"), choices(checkBox=true)); + extends Modelica.Mechanics.MultiBody.Interfaces.PartialConstraint; parameter Boolean animation=true "= true, if animation shall be enabled (show sphere)" @@ -20,10 +9,10 @@ model Spherical parameter SI.Distance sphereDiameter=world.defaultJointLength /3 "Diameter of sphere representing the spherical joint" annotation (Dialog(group="Animation", enable=animation)); - input MBS.Types.Color sphereColor=MBS.Types.Defaults.JointColor + input Types.Color sphereColor=Types.Defaults.JointColor "Color of sphere representing the spherical joint" annotation (Dialog(colorSelector=true, group="Animation", enable=animation)); - input MBS.Types.SpecularCoefficient specularCoefficient = world.defaultSpecularCoefficient + input Types.SpecularCoefficient specularCoefficient = world.defaultSpecularCoefficient "Reflection of ambient light (= 0: light is completely absorbed)" annotation (Dialog(group="Animation", enable=animation)); @@ -39,42 +28,11 @@ model Spherical r_shape={-0.5,0,0}*sphereDiameter, r=frame_a.r_0, R=frame_a.R) if world.enableAnimation and animation; -protected - MBS.Frames.Orientation R_rel - "Dummy or relative orientation object from frame_a to frame_b"; - SI.Position r_rel_a[3] - "Position vector from origin of frame_a to origin of frame_b, resolved in frame_a"; - SI.InstantaneousPower P; equation - // Determine relative position vector resolved in frame_a - R_rel = MBS.Frames.relativeRotation(frame_a.R, frame_b.R); - r_rel_a = MBS.Frames.resolve2(frame_a.R, frame_b.r_0 - frame_a.r_0); - - // Constraint equations concerning translation - if x_locked then - r_rel_a[1]=0; - else - frame_a.f[1]=0; - end if; - - if y_locked then - r_rel_a[2]=0; - else - frame_a.f[2]=0; - end if; - - if z_locked then - r_rel_a[3]=0; - else - frame_a.f[3]=0; - end if; - //frame_a.t = zeros(3); frame_b.t = zeros(3); - frame_b.f = -MBS.Frames.resolve2(R_rel, frame_a.f); - zeros(3) = frame_a.t + MBS.Frames.resolve1(R_rel, frame_b.t) - cross(r_rel_a, frame_a.f); - P= frame_a.t*MBS.Frames.angularVelocity2(frame_a.R)+frame_b.t*MBS.Frames.angularVelocity2(frame_b.R) + MBS.Frames.resolve1(frame_b.R,frame_b.f)*der(frame_b.r_0)+MBS.Frames.resolve1(frame_a.R,frame_a.f)*der(frame_a.r_0); + annotation ( defaultComponentName="constraint", Icon(coordinateSystem( @@ -155,7 +113,7 @@ equation textColor={0,0,255}, textString="%name")}), Documentation(info=" -This model does not use explicit variables e.g. state variables in order to describe the relative motion of frame_b with to respect to frame_a, but defines kinematic constraints between the frame_a and frame_b. The forces and torques at both frames are then evaluated in such a way that the constraints are satisfied. Sometimes this type of formulation is also called an implicit joint in literature.
+This model does not use explicit variables e.g. state variables in order to describe the relative motion of frame_b with respect to frame_a, but defines kinematic constraints between the frame_a and frame_b. The forces and torques at both frames are then evaluated in such a way that the constraints are satisfied. Sometimes this type of formulation is also called an implicit joint in literature.
As a consequence of the formulation the relative kinematics between frame_a and frame_b cannot be initialized.
In particular in complex multibody systems with closed loops this may help to simplify the system of non-linear equations. Please compare the translation log using the classical joint formulation and the alternative formulation used here in order to check whether this fact applies to the particular system under consideration.
In systems without closed loops the use of this implicit joint does not make sense or may even be disadvantageous.
diff --git a/Modelica/Mechanics/MultiBody/Joints/Constraints/Universal.mo b/Modelica/Mechanics/MultiBody/Joints/Constraints/Universal.mo index 9dce558fb0..829a213a22 100644 --- a/Modelica/Mechanics/MultiBody/Joints/Constraints/Universal.mo +++ b/Modelica/Mechanics/MultiBody/Joints/Constraints/Universal.mo @@ -1,79 +1,37 @@ within Modelica.Mechanics.MultiBody.Joints.Constraints; model Universal "Universal cut-joint and translational directions may be constrained or released" - extends Modelica.Mechanics.MultiBody.Interfaces.PartialTwoFrames; - import MBS = Modelica.Mechanics.MultiBody; + extends Modelica.Mechanics.MultiBody.Interfaces.PartialConstraint; - parameter MBS.Types.Axis n_a={1,0,0} + parameter Types.Axis n_a={1,0,0} "Axis of revolute joint 1 resolved in frame_a" annotation (Evaluate=true); - parameter MBS.Types.Axis n_b={0,1,0} + parameter Types.Axis n_b={0,1,0} "Axis of revolute joint 2 resolved in frame_b" annotation (Evaluate=true); - parameter Boolean x_locked=true - "= true: constraint force in x-direction, resolved in frame_a" - annotation (Dialog(group="Constraints in translational motion"), choices(checkBox=true)); - parameter Boolean y_locked=true - "= true: constraint force in y-direction, resolved in frame_a" - annotation (Dialog(group="Constraints in translational motion"), choices(checkBox=true)); - parameter Boolean z_locked=true - "= true: constraint force in z-direction, resolved in frame_a" - annotation (Dialog(group="Constraints in translational motion"), choices(checkBox=true)); - parameter Boolean animation=true "= true, if animation shall be enabled (show sphere)" annotation (Dialog(group="Animation")); parameter SI.Distance sphereDiameter=world.defaultJointLength /3 "Diameter of sphere representing the spherical joint" annotation (Dialog(group="Animation", enable=animation)); - input MBS.Types.Color sphereColor=MBS.Types.Defaults.JointColor + input Types.Color sphereColor=Types.Defaults.JointColor "Color of sphere representing the spherical joint" annotation (Dialog(colorSelector=true, group="Animation", enable=animation)); - input MBS.Types.SpecularCoefficient specularCoefficient = world.defaultSpecularCoefficient + input Types.SpecularCoefficient specularCoefficient = world.defaultSpecularCoefficient "Reflection of ambient light (= 0: light is completely absorbed)" annotation (Dialog(group="Animation", enable=animation)); protected - MBS.Frames.Orientation R_rel - "Dummy or relative orientation object from frame_a to frame_b"; Real w_rel[3]; - SI.Position r_rel_a[3] - "Position vector from origin of frame_a to origin of frame_b, resolved in frame_a"; - SI.InstantaneousPower P; equation - // Determine relative position vector resolved in frame_a - R_rel = MBS.Frames.relativeRotation(frame_a.R, frame_b.R); - w_rel = MBS.Frames.angularVelocity1(R_rel); - r_rel_a = MBS.Frames.resolve2(frame_a.R, frame_b.r_0 - frame_a.r_0); - - // Constraint equations concerning translations - if x_locked then - r_rel_a[1]=0; - else - frame_a.f[1]=0; - end if; - - if y_locked then - r_rel_a[2]=0; - else - frame_a.f[2]=0; - end if; - - if z_locked then - r_rel_a[3]=0; - else - frame_a.f[3]=0; - end if; + w_rel = Frames.angularVelocity1(R_rel); // Constraint equations concerning rotations - frame_a.t*n_a=0; - frame_b.t*n_b=0; - n_b*R_rel.T*n_a=0; + frame_a.t * n_a = 0; + frame_b.t * n_b = 0; + n_b * Frames.resolve2(R_rel, n_a) = 0; // Constraint: R_rel shall assure orthogonality of n_a and n_b assert(abs(n_a*n_b) < Modelica.Constants.eps, "The two axes that constitute the Constraints.Universal joint must be different"); - zeros(3)=frame_a.f + MBS.Frames.resolve1(R_rel, frame_b.f); - zeros(3) = frame_a.t+MBS.Frames.resolve1(R_rel, frame_b.t)- cross(r_rel_a, frame_a.f); - P = frame_a.t*MBS.Frames.angularVelocity2(frame_a.R)+frame_b.t*MBS.Frames.angularVelocity2(frame_b.R) + MBS.Frames.resolve1(frame_b.R,frame_b.f)*der(frame_b.r_0)+MBS.Frames.resolve1(frame_a.R,frame_a.f)*der(frame_a.r_0); - annotation ( defaultComponentName="constraint", Icon(coordinateSystem(