Name | Description |
---|---|
![]() | models the collision between a spheres and a plane |
![]() | models the collision between two spheres |
![]() | dummy collision element |
![]() | dummy collision element |
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;
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;
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;
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;