OneWayClutch

model OneWayClutch "Parallel connection of freewheel and clutch"
    extends Modelica.Mechanics.Rotational.Icons.Clutch;
    extends Modelica.Mechanics.Rotational.Interfaces.PartialCompliantWithRelativeStates;

    parameter Real mue_pos[:,2] = [0,0.5] "[w,mue] positive sliding friction coefficient (w_rel>=0)";
    parameter Real peak(final min = 1) = 1 "Peak for maximum value of mue at w==0 (mue0_max = peak*mue_pos[1,2])";
    parameter Real cgeo(final min = 0) = 1 "Geometry constant containing friction distribution assumption";
    parameter SI.Force fn_max(final min = 0, start = 1) "Maximum normal force";
    parameter SI.AngularVelocity w_small = 1e+10 "Relative angular velocity near to zero if jumps due to a reinit(..) of the velocity can occur (set to low value only if such impulses can occur)"
        annotation (Dialog(tab = "Advanced"));

    extends Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT;

    Real u "Normalized force input signal (0..1)";
    SI.Force fn "Normal force (fn=fn_max*inPort.signal)";
    Boolean startForward(start = false) "true, if w_rel=0 and start of forward sliding or w_rel > w_small";
    Boolean locked(start = false) "true, if w_rel=0 and not sliding";
    Boolean stuck(start = false) "w_rel=0 (locked or start forward sliding)";
protected
    SI.Torque tau0 "Friction torque for w=0 and sliding";
    SI.Torque tau0_max "Maximum friction torque for w=0 and locked";
    Real mue0 "Friction coefficient for w=0 and sliding";
    Boolean free "true, if frictional element is not active";
    Real sa(final unit = "1") "Path parameter of tau = f(a_rel) Friction characteristic";
    constant Real eps0 = 1e-4 "Relative hysteresis epsilon";
    SI.Torque tau0_max_low "Lowest value for tau0_max";
    parameter Real peak2 = max([peak,1 + eps0]);
    constant SI.AngularAcceleration unitAngularAcceleration = 10000;
    constant SI.Torque unitTorque = 1;
public
    Modelica.Blocks.Interfaces.RealInput f_normalized "Normalized force signal 0..1 (normal force = fn_max*f_normalized; clutch is engaged if > 0)"
        annotation (Placement(transformation(
            origin = {0, 110},
            extent = {
                {20, -20}, 
                {-20, 20}},
            rotation = 90)));
equation
    u = f_normalized;
    a_rel = unitAngularAcceleration * (if locked then 0 else sa - tau0 / unitTorque);
    fn = if free then 0 else fn_max * u;
    free = u <= 0;
    locked = pre(stuck) and not startForward;
    lossPower = if stuck then 0 else tau * w_rel;
    mue0 = Modelica.Math.Vectors.interpolate(mue_pos[:,1], mue_pos[:,2], 0, 1);
    stuck = locked or w_rel <= 0;
    tau = if locked then sa * unitTorque else if free then 0 else cgeo * fn * Modelica.Math.Vectors.interpolate(mue_pos[:,1], mue_pos[:,2], w_rel, 1);
    tau0 = mue0 * cgeo * fn;
    tau0_max = if free then tau0_max_low else peak2 * tau0;
    startForward = pre(stuck) and (tau0_max / unitTorque < sa or pre(startForward) and tau0 / unitTorque < sa or w_small < w_rel) or initial() and 0 < w_rel;
    tau0_max_low = eps0 * mue0 * cgeo * fn_max;

    annotation (
        Icon(
            coordinateSystem(
                preserveAspectRatio = true,
                extent = {
                    {-100, -100}, 
                    {100, 100}}),
            graphics = {
                Text(
                    extent = {
                        {-150, -110}, 
                        {150, -70}},
                    textString = "%name",
                    lineColor = {0, 0, 255}), 
                Polygon(
                    points = {
                        {-10, 30}, 
                        {50, 0}, 
                        {-10, -30}, 
                        {-10, 30}},
                    fillPattern = FillPattern.Solid), 
                Line(
                    visible = useHeatPort,
                    points = {
                        {-100, -99}, 
                        {-100, -40}, 
                        {0, -40}},
                    color = {191, 0, 0},
                    pattern = LinePattern.Dot)}),
        Documentation(info = "<html>\n<p>\nThis component models a <strong>one-way clutch</strong>, i.e., a component with\ntwo flanges where friction is present between the two flanges\nand these flanges are pressed together via a normal force. These\nflanges may be sliding with respect to each other.\n</p>\n<p>\nA one-way-clutch is an element where a&nbsp;clutch is connected in parallel\nto a&nbsp;free wheel. This special element is provided, because such\na parallel connection introduces an ambiguity into the model\n(the constraint torques are not uniquely defined when both\nelements are stuck) and this element resolves it by introducing\n<strong>one</strong> constraint torque only instead of two constraints.\n</p>\n<p>\nNote, initial values have to be chosen for the model such that the\nrelative speed of the one-way-clutch &ge;&nbsp;0. Otherwise, the configuration\nis physically not possible and an error occurs.\n</p>\n<p>\nThe normal force&nbsp;fn has to be provided as input signal f_normalized in a normalized form\n(0&nbsp;&le;&nbsp;f_normalized&nbsp;&le;&nbsp;1),\nfn&nbsp;=&nbsp;fn_max&nbsp;*&nbsp;f_normalized, where fn_max has to be provided as parameter.\n</p>\n<p>\nThe friction in the clutch is modeled in the following way.\nWhen the relative angular velocity is positive, the friction torque is a\nfunction of the velocity dependent friction coefficient mue(w_rel), of\nthe normal force&nbsp;fn, and of a geometry constant cgeo which takes into\naccount the geometry of the device and the assumptions on the friction\ndistributions:\n</p>\n\n<blockquote><pre>\nfrictional_torque = <strong>cgeo</strong> * <strong>mue</strong>(w_rel) * <strong>fn</strong>\n</pre></blockquote>\n\n<p>\nTypical values of coefficients of friction:\n</p>\n\n<blockquote><pre>\ndry operation   :  <strong>mue</strong> = 0.2 .. 0.4\noperating in oil:  <strong>mue</strong> = 0.05 .. 0.1\n</pre></blockquote>\n\n<p>\nThe geometry constant is calculated - under the\nassumption of a uniform rate of wear at the friction surfaces - in the following way:\n</p>\n\n<blockquote><pre>\n<strong>cgeo</strong> = <strong>N</strong>*(<strong>r0</strong> + <strong>ri</strong>)/2\n</pre></blockquote>\n\n<p>\nwhere <strong>ri</strong> is the inner radius,\n<strong>ro</strong> is the outer radius and&nbsp;<strong>N</strong> is the number of friction interfaces,\n</p>\n\n<p>\nThe positive part of the friction characteristic <strong>mue</strong>(w_rel),\nw_rel&nbsp;>=&nbsp;0, is defined via table mue_pos (first column = w_rel,\nsecond column = mue). Currently, only linear interpolation in\nthe table is supported.\n</p>\n<p>\nWhen the relative angular velocity w_rel becomes zero, the elements\nconnected by the friction element become stuck, i.e., the relative\nangle remains constant. In this phase the friction torque is\ncalculated from a torque balance due to the requirement that\nthe relative acceleration shall be zero.  The elements begin\nto slide when the friction torque exceeds a threshold value,\ncalled the  maximum static friction torque, computed via:\n</p>\n\n<blockquote><pre>\nfrictional_torque = <strong>peak</strong> * <strong>cgeo</strong> * <strong>mue</strong>(w_rel=0) * <strong>fn</strong>,   (<strong>peak</strong> >= 1)\n</pre></blockquote>\n\n<p>\nThis procedure is implemented in a \"clean\" way by state events and\nleads to continuous/discrete systems of equations if friction elements\nare dynamically coupled. The method is described in\n(see also a short sketch in <a href=\"modelica://Modelica.Mechanics.Rotational.UsersGuide.ModelingOfFriction\">UsersGuide.ModelingOfFriction</a>):\n</p>\n<dl>\n<dt>Otter M., Elmqvist H., and Mattsson S.E. (1999):</dt>\n<dd><strong>Hybrid Modeling in Modelica based on the Synchronous\n    Data Flow Principle</strong>. CACSD'99, Aug. 22.-26, Hawaii.</dd>\n</dl>\n\n<p>\nSee also the discussion\n<a href=\"modelica://Modelica.Mechanics.Rotational.UsersGuide.StateSelection\">State Selection</a>\nin the User's Guide of the Rotational library.\n</p>\n</html>"));
end OneWayClutch;