{"id":100215,"date":"2026-02-15T20:27:48","date_gmt":"2026-02-15T20:27:48","guid":{"rendered":"https:\/\/vibromera.eu\/?post_type=calculator&#038;p=100215"},"modified":"2026-03-05T15:44:03","modified_gmt":"2026-03-05T15:44:03","slug":"rul-prognostics-calculator","status":"publish","type":"calculator","link":"https:\/\/vibromera.eu\/sw\/calculators\/rul-prognostics-calculator\/","title":{"rendered":"Kikokotoo cha Utabiri wa RUL | ISO 13381 | Vibromera"},"content":{"rendered":"\n<script type=\"application\/ld+json\">\n{\"@context\":\"https:\/\/schema.org\",\"@type\":\"WebApplication\",\"name\":\"Remaining Useful Life (RUL) Prognostics Calculator\",\"alternateName\":[\"RUL Calculator\",\"Prognostics Calculator\",\"ISO 13381 Calculator\"],\"description\":\"Free online engineering calculator for remaining useful life estimation per ISO 13381. Supports linear, exponential, and polynomial trend extrapolation.\",\"url\":\"https:\/\/vibromera.eu\/calculators\/rul-prognostics-calculator\/\",\"applicationCategory\":\"Engineering Calculator\",\"operatingSystem\":\"Any (Web Browser)\",\"offers\":{\"@type\":\"Offer\",\"price\":\"0\",\"priceCurrency\":\"EUR\"},\"creator\":{\"@type\":\"Organization\",\"name\":\"Vibromera\",\"url\":\"https:\/\/vibromera.eu\/\"},\"datePublished\":\"2025-01-01\",\"dateModified\":\"2025-06-01\",\"inLanguage\":\"en\",\"isAccessibleForFree\":true,\"featureList\":[\"Up to 8 trend data points\",\"Linear, exponential, polynomial regression\",\"Failure threshold extrapolation\",\"Confidence interval estimation\",\"Interactive trend chart\",\"Auto-calculation on input change\"],\"keywords\":\"RUL, remaining useful life, prognostics, ISO 13381, trend extrapolation, curve fitting, predictive maintenance\"}\n<\/script>\n\n<script type=\"application\/ld+json\">\n{\"@context\":\"https:\/\/schema.org\",\"@type\":\"FAQPage\",\"mainEntity\":[\n{\"@type\":\"Question\",\"name\":\"What is Remaining Useful Life (RUL)?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"RUL is the estimated time remaining before an asset reaches a predefined failure threshold. It is a core concept in prognostics and predictive maintenance, defined in ISO 13381.\"}},\n{\"@type\":\"Question\",\"name\":\"What regression models are available?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"This calculator supports linear (y = a + bx), exponential (y = a\u00b7e^(bx)), and second-order polynomial (y = a + bx + cx\u00b2) regression models for trend extrapolation.\"}},\n{\"@type\":\"Question\",\"name\":\"How is confidence level estimated?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Confidence is derived from the R\u00b2 (coefficient of determination) of the fitted model. Higher R\u00b2 indicates a better fit and more reliable RUL prediction.\"}}\n]}\n<\/script>\n\n<script type=\"application\/ld+json\">\n{\"@context\":\"https:\/\/schema.org\",\"@type\":\"BreadcrumbList\",\"itemListElement\":[\n{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/vibromera.eu\/\"},\n{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Calculators\",\"item\":\"https:\/\/vibromera.eu\/calculators\/\"},\n{\"@type\":\"ListItem\",\"position\":3,\"name\":\"RUL Prognostics Calculator\",\"item\":\"https:\/\/vibromera.eu\/calculators\/rul-prognostics-calculator\/\"}\n]}\n<\/script>\n\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700;1,9..40,400&#038;family=JetBrains+Mono:wght@400;500;600&#038;family=Fraunces:opsz,wght@9..144,700;9..144,800&#038;display=swap\" rel=\"stylesheet\">\n\n<link rel=\"stylesheet\" href=\"https:\/\/cdn.jsdelivr.net\/npm\/katex@0.16.11\/dist\/katex.min.css\">\n\n<style>\n:root {\n    --vc-bg: #f4f1ec;\n    --vc-surface: #ffffff;\n    --vc-surface-alt: #f8f6f2;\n    --vc-ink: #1a1a1a;\n    --vc-ink-secondary: #5a5650;\n    --vc-ink-muted: #8a857e;\n    --vc-accent: #c85a2a;\n    --vc-accent-hover: #b04d22;\n    --vc-accent-light: #fdf0ea;\n    --vc-blue: #2a5c8c;\n    --vc-blue-light: #eaf1f8;\n    --vc-green: #2a7a4b;\n    --vc-green-light: #eaf8ef;\n    --vc-yellow: #a67c00;\n    --vc-yellow-light: #fef9e8;\n    --vc-red: #b91c1c;\n    --vc-red-light: #fef2f2;\n    --vc-border: #d9d4cc;\n    --vc-border-light: #e8e4dd;\n    --vc-shadow: 0 1px 3px rgba(26,26,26,0.06), 0 4px 12px rgba(26,26,26,0.04);\n    --vc-shadow-lg: 0 4px 12px rgba(26,26,26,0.08), 0 16px 40px rgba(26,26,26,0.06);\n    --vc-radius: 8px;\n    --vc-radius-lg: 12px;\n    --vc-font: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n    --vc-mono: 'JetBrains Mono', 'Consolas', 'Monaco', monospace;\n    --vc-display: 'Fraunces', Georgia, serif;\n}\n\n.vc-calculator { font-family: var(--vc-font); font-size: 15px; line-height: 1.65; color: var(--vc-ink); max-width: 960px; margin: 0 auto; padding: 20px 16px 40px; -webkit-font-smoothing: antialiased; }\n.vc-calculator *, .vc-calculator *::before, .vc-calculator *::after { box-sizing: border-box; }\n\n\/* \u2500\u2500 HEADER \u2500\u2500 *\/\n.vc-header { text-align: center; padding: 48px 24px 40px; position: relative; }\n.vc-header::after { content:''; position:absolute; bottom:0; left:50%; transform:translateX(-50%); width:80px; height:3px; background:var(--vc-accent); border-radius:2px; }\n.vc-header-eyebrow { font-family:var(--vc-mono); font-size:11px; font-weight:500; letter-spacing:0.15em; text-transform:uppercase; color:var(--vc-accent); margin:0 0 12px; }\n.vc-header-title { font-family:var(--vc-display); font-size:clamp(24px,4vw,36px); font-weight:800; line-height:1.15; color:var(--vc-ink); margin:0 0 16px; letter-spacing:-0.02em; }\n.vc-header-subtitle { font-size:15px; color:var(--vc-ink-secondary); margin:0 auto 20px; max-width:600px; }\n.vc-badges { display:inline-flex; gap:8px; flex-wrap:wrap; justify-content:center; }\n.vc-badge { font-family:var(--vc-mono); font-size:11px; font-weight:500; padding:4px 10px; border-radius:4px; background:var(--vc-surface); border:1px solid var(--vc-border); color:var(--vc-ink-secondary); }\n\n\/* \u2500\u2500 CARD \u2500\u2500 *\/\n.vc-card { background:var(--vc-surface); border:1px solid var(--vc-border); border-radius:var(--vc-radius-lg); box-shadow:var(--vc-shadow); overflow:hidden; margin-top:32px; }\n\n\/* \u2500\u2500 FORM \u2500\u2500 *\/\n.vc-form { padding:24px; }\n.vc-form-grid { display:grid; grid-template-columns:1fr 1fr; gap:18px; }\n@media(max-width:600px) { .vc-form-grid { grid-template-columns:1fr; } }\n.vc-field { display:flex; flex-direction:column; }\n.vc-field-full { grid-column: 1 \/ -1; }\n.vc-label { font-size:12px; font-weight:600; letter-spacing:0.04em; text-transform:uppercase; color:var(--vc-ink-secondary); margin-bottom:6px; }\n.vc-label-hint { font-weight:400; text-transform:none; letter-spacing:0; color:var(--vc-ink-muted); font-size:11px; }\n.vc-select, .vc-input { width:100%; padding:10px 12px; border:1.5px solid var(--vc-border); border-radius:6px; font-family:var(--vc-font); font-size:14px; color:var(--vc-ink); background:var(--vc-surface); transition:border-color 0.15s, box-shadow 0.15s; }\n.vc-select { padding-right:36px; appearance:none; -webkit-appearance:none; cursor:pointer; background-image:url(\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' width='16' height='16' fill='none' stroke='%235a5650' stroke-width='2'%3E%3Cpath d='M4 6l4 4 4-4'\/%3E%3C\/svg%3E\"); background-repeat:no-repeat; background-position:right 10px center; }\n.vc-select:focus, .vc-input:focus { outline:none; border-color:var(--vc-accent); box-shadow:0 0 0 3px rgba(200,90,42,0.12); }\n.vc-select:hover, .vc-input:hover { border-color:var(--vc-ink-muted); }\n\n\/* \u2500\u2500 DATA POINTS TABLE \u2500\u2500 *\/\n.vc-data-table { width:100%; border-collapse:collapse; margin:10px 0; }\n.vc-data-table th { font-family:var(--vc-mono); font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:0.05em; color:var(--vc-ink-secondary); padding:8px; text-align:left; background:var(--vc-surface-alt); border:1px solid var(--vc-border-light); }\n.vc-data-table td { padding:4px; border:1px solid var(--vc-border-light); }\n.vc-data-table input { width:100%; padding:8px 10px; border:1.5px solid var(--vc-border); border-radius:5px; font-family:var(--vc-font); font-size:14px; color:var(--vc-ink); background:var(--vc-surface); }\n.vc-data-table input:focus { outline:none; border-color:var(--vc-accent); box-shadow:0 0 0 3px rgba(200,90,42,0.12); }\n.vc-data-table tr.vc-row-disabled input { opacity:0.4; }\n\n\/* \u2500\u2500 PRESETS \u2500\u2500 *\/\n.vc-presets { display:flex; flex-wrap:wrap; gap:8px; margin-top:18px; padding-top:18px; border-top:1px solid var(--vc-border-light); }\n.vc-presets-label { font-family:var(--vc-mono); font-size:11px; font-weight:500; letter-spacing:0.1em; text-transform:uppercase; color:var(--vc-ink-muted); width:100%; margin-bottom:2px; }\n.vc-preset-btn { padding:5px 12px; font-family:var(--vc-font); font-size:12px; font-weight:500; border:1px solid var(--vc-border); border-radius:6px; background:var(--vc-surface-alt); color:var(--vc-ink-secondary); cursor:pointer; transition:all 0.15s; }\n.vc-preset-btn:hover { border-color:var(--vc-accent); color:var(--vc-accent); background:var(--vc-accent-light); }\n\n\/* \u2500\u2500 RESULTS \u2500\u2500 *\/\n.vc-results { border-top:1px solid var(--vc-border-light); background:var(--vc-surface-alt); padding:0; max-height:0; overflow:hidden; transition:max-height 0.5s cubic-bezier(0.4,0,0.2,1), padding 0.3s; }\n.vc-results.vc-visible { max-height:3000px; padding:24px; }\n.vc-results-head { display:flex; align-items:center; justify-content:space-between; margin-bottom:18px; }\n.vc-results-title { font-family:var(--vc-display); font-size:20px; font-weight:700; color:var(--vc-ink); margin:0; }\n.vc-copy-btn { display:inline-flex; align-items:center; gap:5px; padding:6px 12px; border:1px solid var(--vc-border); border-radius:6px; background:var(--vc-surface); font-family:var(--vc-font); font-size:12px; font-weight:500; color:var(--vc-ink-secondary); cursor:pointer; transition:all 0.15s; }\n.vc-copy-btn:hover { border-color:var(--vc-accent); color:var(--vc-accent); }\n.vc-copy-btn.vc-copied { background:var(--vc-green-light); border-color:var(--vc-green); color:var(--vc-green); }\n\n.vc-result-grid { display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-bottom:20px; }\n@media(max-width:500px) { .vc-result-grid { grid-template-columns:1fr; } }\n.vc-rcard { background:var(--vc-surface); border:1px solid var(--vc-border-light); border-radius:var(--vc-radius); padding:16px; transition:transform 0.2s; }\n.vc-rcard:hover { transform:translateY(-1px); }\n.vc-rcard-primary { border-color:var(--vc-accent); border-width:2px; background:linear-gradient(135deg, #fdf6f2 0%, var(--vc-surface) 100%); grid-column:1 \/ -1; }\n.vc-rcard-label { font-family:var(--vc-mono); font-size:10px; font-weight:500; letter-spacing:0.1em; text-transform:uppercase; color:var(--vc-ink-muted); margin-bottom:4px; }\n.vc-rcard-value { font-family:var(--vc-mono); font-size:22px; font-weight:600; color:var(--vc-ink); line-height:1.2; }\n.vc-rcard-primary .vc-rcard-value { font-size:30px; color:var(--vc-accent); }\n.vc-rcard-unit { font-size:14px; font-weight:400; color:var(--vc-ink-secondary); }\n.vc-rcard-good { border-color:var(--vc-green); background:var(--vc-green-light); }\n.vc-rcard-warn { border-color:var(--vc-yellow); background:var(--vc-yellow-light); }\n.vc-rcard-bad { border-color:var(--vc-red); background:var(--vc-red-light); }\n\n\/* \u2500\u2500 CHART \u2500\u2500 *\/\n.vc-chart-wrap { background:var(--vc-surface); border:1px solid var(--vc-border-light); border-radius:var(--vc-radius); padding:16px; margin-bottom:16px; }\n.vc-chart-wrap svg { width:100%; height:auto; }\n\n\/* \u2500\u2500 COLLAPSIBLE SECTIONS \u2500\u2500 *\/\n.vc-section { margin-top:24px; border:1px solid var(--vc-border); border-radius:var(--vc-radius-lg); background:var(--vc-surface); box-shadow:var(--vc-shadow); overflow:hidden; }\n.vc-section-toggle { width:100%; display:flex; align-items:center; justify-content:space-between; padding:18px 24px; border:none; background:transparent; cursor:pointer; font-family:var(--vc-font); text-align:left; transition:background 0.15s; }\n.vc-section-toggle:hover { background:var(--vc-surface-alt); }\n.vc-section-toggle-text { display:flex; align-items:center; gap:10px; }\n.vc-section-icon { font-size:20px; line-height:1; }\n.vc-section-title { font-family:var(--vc-display); font-size:18px; font-weight:700; color:var(--vc-ink); margin:0; }\n.vc-section-chevron { width:20px; height:20px; color:var(--vc-ink-muted); transition:transform 0.3s; flex-shrink:0; }\n.vc-section.vc-open .vc-section-chevron { transform:rotate(180deg); }\n.vc-section-body { max-height:0; overflow:hidden; transition:max-height 0.4s cubic-bezier(0.4,0,0.2,1); }\n.vc-section.vc-open .vc-section-body { max-height:20000px; }\n.vc-section-inner { padding:0 24px 24px; border-top:1px solid var(--vc-border-light); }\n\n\/* \u2500\u2500 THEORY \u2500\u2500 *\/\n.vc-theory h3 { font-family:var(--vc-display); font-size:17px; font-weight:700; color:var(--vc-ink); margin:28px 0 10px; }\n.vc-theory h3:first-child { margin-top:20px; }\n.vc-theory p { font-size:14px; color:var(--vc-ink-secondary); margin:0 0 10px; }\n.vc-theory ul, .vc-theory ol { font-size:14px; color:var(--vc-ink-secondary); margin:0 0 12px 18px; padding:0; }\n.vc-theory li { margin-bottom:5px; }\n.vc-formula-box { background:var(--vc-surface-alt); border:2px solid var(--vc-border); border-radius:6px; padding:14px 20px; font-family:var(--vc-mono); font-size:16px; font-weight:500; text-align:center; margin:14px 0; color:var(--vc-ink); overflow-x:auto; }\n.vc-info-box { background:var(--vc-blue-light); border-left:3px solid var(--vc-blue); padding:14px 16px; border-radius:0 6px 6px 0; margin:14px 0; }\n.vc-info-box p { margin:0; font-size:14px; color:var(--vc-ink-secondary); }\n.vc-warning-box { background:var(--vc-yellow-light); border-left:3px solid var(--vc-yellow); padding:14px 16px; border-radius:0 6px 6px 0; margin:14px 0; }\n.vc-example-box { background:var(--vc-surface-alt); border:1px solid var(--vc-border-light); border-radius:6px; padding:16px; margin:14px 0; }\n.vc-example-title { font-family:var(--vc-mono); font-size:13px; font-weight:600; color:var(--vc-accent); margin-bottom:8px; }\n.vc-table { width:100%; border-collapse:collapse; margin:14px 0; font-size:13px; }\n.vc-table th, .vc-table td { padding:10px 12px; border:1px solid var(--vc-border-light); text-align:left; }\n.vc-table th { background:var(--vc-surface-alt); font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:0.05em; color:var(--vc-ink-secondary); }\n.vc-table tr:nth-child(even) { background:var(--vc-surface-alt); }\n@media(max-width:600px) { .vc-table { font-size:12px; } .vc-table th, .vc-table td { padding:8px; } }\n\n\/* \u2500\u2500 FAQ \u2500\u2500 *\/\n.vc-faq-list { display:flex; flex-direction:column; gap:8px; margin-top:20px; }\n.vc-faq-item { border:1px solid var(--vc-border-light); border-radius:6px; overflow:hidden; }\n.vc-faq-q { width:100%; display:flex; align-items:center; justify-content:space-between; gap:12px; padding:14px 16px; border:none; background:var(--vc-surface-alt); cursor:pointer; font-family:var(--vc-font); font-size:15px; font-weight:600; color:var(--vc-ink); text-align:left; transition:background 0.15s; }\n.vc-faq-q:hover { background:#ede9e3; }\n.vc-faq-chevron { width:16px; height:16px; color:var(--vc-ink-muted); flex-shrink:0; transition:transform 0.25s; }\n.vc-faq-item.vc-open .vc-faq-chevron { transform:rotate(180deg); }\n.vc-faq-a { max-height:0; overflow:hidden; transition:max-height 0.35s; }\n.vc-faq-item.vc-open .vc-faq-a { max-height:1200px; }\n.vc-faq-a-inner { padding:14px 16px; border-top:1px solid var(--vc-border-light); font-size:14px; color:var(--vc-ink-secondary); }\n.vc-faq-a-inner p { margin:0 0 8px; }\n.vc-faq-a-inner p:last-child { margin-bottom:0; }\n.vc-faq-a-inner ul { margin:4px 0 8px 16px; padding:0; }\n.vc-faq-a-inner li { margin-bottom:3px; }\n\n\/* \u2500\u2500 RELATED \u2500\u2500 *\/\n.vc-related { display:flex; flex-wrap:wrap; gap:10px; margin-top:16px; }\n.vc-related-link { display:inline-block; padding:8px 16px; font-family:var(--vc-font); font-size:13px; font-weight:600; background:var(--vc-surface-alt); color:var(--vc-ink-secondary); border:1px solid var(--vc-border); border-radius:var(--vc-radius); text-decoration:none; transition:all 0.15s; }\n.vc-related-link:hover { border-color:var(--vc-accent); color:var(--vc-accent); background:var(--vc-accent-light); }\n\n\/* \u2500\u2500 PROMO \u2500\u2500 *\/\n.vc-promo { margin-top:24px; padding:20px; background:linear-gradient(135deg, var(--vc-accent-light), var(--vc-surface)); border:1px solid var(--vc-border); border-radius:var(--vc-radius-lg); display:flex; align-items:center; gap:16px; }\n.vc-promo-text { flex:1; font-size:14px; color:var(--vc-ink-secondary); }\n.vc-promo-text strong { color:var(--vc-ink); }\n.vc-promo-link { padding:8px 20px; font-size:13px; font-weight:700; color:#fff; background:var(--vc-accent); border-radius:var(--vc-radius); text-decoration:none; white-space:nowrap; transition:background 0.15s; }\n.vc-promo-link:hover { background:var(--vc-accent-hover); }\n\n\/* \u2500\u2500 FOOTER \u2500\u2500 *\/\n.vc-footer { text-align:center; padding:32px 16px; font-size:13px; color:var(--vc-ink-muted); }\n.vc-footer a { color:var(--vc-accent); text-decoration:none; }\n.vc-footer a:hover { text-decoration:underline; }\n.vc-footer-links { margin-top:8px; font-size:12px; }\n.vc-footer-links a { margin:0 8px; }\n\n\/* \u2500\u2500 PRINT \u2500\u2500 *\/\n@media print {\n    .vc-section-body { max-height:none!important; }\n    .vc-faq-a { max-height:none!important; }\n    .vc-results { max-height:none!important; padding:24px!important; }\n    .vc-copy-btn, .vc-section-chevron, .vc-faq-chevron, .vc-presets, .vc-promo { display:none!important; }\n}\n<\/style>\n\n<div class=\"vc-calculator\" id=\"vc-rul-prognostics\">\n\n<!-- Header -->\n<header class=\"vc-header\">\n    <p class=\"vc-header-eyebrow\">Free Engineering Tool<\/p>\n    <h1 class=\"vc-header-title\">Remaining Useful Life (RUL) Prognostics Calculator<\/h1>\n    <p class=\"vc-header-subtitle\">Enter trend data points, choose a regression model, set a failure threshold, and estimate the remaining useful life with confidence level per ISO 13381.<\/p>\n    <div class=\"vc-badges\">\n        <span class=\"vc-badge\">ISO 13381-1<\/span>\n        <span class=\"vc-badge\">Linear \/ Exponential \/ Polynomial<\/span>\n        <span class=\"vc-badge\">Up to 8 Points<\/span>\n    <\/div>\n<\/header>\n\n<!-- Calculator Card -->\n<div class=\"vc-card\">\n    <form class=\"vc-form\" id=\"vc-form\" autocomplete=\"off\">\n        <div class=\"vc-form-grid\">\n            <div class=\"vc-field\">\n                <label class=\"vc-label\" for=\"vc-model\">Regression Model<\/label>\n                <select class=\"vc-select\" id=\"vc-model\">\n                    <option value=\"linear\" selected>Linear (y = a + b\u00b7t)<\/option>\n                    <option value=\"exponential\">Exponential (y = a\u00b7e^(b\u00b7t))<\/option>\n                    <option value=\"polynomial\">Polynomial 2nd order (y = a + b\u00b7t + c\u00b7t\u00b2)<\/option>\n                <\/select>\n            <\/div>\n            <div class=\"vc-field\">\n                <label class=\"vc-label\" for=\"vc-threshold\">Failure Threshold <span class=\"vc-label-hint\">(parameter value)<\/span><\/label>\n                <input class=\"vc-input\" type=\"number\" id=\"vc-threshold\" inputmode=\"decimal\" step=\"any\" min=\"0\" placeholder=\"e.g. 7.1\" value=\"7.1\">\n            <\/div>\n            <div class=\"vc-field\">\n                <label class=\"vc-label\" for=\"vc-param-name\">Parameter Name <span class=\"vc-label-hint\">(optional label)<\/span><\/label>\n                <input class=\"vc-input\" type=\"text\" id=\"vc-param-name\" placeholder=\"e.g. Vibration mm\/s\" value=\"Vibration mm\/s\">\n            <\/div>\n            <div class=\"vc-field\">\n                <label class=\"vc-label\" for=\"vc-time-unit\">Time Unit<\/label>\n                <select class=\"vc-select\" id=\"vc-time-unit\">\n                    <option value=\"hours\">Hours<\/option>\n                    <option value=\"days\" selected>Days<\/option>\n                    <option value=\"months\">Months<\/option>\n                    <option value=\"cycles\">Cycles<\/option>\n                <\/select>\n            <\/div>\n        <\/div>\n\n        <!-- Data Points Table -->\n        <div style=\"margin-top:20px;\">\n            <label class=\"vc-label\">Trend Data Points <span class=\"vc-label-hint\">(minimum 3 required)<\/span><\/label>\n            <table class=\"vc-data-table\" id=\"vc-data-table\">\n                <thead>\n                    <tr><th style=\"width:50px\">#<\/th><th>Time (t)<\/th><th>Parameter Value (y)<\/th><\/tr>\n                <\/thead>\n                <tbody id=\"vc-data-body\"><\/tbody>\n            <\/table>\n        <\/div>\n\n        <!-- Presets -->\n        <div class=\"vc-presets\">\n            <div class=\"vc-presets-label\">Quick presets<\/div>\n            <button type=\"button\" class=\"vc-preset-btn\" data-preset=\"vibration\">Bearing Vibration Trend<\/button>\n            <button type=\"button\" class=\"vc-preset-btn\" data-preset=\"temperature\">Temperature Rise Trend<\/button>\n            <button type=\"button\" class=\"vc-preset-btn\" data-preset=\"wear\">Wear Particle Count<\/button>\n        <\/div>\n    <\/form>\n\n    <!-- Results -->\n    <div class=\"vc-results\" id=\"vc-results\">\n        <div class=\"vc-results-head\">\n            <h2 class=\"vc-results-title\">Results<\/h2>\n            <button type=\"button\" class=\"vc-copy-btn\" id=\"vc-copy-btn\">\n                <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\"\/><path d=\"M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1\"\/><\/svg>\n                Copy\n            <\/button>\n        <\/div>\n        <div class=\"vc-result-grid\">\n            <div class=\"vc-rcard vc-rcard-primary\">\n                <div class=\"vc-rcard-label\">Estimated Remaining Useful Life<\/div>\n                <div class=\"vc-rcard-value\" id=\"vc-r-rul\">\u2014<\/div>\n            <\/div>\n            <div class=\"vc-rcard\">\n                <div class=\"vc-rcard-label\">Predicted Failure Time<\/div>\n                <div class=\"vc-rcard-value\" id=\"vc-r-fail-time\">\u2014<\/div>\n            <\/div>\n            <div class=\"vc-rcard\">\n                <div class=\"vc-rcard-label\">Model R\u00b2 (Goodness of Fit)<\/div>\n                <div class=\"vc-rcard-value\" id=\"vc-r-r2\">\u2014<\/div>\n            <\/div>\n            <div class=\"vc-rcard\">\n                <div class=\"vc-rcard-label\">Confidence Level<\/div>\n                <div class=\"vc-rcard-value\" id=\"vc-r-conf\">\u2014<\/div>\n            <\/div>\n            <div class=\"vc-rcard\">\n                <div class=\"vc-rcard-label\">Current Rate of Change<\/div>\n                <div class=\"vc-rcard-value\" id=\"vc-r-rate\">\u2014<\/div>\n            <\/div>\n        <\/div>\n\n        <!-- Trend Chart -->\n        <div class=\"vc-chart-wrap\">\n            <svg id=\"vc-chart\" viewBox=\"0 0 700 350\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\"><\/svg>\n        <\/div>\n    <\/div>\n<\/div>\n\n<!-- Theory & Reference -->\n<div class=\"vc-section vc-open\" id=\"vc-sec-theory\">\n    <button type=\"button\" class=\"vc-section-toggle\" aria-expanded=\"true\">\n        <span class=\"vc-section-toggle-text\">\n            <span class=\"vc-section-icon\">\ud83d\udcd8<\/span>\n            <span class=\"vc-section-title\">Theory &amp; Formulas<\/span>\n        <\/span>\n        <svg class=\"vc-section-chevron\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M6 9l6 6 6-6\"\/><\/svg>\n    <\/button>\n    <div class=\"vc-section-body\">\n        <div class=\"vc-section-inner vc-theory\">\n            <h3>Prognostics per ISO 13381-1<\/h3>\n            <p>ISO 13381-1 defines a framework for condition monitoring and prognostics of machines. The core idea is to track a health indicator over time, fit a degradation model, and extrapolate to a predefined failure threshold.<\/p>\n            <div class=\"vc-formula-box\" id=\"vc-katex-1\"><\/div>\n            <h3>Regression Models<\/h3>\n            <p>Three models are supported for fitting trend data:<\/p>\n            <ul>\n                <li><strong>Linear:<\/strong> y(t) = a + b\u00b7t \u2014 suitable for steady, constant-rate degradation<\/li>\n                <li><strong>Exponential:<\/strong> y(t) = a\u00b7e<sup>b\u00b7t<\/sup> \u2014 suitable for accelerating degradation (e.g. bearing wear)<\/li>\n                <li><strong>Polynomial (2nd order):<\/strong> y(t) = a + b\u00b7t + c\u00b7t\u00b2 \u2014 suitable for non-linear trends with inflection<\/li>\n            <\/ul>\n            <div class=\"vc-formula-box\" id=\"vc-katex-2\"><\/div>\n            <h3>Goodness of Fit \u2014 R\u00b2<\/h3>\n            <p>The coefficient of determination R\u00b2 measures how well the model fits the data:<\/p>\n            <div class=\"vc-formula-box\" id=\"vc-katex-3\"><\/div>\n            <ul>\n                <li>R\u00b2 &gt; 0.95 \u2014 Excellent fit, high confidence in RUL estimate<\/li>\n                <li>R\u00b2 = 0.80\u20130.95 \u2014 Good fit, moderate confidence<\/li>\n                <li>R\u00b2 &lt; 0.80 \u2014 Poor fit, consider a different model or more data<\/li>\n            <\/ul>\n\n            <h3>Practical Example<\/h3>\n            <div class=\"vc-example-box\">\n                <div class=\"vc-example-title\">Example \u2014 Bearing Vibration Degradation<\/div>\n                <p><strong>Given:<\/strong> Vibration readings at days 0, 30, 60, 90, 120, 150 are: 1.2, 1.8, 2.5, 3.4, 4.1, 5.0 mm\/s. Alarm threshold = 7.1 mm\/s.<\/p>\n                <p>Linear fit: y = 1.14 + 0.0253\u00b7t \u2192 threshold at t \u2248 236 days \u2192 RUL \u2248 86 days from last measurement.<\/p>\n                <p>Exponential fit may give a shorter RUL if degradation is accelerating.<\/p>\n            <\/div>\n\n            <div class=\"vc-warning-box\">\n                <p style=\"margin:0;font-size:14px;color:var(--vc-ink-secondary);\"><strong>\u26a0\ufe0f Note:<\/strong> Prognostic estimates depend heavily on data quality and the assumption that the degradation mechanism remains unchanged. Always combine with engineering judgment and additional condition monitoring data.<\/p>\n            <\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<!-- Related Calculators -->\n<div class=\"vc-section\" id=\"vc-sec-related\">\n    <button type=\"button\" class=\"vc-section-toggle\" aria-expanded=\"false\">\n        <span class=\"vc-section-toggle-text\">\n            <span class=\"vc-section-icon\">\ud83d\udd17<\/span>\n            <span class=\"vc-section-title\">Related Calculators<\/span>\n        <\/span>\n        <svg class=\"vc-section-chevron\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M6 9l6 6 6-6\"\/><\/svg>\n    <\/button>\n    <div class=\"vc-section-body\">\n        <div class=\"vc-section-inner\">\n            <div class=\"vc-related\">\n                <a class=\"vc-related-link\" href=\"\/calculators\/vibration-velocity\/\">Vibration Velocity (ISO 10816)<\/a>\n                <a class=\"vc-related-link\" href=\"\/calculators\/bearing-modified-life-l10a\/\">Bearing Life (L10)<\/a>\n                <a class=\"vc-related-link\" href=\"\/calculators\/generator-bearing-temp-monitor\/\">Bearing Temp Monitor<\/a>\n                <a class=\"vc-related-link\" href=\"\/calculators\/vibration-acceleration\/\">Vibration Acceleration<\/a>\n            <\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<!-- FAQ -->\n<div class=\"vc-section\" id=\"vc-sec-faq\">\n    <button type=\"button\" class=\"vc-section-toggle\" aria-expanded=\"false\">\n        <span class=\"vc-section-toggle-text\">\n            <span class=\"vc-section-icon\">\u2753<\/span>\n            <span class=\"vc-section-title\">Frequently Asked Questions<\/span>\n        <\/span>\n        <svg class=\"vc-section-chevron\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M6 9l6 6 6-6\"\/><\/svg>\n    <\/button>\n    <div class=\"vc-section-body\">\n        <div class=\"vc-section-inner\">\n            <div class=\"vc-faq-list\" id=\"vc-faq-list\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<!-- Promo -->\n<div class=\"vc-promo\">\n    <div class=\"vc-promo-text\">\n        <strong>Vibromera \u2014 Portable Balancing &amp; Vibration Analysis<\/strong><br>\n        Professional condition monitoring and vibration analysis instruments. Predict failures before they happen. Used in 50+ countries.\n    <\/div>\n    <a class=\"vc-promo-link\" href=\"https:\/\/vibromera.eu\/\" target=\"_blank\" rel=\"noopener\">Learn More<\/a>\n<\/div>\n\n<!-- Footer -->\n<footer class=\"vc-footer\">\n    <p>\u00a9 2024\u20132025 <a href=\"https:\/\/vibromera.eu\/\">Vibromera<\/a> \u2014 Engineering Calculators<\/p>\n    <p style=\"font-size:12px;margin-top:4px;\">Based on ISO 13381-1 (Condition monitoring \u2014 Prognostics). Last updated: June 2025<\/p>\n    <div class=\"vc-footer-links\">\n        <a href=\"\/calculators\/engineering-calculators\/\">All Calculators<\/a>\n        <a href=\"https:\/\/vibromera.eu\/contacts\/\">Contact<\/a>\n    <\/div>\n<\/footer>\n\n<\/div>\n\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/katex@0.16.11\/dist\/katex.min.js\"><\/script>\n<script>\n(function() {\n    'use strict';\n\n    var SLUG = 'rul-prognostics-calculator';\n    var MAX_POINTS = 8;\n\n    function $(id) { return document.getElementById(id); }\n    function fmt(n, d) { if(isNaN(n)||!isFinite(n)) return '\u2014'; var f=n.toFixed(d===undefined?2:d); return f.replace(\/(\\.\\d*?)0+$\/,'$1').replace(\/\\.$\/,''); }\n\n    \/* \u2500\u2500 BUILD DATA TABLE \u2500\u2500 *\/\n    function buildTable() {\n        var body = $('vc-data-body');\n        body.innerHTML = '';\n        for (var i = 0; i < MAX_POINTS; i++) {\n            var tr = document.createElement('tr');\n            tr.innerHTML = '<td style=\"text-align:center;font-family:var(--vc-mono);font-size:13px;color:var(--vc-ink-muted);\">' + (i+1) + '<\/td>' +\n                '<td><input type=\"number\" inputmode=\"decimal\" step=\"any\" class=\"vc-pt-t\" data-idx=\"' + i + '\" placeholder=\"t' + (i+1) + '\"><\/td>' +\n                '<td><input type=\"number\" inputmode=\"decimal\" step=\"any\" class=\"vc-pt-y\" data-idx=\"' + i + '\" placeholder=\"y' + (i+1) + '\"><\/td>';\n            body.appendChild(tr);\n        }\n    }\n\n    \/* \u2500\u2500 GET DATA POINTS \u2500\u2500 *\/\n    function getPoints() {\n        var pts = [];\n        var tInputs = document.querySelectorAll('.vc-pt-t');\n        var yInputs = document.querySelectorAll('.vc-pt-y');\n        for (var i = 0; i < MAX_POINTS; i++) {\n            var t = parseFloat(tInputs[i].value);\n            var y = parseFloat(yInputs[i].value);\n            if (!isNaN(t) && !isNaN(y)) pts.push({ t: t, y: y });\n        }\n        return pts;\n    }\n\n    \/* \u2500\u2500 LINEAR REGRESSION \u2500\u2500 *\/\n    function linReg(pts) {\n        var n = pts.length, st = 0, sy = 0, stt = 0, sty = 0;\n        for (var i = 0; i < n; i++) { st += pts[i].t; sy += pts[i].y; stt += pts[i].t * pts[i].t; sty += pts[i].t * pts[i].y; }\n        var b = (n * sty - st * sy) \/ (n * stt - st * st);\n        var a = (sy - b * st) \/ n;\n        return { a: a, b: b, predict: function(t) { return a + b * t; } };\n    }\n\n    \/* \u2500\u2500 EXPONENTIAL REGRESSION (ln transform) \u2500\u2500 *\/\n    function expReg(pts) {\n        var logPts = [];\n        for (var i = 0; i < pts.length; i++) {\n            if (pts[i].y <= 0) return null;\n            logPts.push({ t: pts[i].t, y: Math.log(pts[i].y) });\n        }\n        var lr = linReg(logPts);\n        var a = Math.exp(lr.a), b = lr.b;\n        return { a: a, b: b, predict: function(t) { return a * Math.exp(b * t); } };\n    }\n\n    \/* \u2500\u2500 POLYNOMIAL 2nd ORDER REGRESSION \u2500\u2500 *\/\n    function polyReg(pts) {\n        var n = pts.length;\n        var S = [0,0,0,0,0], T = [0,0,0];\n        for (var i = 0; i < n; i++) {\n            var t = pts[i].t, y = pts[i].y;\n            S[0] += 1; S[1] += t; S[2] += t*t; S[3] += t*t*t; S[4] += t*t*t*t;\n            T[0] += y; T[1] += t*y; T[2] += t*t*y;\n        }\n        \/\/ Solve 3x3 system using Cramer's rule\n        var M = [[S[0],S[1],S[2]], [S[1],S[2],S[3]], [S[2],S[3],S[4]]];\n        var D = det3(M);\n        if (Math.abs(D) < 1e-12) return null;\n        var a = det3([[T[0],S[1],S[2]], [T[1],S[2],S[3]], [T[2],S[3],S[4]]]) \/ D;\n        var b = det3([[S[0],T[0],S[2]], [S[1],T[1],S[3]], [S[2],T[2],S[4]]]) \/ D;\n        var c = det3([[S[0],S[1],T[0]], [S[1],S[2],T[1]], [S[2],S[3],T[2]]]) \/ D;\n        return { a:a, b:b, c:c, predict: function(t) { return a + b*t + c*t*t; } };\n    }\n\n    function det3(m) {\n        return m[0][0]*(m[1][1]*m[2][2]-m[1][2]*m[2][1]) - m[0][1]*(m[1][0]*m[2][2]-m[1][2]*m[2][0]) + m[0][2]*(m[1][0]*m[2][1]-m[1][1]*m[2][0]);\n    }\n\n    \/* \u2500\u2500 R\u00b2 CALCULATION \u2500\u2500 *\/\n    function calcR2(pts, model) {\n        var n = pts.length, yMean = 0;\n        for (var i = 0; i < n; i++) yMean += pts[i].y;\n        yMean \/= n;\n        var ssTot = 0, ssRes = 0;\n        for (var i = 0; i < n; i++) {\n            ssTot += (pts[i].y - yMean) * (pts[i].y - yMean);\n            var yHat = model.predict(pts[i].t);\n            ssRes += (pts[i].y - yHat) * (pts[i].y - yHat);\n        }\n        return ssTot === 0 ? 0 : 1 - ssRes \/ ssTot;\n    }\n\n    \/* \u2500\u2500 FIND CROSSING TIME \u2500\u2500 *\/\n    function findCrossing(model, threshold, tMax) {\n        \/\/ Simple numerical search\n        var dt = (tMax) \/ 10000;\n        for (var t = 0; t <= tMax; t += dt) {\n            if (model.predict(t) >= threshold) return t;\n        }\n        return NaN;\n    }\n\n    \/* \u2500\u2500 CHART DRAWING \u2500\u2500 *\/\n    function drawChart(pts, model, threshold, failTime, timeUnit) {\n        var svg = $('vc-chart');\n        var W = 700, H = 350, pad = { l:60, r:30, t:20, b:50 };\n        var pw = W - pad.l - pad.r, ph = H - pad.t - pad.b;\n\n        var tMin = pts[0].t, tMaxData = pts[pts.length - 1].t;\n        var tMax = isNaN(failTime) ? tMaxData * 1.5 : Math.min(failTime * 1.15, tMaxData * 3);\n        var yMin = 0, yMax = Math.max(threshold * 1.2, pts.reduce(function(m,p){return Math.max(m,p.y);}, 0) * 1.2);\n\n        function sx(t) { return pad.l + (t - tMin) \/ (tMax - tMin) * pw; }\n        function sy(y) { return pad.t + ph - (y - yMin) \/ (yMax - yMin) * ph; }\n\n        var html = '<rect width=\"' + W + '\" height=\"' + H + '\" fill=\"var(--vc-surface)\" rx=\"4\"\/>';\n        \/\/ Grid\n        for (var i = 0; i <= 5; i++) {\n            var gy = yMin + (yMax - yMin) * i \/ 5;\n            html += '<line x1=\"' + pad.l + '\" y1=\"' + sy(gy) + '\" x2=\"' + (W-pad.r) + '\" y2=\"' + sy(gy) + '\" stroke=\"var(--vc-border-light)\" stroke-width=\"1\"\/>';\n            html += '<text x=\"' + (pad.l-8) + '\" y=\"' + (sy(gy)+4) + '\" text-anchor=\"end\" font-size=\"11\" fill=\"var(--vc-ink-muted)\" font-family=\"var(--vc-mono)\">' + fmt(gy,1) + '<\/text>';\n        }\n        for (var i = 0; i <= 5; i++) {\n            var gt = tMin + (tMax - tMin) * i \/ 5;\n            html += '<line x1=\"' + sx(gt) + '\" y1=\"' + pad.t + '\" x2=\"' + sx(gt) + '\" y2=\"' + (H-pad.b) + '\" stroke=\"var(--vc-border-light)\" stroke-width=\"1\"\/>';\n            html += '<text x=\"' + sx(gt) + '\" y=\"' + (H-pad.b+18) + '\" text-anchor=\"middle\" font-size=\"11\" fill=\"var(--vc-ink-muted)\" font-family=\"var(--vc-mono)\">' + fmt(gt,0) + '<\/text>';\n        }\n        \/\/ Axis labels\n        html += '<text x=\"' + (pad.l + pw\/2) + '\" y=\"' + (H-5) + '\" text-anchor=\"middle\" font-size=\"12\" fill=\"var(--vc-ink-secondary)\" font-family=\"var(--vc-font)\">Time (' + timeUnit + ')<\/text>';\n\n        \/\/ Threshold line\n        html += '<line x1=\"' + pad.l + '\" y1=\"' + sy(threshold) + '\" x2=\"' + (W-pad.r) + '\" y2=\"' + sy(threshold) + '\" stroke=\"var(--vc-red)\" stroke-width=\"2\" stroke-dasharray=\"6,4\"\/>';\n        html += '<text x=\"' + (W-pad.r-4) + '\" y=\"' + (sy(threshold)-6) + '\" text-anchor=\"end\" font-size=\"11\" fill=\"var(--vc-red)\" font-family=\"var(--vc-mono)\">Threshold = ' + fmt(threshold,1) + '<\/text>';\n\n        \/\/ Fitted curve\n        var curvePts = [];\n        var steps = 200;\n        for (var i = 0; i <= steps; i++) {\n            var t = tMin + (tMax - tMin) * i \/ steps;\n            var y = model.predict(t);\n            if (y >= yMin && y <= yMax * 1.5) curvePts.push(sx(t) + ',' + sy(Math.min(y, yMax)));\n        }\n        html += '<polyline points=\"' + curvePts.join(' ') + '\" fill=\"none\" stroke=\"var(--vc-blue)\" stroke-width=\"2\" stroke-dasharray=\"4,3\"\/>';\n\n        \/\/ Data points\n        for (var i = 0; i < pts.length; i++) {\n            html += '<circle cx=\"' + sx(pts[i].t) + '\" cy=\"' + sy(pts[i].y) + '\" r=\"5\" fill=\"var(--vc-accent)\" stroke=\"var(--vc-surface)\" stroke-width=\"2\"\/>';\n        }\n\n        \/\/ Failure point\n        if (!isNaN(failTime) && failTime <= tMax) {\n            html += '<circle cx=\"' + sx(failTime) + '\" cy=\"' + sy(threshold) + '\" r=\"7\" fill=\"none\" stroke=\"var(--vc-red)\" stroke-width=\"2.5\"\/>';\n            html += '<line x1=\"' + sx(failTime) + '\" y1=\"' + sy(threshold) + '\" x2=\"' + sx(failTime) + '\" y2=\"' + (H-pad.b) + '\" stroke=\"var(--vc-red)\" stroke-width=\"1\" stroke-dasharray=\"3,3\"\/>';\n            html += '<text x=\"' + sx(failTime) + '\" y=\"' + (H-pad.b+32) + '\" text-anchor=\"middle\" font-size=\"11\" fill=\"var(--vc-red)\" font-weight=\"600\" font-family=\"var(--vc-mono)\">t=' + fmt(failTime,1) + '<\/text>';\n        }\n\n        \/\/ Legend\n        html += '<circle cx=\"' + (pad.l+10) + '\" cy=\"' + (pad.t+12) + '\" r=\"4\" fill=\"var(--vc-accent)\"\/>';\n        html += '<text x=\"' + (pad.l+18) + '\" y=\"' + (pad.t+16) + '\" font-size=\"11\" fill=\"var(--vc-ink-secondary)\" font-family=\"var(--vc-font)\">Measured Data<\/text>';\n        html += '<line x1=\"' + (pad.l+110) + '\" y1=\"' + (pad.t+12) + '\" x2=\"' + (pad.l+130) + '\" y2=\"' + (pad.t+12) + '\" stroke=\"var(--vc-blue)\" stroke-width=\"2\" stroke-dasharray=\"4,3\"\/>';\n        html += '<text x=\"' + (pad.l+134) + '\" y=\"' + (pad.t+16) + '\" font-size=\"11\" fill=\"var(--vc-ink-secondary)\" font-family=\"var(--vc-font)\">Fitted Model<\/text>';\n\n        svg.innerHTML = html;\n    }\n\n    \/* \u2500\u2500 MAIN CALCULATION \u2500\u2500 *\/\n    function calculate() {\n        var pts = getPoints();\n        var threshold = parseFloat($('vc-threshold').value);\n        var modelType = $('vc-model').value;\n        var timeUnit = $('vc-time-unit').options[$('vc-time-unit').selectedIndex].text;\n\n        if (pts.length < 3 || isNaN(threshold)) {\n            $('vc-results').classList.remove('vc-visible');\n            return;\n        }\n\n        \/\/ Sort by time\n        pts.sort(function(a, b) { return a.t - b.t; });\n\n        \/\/ Fit model\n        var model = null;\n        if (modelType === 'linear') model = linReg(pts);\n        else if (modelType === 'exponential') model = expReg(pts);\n        else if (modelType === 'polynomial') model = polyReg(pts);\n\n        if (!model) {\n            $('vc-results').classList.remove('vc-visible');\n            return;\n        }\n\n        var r2 = calcR2(pts, model);\n        var tLast = pts[pts.length - 1].t;\n        var searchMax = tLast * 10;\n        var failTime = findCrossing(model, threshold, searchMax);\n        var rul = isNaN(failTime) ? NaN : failTime - tLast;\n\n        \/\/ Rate of change at last point\n        var rate;\n        if (modelType === 'linear') rate = model.b;\n        else if (modelType === 'exponential') rate = model.a * model.b * Math.exp(model.b * tLast);\n        else rate = model.b + 2 * model.c * tLast;\n\n        \/\/ Confidence\n        var conf = r2 >= 0.95 ? 'High' : r2 >= 0.80 ? 'Moderate' : 'Low';\n        var confClass = r2 >= 0.95 ? 'vc-rcard-good' : r2 >= 0.80 ? 'vc-rcard-warn' : 'vc-rcard-bad';\n\n        \/\/ Display\n        if (rul > 0) {\n            $('vc-r-rul').innerHTML = fmt(rul, 1) + ' <span class=\"vc-rcard-unit\">' + timeUnit.toLowerCase() + '<\/span>';\n        } else if (rul <= 0) {\n            $('vc-r-rul').innerHTML = '<span style=\"color:var(--vc-red)\">EXCEEDED<\/span>';\n        } else {\n            $('vc-r-rul').innerHTML = 'Beyond range <span class=\"vc-rcard-unit\">(no crossing found)<\/span>';\n        }\n\n        $('vc-r-fail-time').innerHTML = isNaN(failTime) ? 'Not reached' : fmt(failTime, 1) + ' <span class=\"vc-rcard-unit\">' + timeUnit.toLowerCase() + '<\/span>';\n        $('vc-r-r2').innerHTML = fmt(r2, 4);\n        $('vc-r-conf').innerHTML = conf + ' <span class=\"vc-rcard-unit\">(R\u00b2=' + fmt(r2, 3) + ')<\/span>';\n        $('vc-r-conf').parentElement.className = 'vc-rcard ' + confClass;\n        $('vc-r-rate').innerHTML = fmt(rate, 4) + ' <span class=\"vc-rcard-unit\">per ' + timeUnit.toLowerCase().replace(\/s$\/, '') + '<\/span>';\n\n        $('vc-results').classList.add('vc-visible');\n\n        \/\/ Draw chart\n        drawChart(pts, model, threshold, failTime, timeUnit);\n\n        \/\/ Save history\n        saveHistory({ model: modelType, threshold: threshold, points: pts.length, rul: fmt(rul, 1), r2: fmt(r2, 4), _summary: 'RUL=' + fmt(rul,1) + ' ' + timeUnit + ', R\u00b2=' + fmt(r2,3) });\n    }\n\n    \/* \u2500\u2500 PRESETS \u2500\u2500 *\/\n    var presets = {\n        vibration: { name: 'Vibration mm\/s', threshold: 7.1, unit: 'days', data: [[0,1.2],[30,1.8],[60,2.5],[90,3.4],[120,4.1],[150,5.0]] },\n        temperature: { name: 'Temperature \u00b0C', threshold: 90, unit: 'days', data: [[0,55],[15,58],[30,62],[45,67],[60,73],[75,78]] },\n        wear: { name: 'Wear ppm', threshold: 150, unit: 'hours', data: [[0,20],[500,32],[1000,48],[1500,65],[2000,88],[2500,105],[3000,128]] }\n    };\n\n    document.querySelectorAll('.vc-preset-btn').forEach(function(btn) {\n        btn.addEventListener('click', function(e) {\n            e.preventDefault();\n            var p = presets[this.getAttribute('data-preset')];\n            if (!p) return;\n            $('vc-param-name').value = p.name;\n            $('vc-threshold').value = p.threshold;\n            $('vc-time-unit').value = p.unit;\n            var tInputs = document.querySelectorAll('.vc-pt-t');\n            var yInputs = document.querySelectorAll('.vc-pt-y');\n            for (var i = 0; i < MAX_POINTS; i++) {\n                if (i < p.data.length) { tInputs[i].value = p.data[i][0]; yInputs[i].value = p.data[i][1]; }\n                else { tInputs[i].value = ''; yInputs[i].value = ''; }\n            }\n            calculate();\n        });\n    });\n\n    \/* \u2500\u2500 AUTO-CALCULATE \u2500\u2500 *\/\n    $('vc-form').addEventListener('input', calculate);\n    $('vc-form').addEventListener('change', calculate);\n\n    \/* \u2500\u2500 COPY \u2500\u2500 *\/\n    $('vc-copy-btn').addEventListener('click', function() {\n        var text = 'RUL Prognostics Calculation\\n' +\n            '\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n' +\n            'Model: ' + $('vc-model').options[$('vc-model').selectedIndex].text + '\\n' +\n            'Parameter: ' + $('vc-param-name').value + '\\n' +\n            'Threshold: ' + $('vc-threshold').value + '\\n' +\n            'RUL: ' + $('vc-r-rul').textContent + '\\n' +\n            'Failure Time: ' + $('vc-r-fail-time').textContent + '\\n' +\n            'R\u00b2: ' + $('vc-r-r2').textContent + '\\n' +\n            'Confidence: ' + $('vc-r-conf').textContent + '\\n' +\n            '\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n' +\n            'vibromera.eu\/calculators\/rul-prognostics-calculator\/';\n        if (navigator.clipboard) {\n            navigator.clipboard.writeText(text).then(function() {\n                var btn = $('vc-copy-btn');\n                btn.classList.add('vc-copied');\n                btn.innerHTML = '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><polyline points=\"20 6 9 17 4 12\"\/><\/svg> Copied!';\n                setTimeout(function() { btn.classList.remove('vc-copied'); btn.innerHTML = '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\"\/><path d=\"M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1\"\/><\/svg> Copy'; }, 2000);\n            });\n        }\n    });\n\n    \/* \u2500\u2500 COLLAPSIBLE SECTIONS \u2500\u2500 *\/\n    document.querySelectorAll('.vc-section-toggle').forEach(function(btn) {\n        btn.addEventListener('click', function() {\n            var section = this.closest('.vc-section');\n            var isOpen = section.classList.contains('vc-open');\n            section.classList.toggle('vc-open');\n            this.setAttribute('aria-expanded', !isOpen);\n        });\n    });\n\n    \/* \u2500\u2500 FAQ \u2500\u2500 *\/\n    var faqData = [\n        { q: 'What is Remaining Useful Life (RUL)?', a: '<p>RUL is the estimated time remaining before an asset reaches a predefined failure or alarm threshold. It is a core concept in prognostics and predictive maintenance defined by ISO 13381-1.<\/p><p>RUL estimation allows maintenance to be planned proactively, avoiding unexpected downtime while maximizing asset utilization.<\/p>' },\n        { q: 'Which regression model should I choose?', a: '<p>The choice depends on the degradation pattern:<\/p><ul><li><strong>Linear<\/strong> \u2014 constant-rate degradation (e.g. gradual wear, steady contamination buildup)<\/li><li><strong>Exponential<\/strong> \u2014 accelerating degradation (e.g. bearing spalling, fatigue crack growth)<\/li><li><strong>Polynomial<\/strong> \u2014 non-linear trends where rate changes (e.g. initial break-in followed by stable degradation then rapid failure)<\/li><\/ul><p>Compare R\u00b2 values to find the best fit for your data.<\/p>' },\n        { q: 'How many data points do I need?', a: '<p>A minimum of 3 data points is required for any regression. For better confidence:<\/p><ul><li>Linear model: 4\u20135 points recommended<\/li><li>Exponential: 5\u20136 points recommended<\/li><li>Polynomial: 6+ points recommended<\/li><\/ul><p>More data points, especially near the current operating time, improve the prediction.<\/p>' },\n        { q: 'What does the confidence level mean?', a: '<p>Confidence is derived from the R\u00b2 (coefficient of determination) of the fitted model:<\/p><ul><li><strong>High<\/strong> (R\u00b2 \u2265 0.95) \u2014 Model fits data very well, RUL estimate is reliable<\/li><li><strong>Moderate<\/strong> (R\u00b2 0.80\u20130.95) \u2014 Reasonable fit, use with caution<\/li><li><strong>Low<\/strong> (R\u00b2 &lt; 0.80) \u2014 Poor fit, consider a different model or more data points<\/li><\/ul>' },\n        { q: 'How is this different from a simple vibration trend?', a: '<p>This calculator supports multiple parameter types (vibration, temperature, wear particles, etc.), multiple regression models, quantitative goodness-of-fit assessment, and extrapolation to a user-defined threshold \u2014 providing a full prognostic analysis rather than just a visual trend.<\/p>' }\n    ];\n\n    var faqList = $('vc-faq-list');\n    faqData.forEach(function(faq) {\n        faqList.innerHTML += '<div class=\"vc-faq-item\"><button type=\"button\" class=\"vc-faq-q\"><span>' + faq.q + '<\/span><svg class=\"vc-faq-chevron\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M6 9l6 6 6-6\"\/><\/svg><\/button><div class=\"vc-faq-a\"><div class=\"vc-faq-a-inner\">' + faq.a + '<\/div><\/div><\/div>';\n    });\n    faqList.addEventListener('click', function(e) {\n        var btn = e.target.closest('.vc-faq-q');\n        if (!btn) return;\n        btn.closest('.vc-faq-item').classList.toggle('vc-open');\n    });\n\n    \/* \u2500\u2500 HISTORY \u2500\u2500 *\/\n    function saveHistory(entry) {\n        var key = 'vc_history_' + SLUG;\n        var arr = [];\n        try { arr = JSON.parse(localStorage.getItem(key)) || []; } catch(e) {}\n        entry._ts = new Date().toISOString();\n        arr.unshift(entry);\n        if (arr.length > 10) arr = arr.slice(0, 10);\n        try { localStorage.setItem(key, JSON.stringify(arr)); } catch(e) {}\n    }\n\n    \/* \u2500\u2500 KATEX \u2500\u2500 *\/\n    function renderFormulas() {\n        try {\n            katex.render('\\\\text{RUL} = t_{\\\\text{failure}} - t_{\\\\text{current}}', $('vc-katex-1'), { displayMode: true, throwOnError: false });\n            katex.render('R^2 = 1 - \\\\frac{\\\\sum (y_i - \\\\hat{y}_i)^2}{\\\\sum (y_i - \\\\bar{y})^2}', $('vc-katex-3'), { displayMode: true, throwOnError: false });\n            katex.render('y(t) = a \\\\cdot e^{b \\\\cdot t} \\\\quad \\\\text{(exponential model)}', $('vc-katex-2'), { displayMode: true, throwOnError: false });\n        } catch(e) {}\n    }\n\n    \/* \u2500\u2500 INIT \u2500\u2500 *\/\n    function init() {\n        buildTable();\n        renderFormulas();\n        \/\/ Load default preset\n        var p = presets.vibration;\n        $('vc-param-name').value = p.name;\n        $('vc-threshold').value = p.threshold;\n        $('vc-time-unit').value = p.unit;\n        var tInputs = document.querySelectorAll('.vc-pt-t');\n        var yInputs = document.querySelectorAll('.vc-pt-y');\n        for (var i = 0; i < p.data.length; i++) { tInputs[i].value = p.data[i][0]; yInputs[i].value = p.data[i][1]; }\n        calculate();\n    }\n\n    if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);\n    else init();\n})();\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>Kikokotoo cha bure cha mtandaoni cha utabiri wa Maisha Yaliyobaki ya Matumizi (RUL) kulingana na ISO 13381. Ingiza pointi za data ya mwelekeo, chagua mfano wa regression (mstari, eksponenshia, polinomiyo), panua hadi kiwango cha kushindwa na ukadirie maisha yaliyobaki ya matumizi kwa usahihi.<\/p>","protected":false},"featured_media":0,"template":"","meta":{"ai_generated_summary":"","footnotes":""},"categories":[],"tags":[],"class_list":["post-100215","calculator","type-calculator","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/vibromera.eu\/sw\/wp-json\/wp\/v2\/calculator\/100215","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vibromera.eu\/sw\/wp-json\/wp\/v2\/calculator"}],"about":[{"href":"https:\/\/vibromera.eu\/sw\/wp-json\/wp\/v2\/types\/calculator"}],"version-history":[{"count":2,"href":"https:\/\/vibromera.eu\/sw\/wp-json\/wp\/v2\/calculator\/100215\/revisions"}],"predecessor-version":[{"id":100779,"href":"https:\/\/vibromera.eu\/sw\/wp-json\/wp\/v2\/calculator\/100215\/revisions\/100779"}],"wp:attachment":[{"href":"https:\/\/vibromera.eu\/sw\/wp-json\/wp\/v2\/media?parent=100215"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vibromera.eu\/sw\/wp-json\/wp\/v2\/categories?post=100215"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vibromera.eu\/sw\/wp-json\/wp\/v2\/tags?post=100215"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}