Stribeck Friction — Robotics/Actuators And Drivetrain
Robotics/Actuators_And_Drivetrain/Stribeck_Friction · 1 input / 1 output port(s) at insert · exports to Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text
Description#
The block's own DESCRIPTION_HTML, rendered verbatim — the same text the config dialog's info panel and the library navigator show. Fix a wrong sentence in the block's .cpp (R-D9), never here.
Stribeck Friction
Robotics / Actuators And Drivetrain
The friction torque of a real joint as a function of its speed: F = sign(v)·(Fc + (Fs−Fc)· e−(v/vs)²) + b·v, applied entry by entry.
Three effects in one curve: Coulomb friction that is constant in magnitude and flips with direction, a static excess that decays over the Stribeck velocity, and a viscous term proportional to speed. The middle one is why this block exists – just above rest, friction falls as speed rises. That negative slope is what makes a slow axis stick and slip, and what makes a position loop hunt around its setpoint instead of settling.
Ports
- v – the relative speed across the friction interface (rad/s for a joint, m/s for a slide), any size [m,n].
- F – the friction torque or force, the same size as the input. It opposes motion: positive speed gives positive F, so subtract it from the driving torque rather than adding it.
Parameters
- Coulomb Friction (N.m) – Fc, the constant magnitude that remains at speed. Zero or more.
- Static Friction (N.m) – Fs, the magnitude approached as the speed goes to zero. Zero or more. The difference Fs−Fc is the entire Stribeck effect: set them equal and this block is exactly Coulomb + viscous friction, with nothing the existing Coulomb & Viscous Friction block does not already do.
- Stribeck Velocity (rad/s) – vs, positive: the speed scale over which the static excess decays. At |v| = vs the excess is down to 37%, and by 2vs it is 1.8% – so this is the knob that says how narrow the dip is, and it should be set against the speeds the mechanism actually runs at.
- Viscous Damping (N.m.s) – b, zero or more, the slope of the curve away from the origin.
- Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.
Code export
All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text. What the core carries is not the four parameters but the folded constants Fc, Fs−Fc, 1/vs and b – the reciprocal is computed once at export so that no per-sample division reaches any target. They are not retunable on the generated core; re-export to change a mechanism.
The three HDL targets are simulation-only: they carry the
arithmetic in real and quantize only at the port boundary. A
Gaussian has no Q16.16 form to call, so offering them as synthesizable would be
a claim the generated core could not keep.
Simulink bridge
No equivalent (Support::None). Simulink's
Coulomb & Viscous Friction has no Stribeck term, and the friction
models that do ship in Simscape, which is not installed on this
machine (measured). This block is deliberately not a mode on ICore's
own Coulomb & Viscous Friction, which is bridged 1:1 onto that
Simulink block – a mode there would either break the mapping or carry a
config that silently does not cross. To approximate it in Simulink: the
Coulomb & Viscous Friction block plus a Math Function
(exp) branch on the squared, scaled speed.
Notes
- Algebraic, stateless and memoryless – F depends only on the current v, so the block cannot break an algebraic loop, and its output is a pure function of its input rather than of the path the input took.
- At rest it reports zero. sign(0) = 0, the same convention Coulomb & Viscous Friction and Simulink use. This is a friction force curve, not a stiction solver: it does not hold a stopped joint against an applied torque, and a model that needs that behaviour needs a state and a velocity threshold, which is a different block.
- The curve is discontinuous at the origin, jumping by 2Fs as v crosses zero. That is the physics being modelled, not an artefact – but it does mean a continuous solver can take very small steps near zero speed, and a stiff mechanism may be better served by running the model discretely.
- Nonlinear, and deliberately carries no state space: both
signandexpare nonlinear and the curve is not even continuous, so a fabricated linear form would let model reduction merge matrices that do not describe this block. - Fs below Fc is accepted and simply inverts the dip into a bump – friction that rises from rest. It is unusual but it is a real effect in some lubricated contacts, so the block does not refuse it.
- Pairs with Two Mass Drivetrain and DC Motor: subtract this block's output from the driving torque. Friction on the load side is what a Stall Detector eventually sees.
Code facts#
| Fact | Value |
|---|---|
| registered type | Robotics/Actuators_And_Drivetrain/Stribeck_Friction |
| family | Robotics/Actuators_And_Drivetrain |
| solver environment class | ICoreBlock_0_Robotics_1_Actuators_And_Drivetrain_2_Stribeck_Friction |
| source | src/ICoreSDK/ICoreBlockLibrary/Blocks/Robotics/Actuators_And_Drivetrain/Stribeck_Friction/ICoreBlock_0_Robotics_1_Actuators_And_Drivetrain_2_Stribeck_Friction.cpp |
| header | src/ICoreSDK/ICoreBlockLibrary/Blocks/Robotics/Actuators_And_Drivetrain/Stribeck_Friction/ICoreBlock_0_Robotics_1_Actuators_And_Drivetrain_2_Stribeck_Friction.h |
| default size on canvas | 132 × 84 px |
| ports at insert | 1 in, 1 out |
| code generators implemented | Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text |
Ports#
| # | Direction | Signal type | Description label |
|---|---|---|---|
| 1 | in | ICoreDouble | v |
| 2 | out | ICoreDouble | F |
Ports the constructor creates. A block whose port list changes with its configuration adds or removes ports at load time; the count above is the one a freshly inserted block has.
Configuration variables#
| Config variable | Default | Simulink parameter |
|---|---|---|
Coulomb Friction (N.m) | 1 | — |
Static Friction (N.m) | 1.5 | — |
Stribeck Velocity (rad/s) | 0.1 | — |
Viscous Damping (N.m.s) | 0.1 | — |
Every block also carries Sampling Time (s) from ICoreBlockSolverEnvironment: zero or less inherits the solver's rate, a positive value runs the block at that period.
Simulink bridge#
| support | Support::None |
| Simulink path | — |
| port-count rule | PortsParam::None |
SampleTime parameter | yes |
Caveat (shown to the user): no Simulink equivalent available: simulink/Discontinuities/Coulomb & Viscous Friction carries no Stribeck term, and the friction models that do ship in Simscape, which is not installed on this machine (measured). Note this block is deliberately NOT a mode on ICore's own Coulomb_And_Viscous_Friction, which is bridged 1:1 onto that Simulink block - a mode there would break the mapping. To approximate it in Simulink: that block plus a Math Function (exp) branch on the squared, scaled speed
Catalog contract: src/ICoreSDK/ICoreCoder/ICoreCommandSystem/SimulinkBridge/ICoreSimulinkBlockCatalog.h
Description vs code#
The lists agree. check_block_descriptions.py finds no disagreement between the description's Ports, Parameters, Code export and Simulink bridge lists and the code's.
The verdict above is
tools/docs/check_block_descriptions.py(P7.1), which compares LISTS. It cannot read a sentence: "stateless" on a block with a state, an initial-value semantic the recursion does not implement, a "not synthesizable" caveat the HDL banner contradicts. That is the agent audit (P7.3) on BLOCK_DESCRIPTION_AUDIT.md, and this tool's green is not a substitute for one.
File banner (developer view)#
The top comment of the block's .cpp — the maths, the realization and the export strategy, addressed to whoever changes it. It must not contradict the description above (P7.5).
Stribeck Friction — the dip that makes slow axes stick and slip F = sign(v) * ( Fc + (Fs - Fc) * exp(-(v/vs)^2) ) + b*v
Coulomb friction Fc, a static excess (Fs - Fc) decaying over the Stribeck velocity vs, and a viscous term b*v. The block exists for the region near v = 0, where friction FALLS as speed rises: a negative slope, which is what turns a slow feed into stick-slip and a servo holding position into a hunting oscillation.
⚠ NOT A MODE ON Coulomb_And_Viscous_Friction. That block is Support::Both and bridged 1:1 onto a Simulink block with no Stribeck term; a mode there would break a shipped mapping.
⚠ sign(0) = 0, matching Coulomb_And_Viscous_Friction and Simulink. This is a friction FORCE curve, not a stiction solver -- at rest it reports zero rather than holding, and the description says so where a user will read it.
⚠ THE EXPONENTIAL IS THE BLOCK, AND (Fs - Fc) IS ITS AMPLITUDE. At Fs = Fc the term is multiplied by zero and this degenerates EXACTLY into Coulomb + viscous -- a core that emitted no exponential at all would then be bit-identical to a correct one. The rig runs the two well apart for that reason, and the description warns the same thing.
⚠ THE THREE HDL TARGETS ARE SIMULATION-ONLY
real: a Gaussian has no Q16.16 form to call.
Sample results#
| t | in ICoreDouble-Out-0 | out ICoreDouble-Out-0 |
|---|---|---|
| 0 | -2 | -1.2 |
| 0.4 | 0.5 | 1.05 |
| 0.8 | -2 | -1.2 |
| 1.2 | 0.5 | 1.05 |
| 1.6 | -2 | -1.2 |
| 2 | 0.5 | 1.05 |
| 2.4 | -2 | -1.2 |
| 2.8 | 0.5 | 1.05 |
| 3.2 | -2 | -1.2 |
| 3.6 | 0.5 | 1.05 |
| 4 | -2 | -1.2 |
| 4.4 | 0.5 | 1.05 |
| 4.8 | -2 | -1.2 |
| 5.2 | 0.5 | 1.05 |
Every 4th of 60 samples, from the table stimulus.
The same rig also ran:
| Stimulus | What it is | Output range |
|---|---|---|
impulse | Impulse: one sample of 1 at k = 5, 0 elsewhere (Repeating Sequence Stair) | 0 … 1.1 |
ramp | Ramp: slope 1 from t = 0 | 0 … 1.58 |
sine | Sine Wave: amplitude 1, 2 rad/s, no phase, no bias | -1.361 … 1.473 |
step | Step: 0 -> 1 at t = 1 s | 0 … 1.1 |
Plotted: table — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample
Category static · sample time 0.1 · 60 steps · commit ccf005c8 · produced by docsSample --out <folder> --steps 60 · data docs/generated/samples/Robotics__Actuators_And_Drivetrain__Stribeck_Friction.json · the SVG is generated from those numbers by tools/docs/plot_svg.py, so it is a run and not a drawing (R-D10).