| Name | Description |
|---|---|
| models the collision between a spheres and a plane | |
| models the collision between two spheres | |
| dummy collision element | |
| dummy collision element |
MultiBondLib.Mechanics3DwithImpulses.Contacts.CollisionSpherePlane
The collision is modelled by three impulses that are separated by a very small timespan.
The first impulse models the reflection law. The second impulse models the effect of friction.
The third impulse models a necessary correction if the friction impulse was too strong and caused a reflection.
The characteristics of the geometry can be set by the parameters:
The parameter s_small in the advanced menu reduces the stiffness of the friction for slip velocities in the range from zero up to s_small.
| Type | Name | Default | Description |
|---|---|---|---|
| Radius | ra | 1 | radius of sphere at frame a [m] |
| Radius | Nb[3] | {0,1,0} | normal vector of plane [m] |
| Real | elasticity | 1.0 | Elasticity of impuls |
| Real | muR | 0.0 | friction coefficient |
| Advanced | |||
| Position | s_small | 1e-4 | critical length [m] |
| Real | contactDuration | 1e-9 | time to handle the impulses |
| Type | Name | Description |
|---|---|---|
| IFrame_a | frame_a | |
| output BooleanOutput | y | |
| IFrame_b | frame_b |
model CollisionSpherePlane
"models the collision between a spheres and a plane"
import SI = Modelica.SIunits;
Interfaces.IFrame_a frame_a;
parameter SI.Radius ra = 1 "radius of sphere at frame a";
parameter SI.Radius Nb[3] = {0,1,0} "normal vector of plane";
parameter SI.Position s_small = 1e-4 "|Advanced||critical length";
parameter Real elasticity = 1.0 "Elasticity of impuls";
parameter Real muR = 0.0 "friction coefficient";
parameter Real contactDuration = 1e-9
"|Advanced||time to handle the impulses";
protected
Real[3,3] R_a "orientation of frame a at the impulse time";
Real[3,3] R_b "orientation of frame a at the impulse time";
SI.Distance d "distance vector from sphere center to plane";
Real eR[3] "normalized variant of d";
Real noteR[3] "a vector that has any value but not r";
Real eA[3] "unit vector that is normal to r";
Real eB[3] "unit vector that is normal to r and eA.";
//eR, eA, eB build up an orthonormal coordinate system, where eR is pointing in contact direction.
Boolean contact "contact signal";
Integer seqState
"state in the impluse sequence (0=impact, 1=friction, 2=correction)";
Real frictionImpulseTime "time of the succeeding friction Impulse";
Real correctionImpulseTime "time of the succeeding correction Impulse";
SI.Impulse F[3] "force impulse between the two frames";
SI.Velocity vA[3] "rel. velocity of the two frames right before the impulse";
SI.Velocity Vm[3] "average rel. velocity during the impulse";
//variables of the impact impulse
SI.Impulse FR "force impulse in direction of eR";
SI.Impulse FA0 "force impulse in direction of eA";
SI.Impulse FB0 "force impulse in direction of eB";
SI.Velocity VmR0 "average velocity in direction of eR";
//variables of the friction impulse
SI.Impulse FA1 "force impulse in direction of eA";
SI.Impulse FB1 "force impulse in direction of eB";
SI.Impulse FR1 "force impulse in direction of eR";
SI.Velocity VFricElast[3]
"becomes non-zero if the friction impulse caused more than an elastic impulse";
//eC, eD, eE build up an orthonormal coordinate system where eC points into the direction
//of the lateral velocity difference (slippage)
Real eC[3];
Real noteC[3];
Real eD[3];
Real eE[3];
//variables of the correction impulse
SI.Impulse FD2 "force impulse in direction of eD";
SI.Impulse FE2 "force impulse in direction of eE";
SI.Velocity VmC2 "average velocity in direction of eC";
public
Modelica.Blocks.Interfaces.BooleanOutput y;
Interfaces.IFrame_b frame_b;
initial equation
contact = false;
seqState = -1;
frictionImpulseTime = 0;
correctionImpulseTime = 0;
equation
algorithm
//reset contact signal to false
when contact then
contact :=false;
end when;
//detect collision and trigger event
when d <= ra then
contact :=true;
seqState := 0;
frictionImpulseTime :=time + contactDuration/2;
end when;
//trigger event for friction impulse
when (time >= frictionImpulseTime) and (seqState == 0) then
contact :=true;
seqState := 1;
frictionImpulseTime := 0;
correctionImpulseTime := time + contactDuration/2;
end when;
//trigger event for correction impulse
when (time >= correctionImpulseTime) and (seqState == 1) then
contact :=true;
seqState := 2;
correctionImpulseTime := 0;
end when;
equation
//build up coordinate system eR, eA, eB at the moment of collision.
d = (frame_a.P.x- frame_b.P.x)*(transpose(frame_b.P.R)*Nb);
when contact and (seqState == 0) then
eR = transpose(R_b)*Nb/sqrt(Nb*Nb);
noteR = if abs(eR[1]) > 0.1 then {0,1,0} else (if abs(eR[2])
> 0.1 then {0,0,1} else {1,0,0});
eA = cross(eR, noteR)/sqrt(cross(eR, noteR)*cross(eR, noteR));
eB = cross(eA, eR);
end when;
//state situation right before the impulse
when contact then
vA = (pre(frame_b.P.v)+cross(transpose(R_b)*pre(frame_b.P.w),zeros(3))) -
(pre(frame_a.P.v)+cross(transpose(R_a)*pre(frame_a.P.w),-eR*ra));
R_a = frame_a.P.R;
R_b = frame_b.P.R;
end when;
//store the impact impulse in FR
when contact then
FR = F*eR;
end when;
//impact impulse
when contact and (seqState == 0) then
VmR0 = (1-elasticity)*(vA*eR)/2;
FA0 = 0;
FB0 = 0;
end when;
//friction impulse
when contact and (seqState == 1) then
FR1 = 0;
FA1 = -muR*abs(pre(FR))*((vA/sqrt(vA*vA))*eA);
FB1 = -muR*abs(pre(FR))*((vA/sqrt(vA*vA))*eB);
VFricElast[1] = if sign(vA[1])*Vm[1] >= abs(vA[1]/2) then 0 else Vm[1]- (vA[1]/2);
VFricElast[2] = if sign(vA[2])*Vm[2] >= abs(vA[2]/2) then 0 else Vm[2]- (vA[2]/2);
VFricElast[3] = if sign(vA[3])*Vm[3] >= abs(vA[3]/2) then 0 else Vm[3]- (vA[3]/2);
end when;
//correction impulse
when contact and (seqState == 2) and (pre(VFricElast)*pre(VFricElast) > 0) then
eC = if pre(VFricElast)*pre(VFricElast) < s_small^2 then {1,0,0} else
pre(VFricElast)/sqrt(pre(VFricElast)*pre(VFricElast));
noteC = if abs(eC[1]) > 0.1 then {0,1,0} else (if abs(eC[2])
> 0.1 then {0,0,1} else {1,0,0});
eD = cross(eC, noteC)/sqrt(cross(eC, noteC)*cross(eC, noteC));
eE = cross(eD, eC);
VmC2 = sqrt(pre(VFricElast)*pre(VFricElast));
FD2 = 0;
FE2 = 0;
end when;
//state impulse dependent equations
if contact then
if (seqState == 0) then //further equations fot the impact impulse
Vm*eR = VmR0;
F*eA = FA0;
F*eB = FB0;
else
if (seqState == 1) then //further equations fot the friction impulse
F*eR = FR1;
F*eA = FA1;
F*eB = FB1;
else
//further equations fot the correction impulse
if (seqState == 2) and (pre(VFricElast)*pre(VFricElast) > 0) then
Vm*eC = VmC2;
F*eD = FD2;
F*eE = FE2;
else
F = zeros(3);
end if;
end if;
end if;
else
F = zeros(3);
end if;
//propagate contact signal
y = contact;
//state equations for the translational domain
Vm = (frame_b.Vm+cross(transpose(R_b)*frame_b.Wm,zeros(3))) -
(frame_a.Vm+cross(transpose(R_a)*frame_a.Wm,-eR*ra));
F = -frame_b.F;
F = frame_a.F;
//state equations for the rotational domain
R_b*cross(zeros(3),F) = -frame_b.T;
R_a*cross(-eR*ra,F) = frame_a.T;
//define continuous connector variables
frame_a.f = zeros(3);
frame_a.t = zeros(3);
frame_b.f = zeros(3);
frame_b.t = zeros(3);
end CollisionSpherePlane;
MultiBondLib.Mechanics3DwithImpulses.Contacts.CollisionSphereSphere
The collision is modelled by three impulses that are separated by a very small timespan.
The first impulse models the reflection law. The second impulse models the effect of friction.
The third impulse models a necessary correction if the friction impulse was too strong and caused a reflection.
The characteristics of the geometry can be set by the parameters:
The parameter s_small in the advanced menu reduces the stiffness of the friction for slip velocities in the range from zero up to s_small.
| Type | Name | Default | Description |
|---|---|---|---|
| Radius | ra | 1 | radius of sphere at frame a [m] |
| Radius | rb | 1 | radius of sphere at frame b [m] |
| Real | elasticity | 1.0 | Elasticity of impuls |
| Real | muR | 0.0 | friction coefficient |
| Advanced | |||
| Position | s_small | 1e-4 | critical length [m] |
| Real | contactDuration | 1e-9 | time to handle the impulses |
| Boolean | useParameters | true | use the parameter values. |
| Type | Name | Description |
|---|---|---|
| IFrame_a | frame_a | |
| output BooleanOutput | y | |
| IFrame_b | frame_b |
model CollisionSphereSphere
"models the collision between two spheres"
import SI = Modelica.SIunits;
Interfaces.IFrame_a frame_a;
parameter SI.Radius ra = 1 "radius of sphere at frame a";
parameter SI.Radius rb = 1 "radius of sphere at frame b";
parameter SI.Position s_small = 1e-4 "|Advanced||critical length";
parameter Real elasticity = 1.0 "Elasticity of impuls";
parameter Real muR = 0.0 "friction coefficient";
parameter Real contactDuration = 1e-9
"|Advanced||time to handle the impulses";
parameter Boolean useParameters = true "|Advanced||use the parameter values.";
//the following variables are determined by the parameters above if useParameter = true
SI.Radius ra_ "optional variable radius of sphere at frame a";
SI.Radius rb_ "optional variable radius of sphere at frame b";
Real elasticity_ "optional variable elasticity";
Real muR_ "optional variable friction coefficient";
protected
Real[3,3] R_a "orientation of frame a at the impulse time";
Real[3,3] R_b "orientation of frame a at the impulse time";
SI.Distance r[3]
"vector pointing from center of sphere a to center of sphere b";
Real eR[3] "normalized variant of r";
Real noteR[3] "a vector that has any value but not r";
Real eA[3] "unit vector that is normal to r";
Real eB[3] "unit vector that is normal to r and eA.";
//eR, eA, eB build up an orthonormal coordinate system, where eR is pointing in contact direction.
Boolean contact "contact signal";
Integer seqState
"state in the impluse sequence (0=impact, 1=friction, 2=correction)";
Real frictionImpulseTime "time of the succeeding friction Impulse";
Real correctionImpulseTime "time of the succeeding correction Impulse";
SI.Impulse F[3] "force impulse between the two frames";
SI.Velocity vA[3] "rel. velocity of the two frames right before the impulse";
SI.Velocity Vm[3] "average rel. velocity during the impulse";
//variables of the impact impulse
SI.Impulse FR "force impulse in direction of eR";
SI.Impulse FA0 "force impulse in direction of eA";
SI.Impulse FB0 "force impulse in direction of eB";
SI.Velocity VmR0 "average velocity in direction of eR";
//variables of the friction impulse
SI.Impulse FA1 "force impulse in direction of eA";
SI.Impulse FB1 "force impulse in direction of eB";
SI.Impulse FR1 "force impulse in direction of eR";
SI.Velocity VFricElast[3]
"becomes non-zero if the friction impulse caused more than an elastic impulse";
//eC, eD, eE build up an orthonormal coordinate system where eC points into the direction
//of the lateral velocity difference (slippage)
Real eC[3];
Real noteC[3];
Real eD[3];
Real eE[3];
//variables of the correction impulse
SI.Impulse FD2 "force impulse in direction of eD";
SI.Impulse FE2 "force impulse in direction of eE";
SI.Velocity VmC2 "average velocity in direction of eC";
public
Modelica.Blocks.Interfaces.BooleanOutput y;
Interfaces.IFrame_b frame_b;
initial equation
contact = false;
seqState = -1;
frictionImpulseTime = 0;
correctionImpulseTime = 0;
equation
algorithm
//reset contact signal to false
when contact then
contact :=false;
end when;
//detect collision and trigger event
when sqrt(r*r) <= (ra_+rb_) then
contact :=true;
seqState := 0;
frictionImpulseTime :=time + contactDuration/2;
end when;
//trigger event for friction impulse
when (time >= frictionImpulseTime) and (seqState == 0) then
contact :=true;
seqState := 1;
frictionImpulseTime := 0;
correctionImpulseTime := time + contactDuration/2;
end when;
//trigger event for correction impulse
when (time >= correctionImpulseTime) and (seqState == 1) then
contact :=true;
seqState := 2;
correctionImpulseTime := 0;
end when;
equation
if useParameters then
ra_ = ra;
rb_ = rb;
elasticity_ = elasticity;
muR_ = muR;
end if;
//build up coordinate system eR, eA, eB at the moment of collision.
r = frame_b.P.x- frame_a.P.x;
when contact and (seqState == 0) then
eR = r/sqrt(r*r);
noteR = if abs(eR[1]) > 0.1 then {0,1,0} else (if abs(eR[2])
> 0.1 then {0,0,1} else {1,0,0});
eA = cross(eR, noteR)/sqrt(cross(eR, noteR)*cross(eR, noteR));
eB = cross(eA, eR);
end when;
//state situation right before the impulse
when contact then
vA = (pre(frame_b.P.v)+cross(transpose(R_b)*pre(frame_b.P.w),-eR*rb_)) -
(pre(frame_a.P.v)+cross(transpose(R_a)*pre(frame_a.P.w),eR*ra_));
R_a = frame_a.P.R;
R_b = frame_b.P.R;
end when;
//store the impact impulse in FR
when contact then
FR = F*eR;
end when;
//impact impulse
when contact and (seqState == 0) then
VmR0 = (1-elasticity_)*(vA*eR)/2;
FA0 = 0;
FB0 = 0;
end when;
//friction impulse
when contact and (seqState == 1) then
FR1 = 0;
FA1 = -muR_*abs(pre(FR))*((vA/sqrt(vA*vA))*eA);
FB1 = -muR_*abs(pre(FR))*((vA/sqrt(vA*vA))*eB);
VFricElast[1] = if sign(vA[1])*Vm[1] >= abs(vA[1]/2) then 0 else Vm[1]- (vA[1]/2);
VFricElast[2] = if sign(vA[2])*Vm[2] >= abs(vA[2]/2) then 0 else Vm[2]- (vA[2]/2);
VFricElast[3] = if sign(vA[3])*Vm[3] >= abs(vA[3]/2) then 0 else Vm[3]- (vA[3]/2);
end when;
//correction impulse
when contact and (seqState == 2) and (pre(VFricElast)*pre(VFricElast) > 0) then
eC = if pre(VFricElast)*pre(VFricElast) < s_small^2 then {1,0,0} else
pre(VFricElast)/sqrt(pre(VFricElast)*pre(VFricElast));
noteC = if abs(eC[1]) > 0.1 then {0,1,0} else (if abs(eC[2])
> 0.1 then {0,0,1} else {1,0,0});
eD = cross(eC, noteC)/sqrt(cross(eC, noteC)*cross(eC, noteC));
eE = cross(eD, eC);
VmC2 = sqrt(pre(VFricElast)*pre(VFricElast));
FD2 = 0;
FE2 = 0;
end when;
//state the impulse dependent equations
if contact then
if (seqState == 0) then //further equations for the impact impulse
Vm*eR = VmR0;
F*eA = FA0;
F*eB = FB0;
else
if (seqState == 1) then //further equations fot the friction impulse
F*eR = FR1;
F*eA = FA1;
F*eB = FB1;
else
//further equations for the correction impulse
if (seqState == 2) and (pre(VFricElast)*pre(VFricElast) > 0) then
Vm*eC = VmC2;
F*eD = FD2;
F*eE = FE2;
else
F = zeros(3);
end if;
end if;
end if;
else
F = zeros(3);
end if;
//propagate contact signal
y = contact;
//state equations for the translational domain
Vm = (frame_b.Vm+cross(transpose(R_b)*frame_b.Wm,-eR*rb_)) -
(frame_a.Vm+cross(transpose(R_a)*frame_a.Wm,eR*ra_));
F = -frame_b.F;
F = frame_a.F;
//state equations for the rotational domain
R_b*cross(-eR*rb_,F) = -frame_b.T;
R_a*cross(eR*ra_,F) = frame_a.T;
//define continuous connector variables
frame_a.f = zeros(3);
frame_a.t = zeros(3);
frame_b.f = zeros(3);
frame_b.t = zeros(3);
end CollisionSphereSphere;
MultiBondLib.Mechanics3DwithImpulses.Contacts.NoCollision
| Type | Name | Description |
|---|---|---|
| IFrame_a | frame_a | |
| output BooleanOutput | y | |
| IFrame_b | frame_b |
model NoCollision "dummy collision element" import SI = Modelica.SIunits; Interfaces.IFrame_a frame_a; public Modelica.Blocks.Interfaces.BooleanOutput y; Interfaces.IFrame_b frame_b; equation y = false; zeros(3) = -frame_b.F; zeros(3) = frame_a.F; zeros(3) = -frame_b.T; zeros(3) = frame_a.T; frame_a.f = zeros(3); frame_a.t = zeros(3); frame_b.f = zeros(3); frame_b.t = zeros(3); end NoCollision;
MultiBondLib.Mechanics3DwithImpulses.Contacts.EnergyInjection
Please note that this element introduces a quadratic equation into the system.
This might result in a larger system of non-linear equations that has to be solved
at corresponding discrete event.
| Type | Name | Default | Description |
|---|---|---|---|
| Position | n[3] | {1,0,0} | direction of the impulse [m] |
| Energy | E | 1 | Energy that should be introduced into the system [J] |
| Type | Name | Description |
|---|---|---|
| IFrame_a | frame_a | |
| input BooleanInput | u |
model EnergyInjection "dummy collision element"
import SI = Modelica.SIunits;
parameter SI.Position n[3] = {1,0,0} "direction of the impulse";
final parameter SI.Position eN[3] = n/sqrt(n*n);
parameter SI.Energy E = 1 "Energy that should be introduced into the system";
SI.Impulse Fn;
SI.Velocity Vm_n;
Interfaces.IFrame_a frame_a;
Modelica.Blocks.Interfaces.BooleanInput u;
protected
Real[3,3] R_a "orientation of frame a at the impulse time";
equation
when u then
R_a = frame_a.P.R;
end when;
zeros(3) = frame_a.T;
Fn * (eN * R_a) = frame_a.F;
Vm_n = frame_a.Vm * (eN*R_a);
frame_a.f = zeros(3);
frame_a.t = zeros(3);
if u then
-Fn*abs(Vm_n) = E;
else
Fn = 0;
end if;
end EnergyInjection;