Joints are massles objects, that define the relative movement between two rigid elements. The number of degrees of freedom specifies how many variables are minimally needed to describe the relative position. An object in a planar space can have up to 3 degrees of freedom.
Joints usually define integrators and the joint variables on positional and velocity level
become state variables of the system. Anyhow the integrators might be removed by the Pantelides algorithm, if the joint is placed in a kinematic loop.
The number of degrees of freedom equals the number of potential state variables.
It is possible and common to create complex joints out of simple joints. However, one has to pay attention that no singularities occur if two or more joints are connected (directly or through massless elements).
Name | Description |
---|---|
Prismatic | prismatic joint (1 degree of freedom) |
Revolute | revolute joint (1-degree of freedom) |
FreeBodyMovement | joint with all degrees of freedom (3) |
PotentialFBM | potential free-body movement joint |
CloseLoop | element to close kinematik loops manualy |
The parameter s_offset defines an offset value for the joint length s.
The parameter animation toggles the visualization of the element.
Name | Default | Description |
---|---|---|
animation | true | animate prismatic joint as box |
n[2] | {1,0} | direction of the joint axis [m] |
s_offset | 0 | Relative distance offset (distance between frame_a and frame_b = s_offset + s) [m] |
Initialization | ||
initType | MB.Types.Init.Free | Type of initialization (defines usage of start values below) |
s_start | 0 | initial length |
v_start | 0 | initial velocity |
a_start | 0 | initial acceleration |
Animation | ||
if animation = true | ||
boxWidth | planarWorld.defaultJointWidth | Width of prismatic joint box [m] |
boxHeight | boxWidth | Height of prismatic joint box [m] |
boxColor | planarWorld.defaultJointColor | Color of prismatic joint box |
Advanced | ||
enforceStates | false | enforce s and v as states |
model Prismatic "prismatic joint (1 degree of freedom)" import SI = Modelica.SIunits; import MB = Modelica.Mechanics.MultiBody; parameter Boolean animation = true "animate prismatic joint as box"; parameter SI.Position n[2] = {1,0} "direction of the joint axis"; parameter SI.Position s_offset=0 "Relative distance offset (distance between frame_a and frame_b = s_offset + s)"; final parameter SI.Position eD[2] = n/sqrt(n*n); parameter MB.Types.Init.Temp initType=MB.Types.Init.Free "|Initialization| Type of initialization (defines usage of start values below)"; parameter Real s_start = 0 "|Initialization|initial length"; parameter Real v_start = 0 "|Initialization|initial velocity"; parameter Real a_start = 0 "|Initialization|initial acceleration"; parameter SI.Distance boxWidth=planarWorld.defaultJointWidth "|Animation|if animation = true| Width of prismatic joint box"; parameter SI.Distance boxHeight=boxWidth "|Animation|if animation = true| Height of prismatic joint box"; parameter Modelica.Mechanics.MultiBody.Types.Color boxColor=planarWorld.defaultJointColor "|Animation|if animation = true| Color of prismatic joint box"; parameter Boolean enforceStates = false "|Advanced||enforce s and v as states"; SI.Position s(stateSelect=if enforceStates then StateSelect.always else StateSelect.prefer) "length of prismatic joint"; SI.Velocity v(stateSelect=if enforceStates then StateSelect.always else StateSelect.prefer) "velocity of prismatic joint"; SI.Acceleration a "acceleration of prismatic joint"; Interfaces.Frame_a frame_a; Interfaces.Frame_b frame_b; protected outer PlanarWorld planarWorld; inner Defaults MBG_defaults(n=3); Interfaces.Mech2MBG Mech2MBG1; Interfaces.MBG2Mech MBG2Mech1; Junctions.J0Partial J0Partial1( n=3, nPartial=2, order={1,2,3}); Bonds.MultiBond MultiBond1; Bonds.MultiBond MultiBond2; AdditionalMBG.Translation Translation1(d=eD); Junctions.J1 J1_1(n=1); Sources.Se Se1(e0={0}, n=1); AdditionalMBG.prismaticTF prismaticTF1(d=eD); AdditionalMBG.translationalTF translationalTF1(d=eD); Bonds.MultiBond MultiBond3; Bonds.Utilities.MultiBondTail MultiBondTail1; Bonds.MultiBond MultiBond4(n=1); Bonds.MultiBond MultiBond5(n=1); Bonds.MultiBond MultiBond6(n=2); Bonds.MultiBond MultiBond7(n=1); Sensors.Dq Dq1(stateInitialCondition=false,q(stateSelect = StateSelect.never), n=1); parameter Integer ndim=if planarWorld.enableAnimation and animation then 1 else 0; MB.Visualizers.Advanced.Shape sphere[ndim]( each shapeType="box", each color=boxColor, each length=Dq1.q[1], each width=boxWidth, each height=boxHeight, each lengthDirection={eD[1],eD[2],0}, each widthDirection={0,0,1}, each r_shape={0,0,0}, each r={Mech2MBG1.q[1],Mech2MBG1.q[2],0}, each R=MB.Frames.planarRotation({0,0,-1},Mech2MBG1.q[3],0)); initial equation if initType == MB.Types.Init.Position or initType == MB.Types.Init. PositionVelocity or initType == MB.Types.Init.PositionVelocityAcceleration then // Initialize positional variables s = s_start; end if; if initType == MB.Types.Init.PositionVelocity or initType == MB.Types.Init. PositionVelocityAcceleration or initType == MB.Types.Init.Velocity or initType == MB.Types.Init.VelocityAcceleration then // Initialize velocity variables v = v_start; end if; if initType == MB.Types.Init.VelocityAcceleration or initType == MB.Types.Init. PositionVelocityAcceleration then // Initialize acceleration variables a = a_start; end if; if initType == MB.Types.Init.SteadyState then v = 0; a = 0; end if; equation defineBranch(frame_a.P, frame_b.P); s = Dq1.q[1]-s_offset; v = J1_1.MultiBondCon1.f[1]; a = der(v); connect(Mech2MBG1.frame_a, frame_a); connect(MBG2Mech1.frame_b, frame_b); connect(MultiBond2.MultiBondCon2, J0Partial1.MultiBondCon1); connect(MultiBond1.MultiBondCon1, J0Partial1.MultiBondCon2); connect(MultiBond1.MultiBondCon2, MBG2Mech1.MultiBondCon1); connect(translationalTF1.MultiBondCon2, MultiBond2.MultiBondCon1); connect(MultiBond3.MultiBondCon2, translationalTF1.MultiBondCon1); connect(MultiBond3.MultiBondCon1, Mech2MBG1.MultiBondCon1); connect(MultiBond6.MultiBondCon1, prismaticTF1.MultiBondConB); connect(MultiBond6.MultiBondCon2, J0Partial1.MultiBondCon3); connect(MultiBond4.MultiBondCon1, Se1.MultiBondCon1); connect(MultiBond4.MultiBondCon2, J1_1.MultiBondCon2); connect(MultiBond5.MultiBondCon1, J1_1.MultiBondCon3); connect(MultiBond5.MultiBondCon2, prismaticTF1.MultiBondConA); connect(Dq1.q[1], translationalTF1.ampl); connect(Dq1.q[1], Translation1.ampl); connect(Mech2MBG1.q, Translation1.q1); connect(Translation1.q2, MBG2Mech1.q); connect(translationalTF1.phi, Mech2MBG1.q[3]); connect(prismaticTF1.phi, Mech2MBG1.q[3]); connect(MultiBond7.MultiBondCon1, J1_1.MultiBondCon1); connect(MultiBond7.MultiBondCon2, Dq1.MultiBondCon1); end Prismatic;
The parameter animation toggles the visualization of the element.
Name | Default | Description |
---|---|---|
animation | true | animate revolute joint as cylinder |
phi_offset | 0 | phi + phi_offset = angle between frames [rad] |
Initialization | ||
initType | MB.Types.Init.Free | Type of initialization (defines usage of start values below) |
phi_start | 0 | initial angle |
w_start | 0 | initial angular velocity |
z_start | 0 | initial angular acceleration |
Animation | ||
if animation = true | ||
cylinderLength | planarWorld.defaultJointLength | Length of cylinder representing the joint axis [m] |
cylinderDiameter | planarWorld.defaultJointWidth | Diameter of cylinder representing the joint axis [m] |
cylinderColor | planarWorld.defaultJointColor | Color of cylinder representing the joint axis |
Advanced | ||
enforceStates | false | enforce phi and w as states |
model Revolute "revolute joint (1-degree of freedom)" import SI = Modelica.SIunits; import MB = Modelica.Mechanics.MultiBody; parameter Boolean animation = true "animate revolute joint as cylinder"; parameter SI.Angle phi_offset = 0 "phi + phi_offset = angle between frames"; parameter MB.Types.Init.Temp initType=MB.Types.Init.Free "|Initialization| Type of initialization (defines usage of start values below)"; parameter Real phi_start = 0 "|Initialization|initial angle"; parameter Real w_start = 0 "|Initialization|initial angular velocity"; parameter Real z_start = 0 "|Initialization|initial angular acceleration"; parameter SI.Distance cylinderLength=planarWorld.defaultJointLength "|Animation|if animation = true| Length of cylinder representing the joint axis"; parameter SI.Distance cylinderDiameter=planarWorld.defaultJointWidth "|Animation|if animation = true| Diameter of cylinder representing the joint axis"; parameter Modelica.Mechanics.MultiBody.Types.Color cylinderColor=planarWorld.defaultJointColor "|Animation|if animation = true| Color of cylinder representing the joint axis"; parameter Boolean enforceStates = false "|Advanced||enforce phi and w as states"; SI.Angle phi(stateSelect=if enforceStates then StateSelect.always else StateSelect.prefer) "revolute angle"; SI.AngularVelocity w(stateSelect=if enforceStates then StateSelect.always else StateSelect.prefer) "revolute angular velocity"; SI.AngularAcceleration z "revolute angular acceleration"; Interfaces.Frame_a frame_a; Interfaces.Frame_b frame_b; protected outer PlanarWorld planarWorld; inner Defaults MBG_defaults(n=3); Interfaces.Mech2MBG Mech2MBG1; Interfaces.MBG2Mech MBG2Mech1; Junctions.J0Partial J0Partial1( n=3, nPartial=1, order={3,1,2}); Bonds.MultiBond MultiBond1; Bonds.MultiBond MultiBond2; Bonds.MultiBond MultiBond3(n=1); Bonds.MultiBond MultiBond5(n=1); Bonds.Utilities.MultiBondTail MultiBondTail1; Junctions.J1 J1_1(n=1); Bonds.MultiBond MultiBond4(n=1); Sources.Se Se1(n=1, e0={0}); Sensors.Dq Dq_phi(stateInitialCondition=false, n=1); AdditionalMBG.Translation TranslationRevolute(d={0,0}); parameter Integer ndim=if planarWorld.enableAnimation and animation then 1 else 0; MB.Visualizers.Advanced.Shape cylinder[ndim]( each shapeType="cylinder", each color=cylinderColor, each length=cylinderLength, each width=cylinderDiameter, each height=cylinderDiameter, each lengthDirection={0,0,1}, each widthDirection={0,1,0}, each r_shape=-{0,0,1}*cylinderLength/2, each r={Mech2MBG1.q[1],Mech2MBG1.q[2],0}, each R=MB.Frames.planarRotation({0,0,-1},Mech2MBG1.q[3],0)); initial equation if initType == MB.Types.Init.Position or initType == MB.Types.Init. PositionVelocity or initType == MB.Types.Init.PositionVelocityAcceleration then // Initialize positional variables phi = phi_start; end if; if initType == MB.Types.Init.PositionVelocity or initType == MB.Types.Init. PositionVelocityAcceleration or initType == MB.Types.Init.Velocity or initType == MB.Types.Init.VelocityAcceleration then // Initialize velocity variables w = w_start; end if; if initType == MB.Types.Init.VelocityAcceleration or initType == MB.Types.Init. PositionVelocityAcceleration then // Initialize acceleration variables z = z_start; end if; if initType == MB.Types.Init.SteadyState then w = 0; z = 0; end if; equation defineBranch(frame_a.P, frame_b.P); phi = Dq_phi.q[1]-phi_offset; w = J1_1.MultiBondCon1.f[1]; z = der(w); connect(MBG2Mech1.frame_b, frame_b); connect(Mech2MBG1.frame_a, frame_a); connect(MultiBond2.MultiBondCon2, J0Partial1.MultiBondCon1); connect(MultiBond1.MultiBondCon2, MBG2Mech1.MultiBondCon1); connect(MultiBond1.MultiBondCon1, J0Partial1.MultiBondCon2); connect(MultiBond2.MultiBondCon1, Mech2MBG1.MultiBondCon1); connect(MultiBond3.MultiBondCon2, J0Partial1.MultiBondCon3); connect(J1_1.MultiBondCon3, MultiBond3.MultiBondCon1); connect(MultiBond4.MultiBondCon2, J1_1.MultiBondCon4); connect(Se1.MultiBondCon1, MultiBond4.MultiBondCon1); connect(Dq_phi.q[1], TranslationRevolute.phi); connect(Mech2MBG1.q, TranslationRevolute.q1); connect(TranslationRevolute.q2, MBG2Mech1.q); connect(MultiBond5.MultiBondCon1, J1_1.MultiBondCon1); connect(MultiBond5.MultiBondCon2, Dq_phi.MultiBondCon1); end Revolute;
Name | Default | Description |
---|---|---|
Initialization | ||
initType | MB.Types.Init.Free | Type of initialization (defines usage of start values below) |
x_start[2] | {0,0} | initial position (x,y) [m] |
v_start[2] | {0,0} | initial velocity (vx, vy) [m/s] |
a_start[2] | {0,0} | initial acceleration (ax, ay) [m/s2] |
phi_start | 0 | initial angle [rad] |
w_start | 0 | initial ang. velocity [rad/s] |
z_start | 0 | initial ang. acc. [rad/s2] |
Advanced | ||
enforceStates | false | enforce x,y,phi and vx, vy, w as states |
model FreeBodyMovement "joint with all degrees of freedom (3)" import SI = Modelica.SIunits; import MB = Modelica.Mechanics.MultiBody; parameter MB.Types.Init.Temp initType=MB.Types.Init.Free "|Initialization| Type of initialization (defines usage of start values below)"; parameter SI.Position x_start[2] = {0,0} "|Initialization|initial position (x,y)"; parameter SI.Velocity v_start[2] = {0,0} "|Initialization|initial velocity (vx, vy)"; parameter SI.Acceleration a_start[2] = {0,0} "|Initialization|initial acceleration (ax, ay)"; parameter SI.Angle phi_start = 0 "|Initialization|initial angle"; parameter SI.AngularVelocity w_start = 0 "|Initialization|initial ang. velocity "; parameter SI.AngularAcceleration z_start = 0 "|Initialization|initial ang. acc."; parameter Boolean enforceStates = false "|Advanced||enforce x,y,phi and vx, vy, w as states"; Interfaces.Frame_b frame_b; SI.Position x(stateSelect=if enforceStates then StateSelect.always else StateSelect.prefer); SI.Position y(stateSelect=if enforceStates then StateSelect.always else StateSelect.prefer); SI.Angle phi(stateSelect=if enforceStates then StateSelect.always else StateSelect.prefer); SI.Velocity vx(stateSelect=if enforceStates then StateSelect.always else StateSelect.prefer); SI.Velocity vy(stateSelect=if enforceStates then StateSelect.always else StateSelect.prefer); SI.AngularVelocity w(stateSelect=if enforceStates then StateSelect.always else StateSelect.prefer); SI.Acceleration ax; SI.Acceleration ay; SI.AngularAcceleration z; protected inner Defaults MBG_defaults(n=3); protected Interfaces.MBG2Mech MBG2Mech1; Bonds.MultiBond MultiBond1; Bonds.MultiBond MultiBond2; Sources.Se Se1(e0={0}, n=3); Sensors.Dq Dq1(n=3, q_start={0,0,0}, stateInitialCondition=false); Junctions.J1 J1_1; Bonds.MultiBond MultiBond3; initial equation if initType == MB.Types.Init.Position or initType == MB.Types.Init. PositionVelocity or initType == MB.Types.Init.PositionVelocityAcceleration then // Initialize positional variables {x,y} = x_start; phi = phi_start; end if; if initType == MB.Types.Init.PositionVelocity or initType == MB.Types.Init. PositionVelocityAcceleration or initType == MB.Types.Init.Velocity or initType == MB.Types.Init.VelocityAcceleration then // Initialize velocity variables {vx, vy} = v_start; w = w_start; end if; if initType == MB.Types.Init.VelocityAcceleration or initType == MB.Types.Init. PositionVelocityAcceleration then // Initialize acceleration variables {ax, ay} = a_start; z = z_start; end if; if initType == MB.Types.Init.SteadyState then {vx, vy} = zeros(2); {ax, ay} = zeros(2); w = 0; z = 0; end if; equation defineRoot(frame_b.P); {x,y,phi} = MBG2Mech1.q; {vx,vy,w} = MBG2Mech1.MultiBondCon1.f; {ax,ay,z} = der({vx,vy,w}); connect(MBG2Mech1.frame_b, frame_b); connect(MultiBond1.MultiBondCon2, MBG2Mech1.MultiBondCon1); connect(Se1.MultiBondCon1, MultiBond2.MultiBondCon1); connect(Dq1.q, MBG2Mech1.q); connect(J1_1.MultiBondCon2, MultiBond1.MultiBondCon1); connect(J1_1.MultiBondCon1, MultiBond2.MultiBondCon2); connect(MultiBond3.MultiBondCon1, J1_1.MultiBondCon3); connect(MultiBond3.MultiBondCon2, Dq1.MultiBondCon1); end FreeBodyMovement;
Name | Default | Description |
---|---|---|
Initialization | ||
initType | MB.Types.Init.Free | Type of initialization (defines usage of start values below) |
x_start[2] | {0,0} | initial position (x,y) [m] |
v_start[2] | {0,0} | initial velocity (vx, vy) [m/s] |
a_start[2] | {0,0} | initial acceleration (ax, ay) [m/s2] |
phi_start | 0 | initial angle [rad] |
w_start | 0 | initial ang. velocity [rad/s] |
z_start | 0 | initial ang. acc. [rad/s2] |
Advanced | ||
enforceStates | false | enforce x,y,phi and vx, vy, w as states |
model PotentialFBM "potential free-body movement joint" import SI = Modelica.SIunits; import MB = Modelica.Mechanics.MultiBody; parameter MB.Types.Init.Temp initType=MB.Types.Init.Free "|Initialization| Type of initialization (defines usage of start values below)"; parameter SI.Position x_start[2] = {0,0} "|Initialization|initial position (x,y)"; parameter SI.Velocity v_start[2] = {0,0} "|Initialization|initial velocity (vx, vy)"; parameter SI.Acceleration a_start[2] = {0,0} "|Initialization|initial acceleration (ax, ay)"; parameter SI.Angle phi_start = 0 "|Initialization|initial angle"; parameter SI.AngularVelocity w_start = 0 "|Initialization|initial ang. velocity "; parameter SI.AngularAcceleration z_start = 0 "|Initialization|initial ang. acc."; parameter Boolean enforceStates = false "|Advanced||enforce x,y,phi and vx, vy, w as states"; Interfaces.Frame_b frame_b; SI.Position x(stateSelect=if enforceStates then StateSelect.always else StateSelect.prefer); SI.Position y(stateSelect=if enforceStates then StateSelect.always else StateSelect.prefer); SI.Angle phi(stateSelect=if enforceStates then StateSelect.always else StateSelect.prefer); SI.Velocity vx(stateSelect=if enforceStates then StateSelect.always else StateSelect.prefer); SI.Velocity vy(stateSelect=if enforceStates then StateSelect.always else StateSelect.prefer); SI.AngularVelocity w(stateSelect=if enforceStates then StateSelect.always else StateSelect.prefer); SI.Acceleration ax; SI.Acceleration ay; SI.AngularAcceleration z; protected inner Defaults MBG_defaults(n=3); protected Interfaces.MBG2Mech MBG2Mech1; Bonds.MultiBond MultiBond1; Bonds.MultiBond MultiBond2; Sources.Se Se1(e0={0}, n=3); Junctions.J1 J1_1; protected Bonds.MultiBond MultiBond3; initial equation if initType == MB.Types.Init.Position or initType == MB.Types.Init. PositionVelocity or initType == MB.Types.Init.PositionVelocityAcceleration then // Initialize positional variables {x,y} = x_start; phi = phi_start; end if; if initType == MB.Types.Init.PositionVelocity or initType == MB.Types.Init. PositionVelocityAcceleration or initType == MB.Types.Init.Velocity or initType == MB.Types.Init.VelocityAcceleration then // Initialize velocity variables {vx, vy} = v_start; w = w_start; end if; if initType == MB.Types.Init.VelocityAcceleration or initType == MB.Types.Init. PositionVelocityAcceleration then // Initialize acceleration variables {ax, ay} = a_start; z = z_start; end if; if initType == MB.Types.Init.SteadyState then {vx, vy} = zeros(2); {ax, ay} = zeros(2); w = 0; z = 0; end if; equation if enforceStates then defineRoot(frame_b.P); else definePotentialRoot(frame_b.P); end if; if isRoot(frame_b.P) then vx = der(x); vy = der(y); w = der(phi); end if; MultiBond3.MultiBondCon2.e = zeros(3); {x,y,phi} = MBG2Mech1.q; {vx,vy,w} = MBG2Mech1.MultiBondCon1.f; {ax,ay,z} = der({vx,vy,w}); connect(MBG2Mech1.frame_b, frame_b); connect(MultiBond1.MultiBondCon2, MBG2Mech1.MultiBondCon1); connect(Se1.MultiBondCon1, MultiBond2.MultiBondCon1); connect(J1_1.MultiBondCon2, MultiBond1.MultiBondCon1); connect(J1_1.MultiBondCon1, MultiBond2.MultiBondCon2); connect(MultiBond3.MultiBondCon1, J1_1.MultiBondCon3); end PotentialFBM;
You can cut a kinematic loop manually with this element . Just insert the element into the loop at the point where you'd like to cut it.
This element connects its two connectors in a non-redundant way. It must not be used outside a kinematik loop.
model CloseLoop "element to close kinematik loops manualy" Interfaces.Frame_a frame_a; Interfaces.Frame_b frame_b; equation frame_a.P.x = frame_b.P.x; frame_a.P.y = frame_b.P.y; frame_a.P.phi = frame_b.P.phi; frame_a.fx = frame_b.fx; frame_a.fy = frame_b.fy; frame_a.t = frame_b.t; end CloseLoop;