SupportFriction

model SupportFriction "Coulomb friction in support"
    extends Modelica.Mechanics.Translational.Interfaces.PartialElementaryTwoFlangesAndSupport2;
    extends Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT;

    parameter Real f_pos[:,2] = [0,1] "[v, f] Positive sliding friction characteristic (v>=0)";
    parameter Real peak(final min = 1) = 1 "Peak for maximum friction force at w==0 (f0_max = peak*f_pos[1,2])";

    extends Translational.Interfaces.PartialFriction;

    SI.Position s "= flange_a.s - support.s";
    SI.Force f "Friction force";
    SI.Velocity v "Absolute velocity of flange_a and flange_b";
    SI.Acceleration a "Absolute acceleration of flange_a and flange_b";
equation
    a = der(v);
    f = if locked then sa * unitForce else if startForward then Modelica.Math.Vectors.interpolate(f_pos[:,1], f_pos[:,2], v, 1) else if startBackward then -Modelica.Math.Vectors.interpolate(f_pos[:,1], f_pos[:,2], -v, 1) else if pre(mode) == Forward then Modelica.Math.Vectors.interpolate(f_pos[:,1], f_pos[:,2], v, 1) else -Modelica.Math.Vectors.interpolate(f_pos[:,1], f_pos[:,2], -v, 1);
    s = flange_a.s - s_support;
    v = der(s);
    a_relfric = a;
    f0 = Modelica.Math.Vectors.interpolate(f_pos[:,1], f_pos[:,2], 0, 1);
    f0_max = peak * f0;
    free = false;
    lossPower = f * v_relfric;
    v_relfric = v;
    flange_a.s = flange_b.s;
    flange_a.f + flange_b.f - f = 0;

    annotation (
        Documentation(info = "<html>\n<p>\nThis element describes <strong>Coulomb friction</strong> in <strong>support</strong>,\ni.e., a frictional force acting between a flange and the housing.\nThe positive sliding friction force \"f\" has to be defined\nby table \"f_pos\" as function of the absolute velocity \"v\".\nE.g.\n</p>\n<pre>\n       v |   f\n      ---+-----\n       0 |   0\n       1 |   2\n       2 |   5\n       3 |   8\n</pre>\n<p>\ngives the following table:\n</p>\n<pre>\n   f_pos = [0, 0; 1, 2; 2, 5; 3, 8];\n</pre>\n<p>\nCurrently, only linear interpolation in the table is supported.\nOutside of the table, extrapolation through the last\ntwo table entries is used. It is assumed that the negative\nsliding friction force has the same characteristic with negative\nvalues. Friction is modelled in the following way:\n</p>\n<p>\nWhen the absolute velocity \"v\" is not zero, the friction force\nis a function of v and of a constant normal force. This dependency\nis defined via table f_pos and can be determined by measurements,\ne.g., by driving the gear with constant velocity and measuring the\nneeded driving force (= friction force).\n</p>\n<p>\nWhen the absolute velocity becomes zero, the elements\nconnected by the friction element become stuck, i.e., the absolute\nposition remains constant. In this phase the friction force is\ncalculated from a force balance due to the requirement, that\nthe absolute acceleration shall be zero.  The elements begin\nto slide when the friction force exceeds a threshold value,\ncalled the maximum static friction force, computed via:\n</p>\n<pre>\n   maximum_static_friction = <strong>peak</strong> * sliding_friction(v=0)  (<strong>peak</strong> >= 1)\n</pre>\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 which have to be solved by appropriate\nnumerical methods. 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<p>\nMore precise friction models take into account the elasticity of the\nmaterial when the two elements are \"stuck\", as well as other effects,\nlike hysteresis. This has the advantage that the friction element can\nbe completely described by a differential equation without events. The\ndrawback is that the system becomes stiff (about 10-20 times slower\nsimulation) and that more material constants have to be supplied which\nrequires more sophisticated identification. For more details, see the\nfollowing references, especially (Armstrong and Canudas de Wit 1996):\n</p>\n<dl>\n<dt>Armstrong B. (1991):</dt>\n<dd><strong>Control of Machines with Friction</strong>. Kluwer Academic\n    Press, Boston MA.<br><br></dd>\n<dt>Armstrong B., and Canudas de Wit C. (1996):</dt>\n<dd><strong>Friction Modeling and Compensation.</strong>\n    The Control Handbook, edited by W.S.Levine, CRC Press,\n    pp. 1369-1382.<br><br></dd>\n<dt>Canudas de Wit C., Olsson H., &Aring;str&ouml;m K.J., and Lischinsky P. (1995):</dt>\n<dd><strong>A new model for control of systems with friction.</strong>\n    IEEE Transactions on Automatic Control, Vol. 40, No. 3, pp. 419-425.<br><br></dd>\n</dl>\n\n</html>"),
        Icon(
            coordinateSystem(
                preserveAspectRatio = true,
                extent = {
                    {-100, -100}, 
                    {100, 100}}),
            graphics = {
                Polygon(
                    points = {
                        {-50, -50}, 
                        {-10, -90}, 
                        {-10, -100}, 
                        {10, -100}, 
                        {10, -90}, 
                        {50, -50}, 
                        {-50, -50}},
                    lineColor = {95, 95, 95},
                    fillColor = {131, 175, 131},
                    fillPattern = FillPattern.Solid), 
                Ellipse(
                    extent = {
                        {-48, -10}, 
                        {-28, -30}},
                    lineColor = {0, 127, 0},
                    fillPattern = FillPattern.Sphere,
                    fillColor = {255, 255, 255}), 
                Ellipse(
                    extent = {
                        {-10, -10}, 
                        {10, -30}},
                    lineColor = {0, 127, 0},
                    fillPattern = FillPattern.Sphere,
                    fillColor = {255, 255, 255}), 
                Ellipse(
                    extent = {
                        {30, -10}, 
                        {50, -30}},
                    lineColor = {0, 127, 0},
                    fillPattern = FillPattern.Sphere,
                    fillColor = {255, 255, 255}), 
                Ellipse(
                    extent = {
                        {-50, 30}, 
                        {-30, 10}},
                    lineColor = {0, 127, 0},
                    fillPattern = FillPattern.Sphere,
                    fillColor = {255, 255, 255}), 
                Ellipse(
                    extent = {
                        {-10, 30}, 
                        {10, 10}},
                    lineColor = {0, 127, 0},
                    fillPattern = FillPattern.Sphere,
                    fillColor = {255, 255, 255}), 
                Ellipse(
                    extent = {
                        {30, 30}, 
                        {50, 10}},
                    lineColor = {0, 127, 0},
                    fillPattern = FillPattern.Sphere,
                    fillColor = {255, 255, 255}), 
                Rectangle(
                    extent = {
                        {-90, 10}, 
                        {90, -10}},
                    lineColor = {0, 127, 0},
                    fillColor = {160, 215, 160},
                    fillPattern = FillPattern.Solid), 
                Text(
                    extent = {
                        {-150, 100}, 
                        {150, 60}},
                    textString = "%name",
                    lineColor = {0, 0, 255}), 
                Polygon(
                    points = {
                        {-60, 30}, 
                        {60, 30}, 
                        {60, 20}, 
                        {80, 20}, 
                        {80, 50}, 
                        {-80, 50}, 
                        {-80, 20}, 
                        {-60, 20}, 
                        {-60, 30}},
                    lineColor = {95, 95, 95},
                    fillPattern = FillPattern.Solid,
                    fillColor = {131, 175, 131}), 
                Line(
                    visible = useHeatPort,
                    points = {
                        {-100, -100}, 
                        {-100, -20}, 
                        {0, -20}},
                    color = {191, 0, 0},
                    pattern = LinePattern.Dot), 
                Polygon(
                    points = {
                        {-60, -30}, 
                        {60, -30}, 
                        {60, -20}, 
                        {80, -20}, 
                        {80, -50}, 
                        {-80, -50}, 
                        {-80, -20}, 
                        {-60, -20}, 
                        {-60, -30}},
                    lineColor = {95, 95, 95},
                    fillPattern = FillPattern.Solid,
                    fillColor = {131, 175, 131})}));
end SupportFriction;