{"id":1818,"date":"2026-10-10T10:55:18","date_gmt":"2026-10-10T14:55:18","guid":{"rendered":"https:\/\/web.uri.edu\/nld\/?page_id=1818"},"modified":"2026-10-10T21:02:07","modified_gmt":"2026-10-11T01:02:07","slug":"kinematics-toolbox","status":"publish","type":"page","link":"https:\/\/web.uri.edu\/nld\/kinematics-toolbox\/","title":{"rendered":"Kinematics toolbox"},"content":{"rendered":"\n<div class=\"nld-page-band\" style=\"background:#132433;padding:28px 32px;display:flex;align-items:center;justify-content:space-between;gap:24px;margin:0 0 32px\">\n<div><p style=\"margin:0 0 10px;font-size:13px;line-height:16px;letter-spacing:0.12em;text-transform:uppercase;font-weight:600;color:#A9B6BF\"><span style=\"display:inline-block;width:24px;height:4px;background:#D98A52;vertical-align:middle;margin-right:10px\"><\/span>Nonlinear Dynamics Laboratory<\/p>\n<h1 style=\"color:#F7F6F2;font-size:36px;line-height:42px;margin:0\">Kinematics toolbox<\/h1><\/div>\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/web.uri.edu\/nld\/wp-content\/uploads\/sites\/1815\/nld-hero-on-navy.jpg\" alt=\"\" width=\"96\" height=\"96\" style=\"width:96px;height:auto;flex:none\">\n<\/div>\n\n\n<div class=\"oembed oembed-youtu-be\" style=\"\" data-url=\"https:\/\/youtu.be\/HQirvoC7scU\"><iframe loading=\"lazy\" title=\"kinematics toolbox\" width=\"1000\" height=\"563\" src=\"https:\/\/www.youtube.com\/embed\/HQirvoC7scU?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Model-free differentiation and integration of measured motion. Get velocity and acceleration from a noisy displacement record, velocity and displacement from a drifting accelerometer, or fuse both channels. No model of the system is used, only a regularity prior on the signal. MATLAB and Python, MIT license.<\/p>\n\n\n\n<p style=\"margin:8px 0 24px\"><a href=\"https:\/\/github.com\/nld-uri\/kinematics-toolbox\" style=\"display:inline-block;background:#9A5323;color:#FFFFFF;padding:10px 16px;border-radius:2px;text-decoration:none;font-weight:600;margin:0 8px 8px 0\">Code on GitHub<\/a><a href=\"https:\/\/github.com\/nld-uri\/kinematics-toolbox\/blob\/main\/talk\/differentiation_integration_talk.pdf\" style=\"display:inline-block;border:1px solid #8A8578;color:#132433;padding:9px 16px;border-radius:2px;text-decoration:none;margin:0 8px 8px 0\">Talk slides (PDF)<\/a><\/p>\n\n\n\n<p style=\"margin:40px 0 8px;font-size:13px;line-height:16px;letter-spacing:0.12em;text-transform:uppercase;font-weight:600;color:#5B6168\"><span style=\"display:inline-block;width:24px;height:4px;background:#B4622A;vertical-align:middle;margin-right:10px\"><\/span>The problem<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Differentiation and integration are the same ill-posed problem<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Labs measure displacement (laser vibrometer, DIC, encoder) and need velocity and acceleration, or measure acceleration and need velocity and displacement. Write the measurement as y = Au + e, with A the integration operator. A is compact and its inverse is unbounded, so noise is amplified by \u03c9 per derivative and by 1\/\u03c9 per integration. No algorithm removes this; every usable method adds a regularity prior.<\/p>\n\n\n\n<figure style=\"margin:24px 0\"><img decoding=\"async\" src=\"https:\/\/raw.githubusercontent.com\/nld-uri\/kinematics-toolbox\/main\/figures\/s_illposed.png\" alt=\"Amplification factor of differentiation and integration versus frequency\" style=\"width:100%;height:auto;border:1px solid #DCD9D2\"><figcaption style=\"font-size:14px;color:#5B6168;margin-top:8px\">The amplification is unbounded at both ends. A 1% noise floor on position dominates the acceleration estimate above about 30 Hz.<\/figcaption><\/figure>\n\n\n\n<figure style=\"margin:24px 0\"><img decoding=\"async\" src=\"https:\/\/raw.githubusercontent.com\/nld-uri\/kinematics-toolbox\/main\/figures\/s_naive.png\" alt=\"Naive finite differences and cumulative trapezoid fail\" style=\"width:100%;height:auto;border:1px solid #DCD9D2\"><figcaption style=\"font-size:14px;color:#5B6168;margin-top:8px\">Ignoring it: a second central difference of 1% noisy position gives 209% rms error; a plain cumulative trapezoid of an accelerometer with 0.5% offset is 64 times off scale after 3 s.<\/figcaption><\/figure>\n\n\n\n<p style=\"margin:40px 0 8px;font-size:13px;line-height:16px;letter-spacing:0.12em;text-transform:uppercase;font-weight:600;color:#5B6168\"><span style=\"display:inline-block;width:24px;height:4px;background:#B4622A;vertical-align:middle;margin-right:10px\"><\/span>Methods<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Pick the prior you actually believe<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>If you are willing to assume<\/th><th>Use<\/th><\/tr><\/thead><tbody><tr><td>The signal is bandlimited and periodic<\/td><td>Spectral (FFT) differentiation<\/td><\/tr><tr><td>It is locally a low-order polynomial<\/td><td>Savitzky\u2013Golay, Lanczos<\/td><\/tr><tr><td>It lies in a low-rank delay-embedding subspace<\/td><td>SVD \/ SSA<\/td><\/tr><tr><td>Its p-th derivative is small in L2<\/td><td>Whittaker\u2013Henderson, Tikhonov, smoothing spline<\/td><\/tr><tr><td>Its derivative is piecewise constant (L1)<\/td><td>Total variation (Chartrand)<\/td><\/tr><tr><td>It is an integrated Wiener process<\/td><td>Kalman \/ RTS smoother (equivalent to a Gaussian process)<\/td><\/tr><tr><td>Its derivative is bounded by a known constant<\/td><td>Levant sliding-mode differentiator (causal, online)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p style=\"margin:40px 0 8px;font-size:13px;line-height:16px;letter-spacing:0.12em;text-transform:uppercase;font-weight:600;color:#5B6168\"><span style=\"display:inline-block;width:24px;height:4px;background:#B4622A;vertical-align:middle;margin-right:10px\"><\/span>Benchmark<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What the benchmark shows<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ground truth is a Duffing free decay (15 Hz, \u03b6 = 0.004, 25% hardening shift at the initial amplitude) sampled at 2 kHz for 3 s. Each method was tuned to its best possible setting; the state-space smoother tunes itself. At 5% noise the self-tuned smoother is within 1.0\u20131.5 times the error of a perfectly tuned method. The FFT method is the most accurate in the interior of a long record, but its velocity error grows from 0.54% in the interior to 8.4% over the full record because of the ends.<\/p>\n\n\n\n<figure style=\"margin:24px 0\"><img decoding=\"async\" src=\"https:\/\/raw.githubusercontent.com\/nld-uri\/kinematics-toolbox\/main\/figures\/fig1_differentiation.png\" alt=\"Velocity and acceleration error of each differentiation method\" style=\"width:100%;height:auto;border:1px solid #DCD9D2\"><figcaption style=\"font-size:14px;color:#5B6168;margin-top:8px\">Differentiation error of each method against noise level.<\/figcaption><\/figure>\n\n\n\n<figure style=\"margin:24px 0\"><img decoding=\"async\" src=\"https:\/\/raw.githubusercontent.com\/nld-uri\/kinematics-toolbox\/main\/figures\/fig2_integration_fusion.png\" alt=\"Integration of acceleration and fusion of displacement and acceleration\" style=\"width:100%;height:auto;border:1px solid #DCD9D2\"><figcaption style=\"font-size:14px;color:#5B6168;margin-top:8px\">Integrating a drifting accelerometer, and fusing it with a displacement channel in one state-space smoother.<\/figcaption><\/figure>\n\n\n\n<p style=\"margin:40px 0 8px;font-size:13px;line-height:16px;letter-spacing:0.12em;text-transform:uppercase;font-weight:600;color:#5B6168\"><span style=\"display:inline-block;width:24px;height:4px;background:#B4622A;vertical-align:middle;margin-right:10px\"><\/span>Recommendation<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Which method to use<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Displacement and acceleration channels:<\/strong> fuse them in one state-space smoother. Best accuracy, no cutoff to choose, error bars included, and kinematically consistent outputs.<\/li>\n\n\n\n<li><strong>Differentiating a smooth position record, one knob acceptable:<\/strong> Whittaker with p = 3 and a corner frequency set from the physics.<\/li>\n\n\n\n<li><strong>Differentiating position with no knob:<\/strong> the self-tuned state-space smoother, nstate = 4 for noisy records, 5 for clean ones.<\/li>\n\n\n\n<li><strong>Impacts, stick\u2013slip, backlash:<\/strong> total variation.<\/li>\n\n\n\n<li><strong>Acceleration only:<\/strong> Tikhonov integration with the corner below the lowest mode and above the drift. Never a bare cumtrapz.<\/li>\n\n\n\n<li><strong>Online or in a control loop:<\/strong> Levant\u2019s differentiator, the only causal one.<\/li>\n\n\n\n<li><strong>Long, stationary record whose ends you can discard:<\/strong> the FFT method.<\/li>\n<\/ol>\n\n\n\n<p style=\"margin:40px 0 8px;font-size:13px;line-height:16px;letter-spacing:0.12em;text-transform:uppercase;font-weight:600;color:#5B6168\"><span style=\"display:inline-block;width:24px;height:4px;background:#B4622A;vertical-align:middle;margin-right:10px\"><\/span>Get started<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Using the code<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Python (NumPy and SciPy only):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import kinematics as kin\n\nv = kin.diff_whittaker(x, dt, order=1, fc=70)     # velocity from position\nd = kin.int_tikhonov(acc, dt, order=2, fc=2.0)    # displacement from acceleration\nr = kin.kinsmooth(t, x=x, a=acc, nstate=4, bias=True)   # fuse both\nr&#091;'x'], r&#091;'v'], r&#091;'a'], r&#091;'std']                  # estimates and posterior std devs<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">MATLAB (base MATLAB, no toolboxes):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd matlab; test_kinematics          % verifies the port against the Python reference\nv = kin_diff_whittaker(x, dt, 1, 70);\nd = kin_int_tikhonov(acc, dt, 2, 2.0);\nr = kin_smooth(t, struct('x',x,'a',acc,'nstate',4,'bias',true));<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Gaps are NaN, a slower channel is a mostly-NaN column, and non-uniform time is handled directly. The full methods note, tuning rules and cross-validation of the MATLAB port are in the <a href=\"https:\/\/github.com\/nld-uri\/kinematics-toolbox\">repository README<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nonlinear Dynamics Laboratory Kinematics toolbox Model-free differentiation and integration of measured motion. Get velocity and acceleration from a noisy displacement record, velocity and displacement from a drifting accelerometer, or fuse both channels. No model of the system is used, only a regularity prior on the signal. MATLAB and Python, MIT license. Code on GitHubTalk slides [&hellip;]<\/p>\n","protected":false},"author":1291,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"footnotes":"","_links_to":"","_links_to_target":""},"class_list":["post-1818","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/web.uri.edu\/nld\/wp-json\/wp\/v2\/pages\/1818","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/web.uri.edu\/nld\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/web.uri.edu\/nld\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/web.uri.edu\/nld\/wp-json\/wp\/v2\/users\/1291"}],"replies":[{"embeddable":true,"href":"https:\/\/web.uri.edu\/nld\/wp-json\/wp\/v2\/comments?post=1818"}],"version-history":[{"count":2,"href":"https:\/\/web.uri.edu\/nld\/wp-json\/wp\/v2\/pages\/1818\/revisions"}],"predecessor-version":[{"id":1906,"href":"https:\/\/web.uri.edu\/nld\/wp-json\/wp\/v2\/pages\/1818\/revisions\/1906"}],"wp:attachment":[{"href":"https:\/\/web.uri.edu\/nld\/wp-json\/wp\/v2\/media?parent=1818"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}