Sensor Fusion Algorithm Parameter Sheet

Sensor Fusion Algorithm Parameter Sheet Generator

1. Algorithm & Project Context

Define Technical Parameters (Q, R, P, x0, etc.)

Add New Parameter

Defined Parameters List

ID Name (Symbol) Value (Start) Source / Unit Actions

Generated Parameter Sheet

Go to the Setup and Manager tabs to define the algorithm parameters.

Time Step (dt): ${data.time_step || 'N/A'} seconds

Primary Sensors: ${data.primary_sensors || 'N/A'}

Purpose/State Vector: ${data.algo_purpose || 'N/A'}

Defined Algorithm Parameters

`; parameters.forEach((param, index) => { html += `

P-${index + 1}: ${param.name} (${param.symbol})

Source/Unit: ${param.source} / ${param.unit}

${param.description || 'No description provided.'}

${param.value.replace(/\n/g, '
')}

`; }); html += `
`; reviewContent.innerHTML = html; pdfDownloadBtn.disabled = false; switchTab(2); // Switch to review tab }; /** * PDF Generation Function */ const downloadPDF = () => { const metaData = getMetaFormData(); const jsPDF = window.jspdf.jsPDF; const doc = new jsPDF('p', 'pt', 'a4'); let currentY = 40; const margin = 40; const pageWidth = doc.internal.pageSize.width; const maxWidth = pageWidth - (margin * 2); const checkPageBreak = (spaceNeeded) => { if (currentY + spaceNeeded > doc.internal.pageSize.height - margin) { doc.addPage(); currentY = margin; } }; const addSectionHeader = (title, color = [0, 0, 0]) => { checkPageBreak(25); doc.setFontSize(16); doc.setFont('Helvetica', 'bold'); doc.setTextColor(color[0], color[1], color[2]); doc.text(title, margin, currentY); currentY += 10; doc.setLineWidth(0.5); doc.setDrawColor(200); doc.line(margin, currentY, pageWidth - margin, currentY); currentY += 12; doc.setTextColor(0); }; const addText = (text, size = 10, style = 'normal', indent = 0) => { doc.setFontSize(size); doc.setFont('Helvetica', style); const lines = doc.splitTextToSize(text, maxWidth - indent); checkPageBreak(lines.length * 9); doc.text(lines, margin + indent, currentY); currentY += (lines.length * 9); }; const addKeyValue = (key, value) => { doc.setFontSize(10); doc.setFont('Helvetica', 'bold'); doc.text(`${key}:`, margin + 10, currentY); doc.setFont('Helvetica', 'normal'); const keyWidth = doc.getStringUnitWidth(`${key}: `) * 10; const valueLines = doc.splitTextToSize(value, maxWidth - keyWidth - 10); // Draw first line of value immediately after key doc.text(valueLines[0], margin + 10 + keyWidth, currentY); currentY += 10; // Draw remaining lines of value with proper indent for(let i = 1; i < valueLines.length; i++) { doc.text(valueLines[i], margin + 10 + keyWidth, currentY); currentY += 10; } currentY += 5; }; // --- PDF Content --- // Title Block doc.setFontSize(20); doc.setFont('Helvetica', 'bold'); doc.setTextColor(0, 119, 182); doc.text(`SENSOR FUSION PARAMETER SHEET`, pageWidth / 2, currentY, { align: 'center' }); currentY += 15; doc.setFontSize(14); doc.text(metaData.project_name, pageWidth / 2, currentY, { align: 'center' }); currentY += 20; // 1. Context addSectionHeader("1. Project & Algorithm Context", [0, 119, 182]); addKeyValue("Algorithm Type", metaData.algo_name); addKeyValue("Version", metaData.algo_version); addKeyValue("Time Step (dt)", `${metaData.time_step} seconds`); addKeyValue("Primary Sensors", metaData.primary_sensors); currentY += 5; addText("Purpose / State Vector:", 10, 'bold'); addText(metaData.algo_purpose, 10, 'normal', 10); currentY += 10; // 2. Parameters Table addSectionHeader("2. Defined Algorithm Parameters", [0, 119, 182]); if (parameters.length > 0) { const paramHead = [ ["ID", "Symbol", "Name", "Source/Unit", "Value & Description"] ]; const paramBody = parameters.map((param, index) => { const combinedValue = `VALUE:\n${param.value}\n\nDESCRIPTION:\n${param.description}`; return [ `P-${index + 1}`, param.symbol, param.name, `${param.source} / ${param.unit}`, combinedValue ]; }); doc.autoTable({ startY: currentY, head: paramHead, body: paramBody, theme: 'grid', headStyles: { fillColor: [74, 78, 105], textColor: [255] }, // Secondary color styles: { fontSize: 8, cellPadding: 5, font: 'Helvetica' }, columnStyles: { 0: { cellWidth: 30 }, 4: { cellWidth: 150, font: 'Courier' } // Monospace font for matrix data } }); currentY = doc.autoTable.previous.finalY + 10; } else { addText("No parameters defined.", 11, 'italic', 5); currentY += 10; } doc.save(`${metaData.project_name.replace(/\s/g, '_')}_Fusion_Parameters.pdf`); }; // --- Tab Navigation --- const switchTab = (tabIndex) => { tabs.forEach((tab, index) => { tab.classList.toggle('active', index === tabIndex); contents[index].classList.toggle('active', index === tabIndex); }); currentTab = tabIndex; updateNavButtons(); if (tabIndex === 2) { renderReviewSheet(); } } const updateNavButtons = () => { prevBtn.disabled = currentTab === 0; nextBtn.disabled = currentTab === tabs.length - 1; } tabs.forEach((tab, index) => { tab.addEventListener('click', () => { const tabNode = tab.closest('.fusion-tab-button'); const newIndex = Array.from(tabNode.parentNode.children).indexOf(tabNode); switchTab(newIndex); }); }); nextBtn.addEventListener('click', () => { if (currentTab < tabs.length - 1) switchTab(currentTab + 1); }); prevBtn.addEventListener('click', () => { if (currentTab > 0) switchTab(currentTab - 1); }); // --- Event Listeners and Initial Load --- metaSaveBtn.addEventListener('click', updateMetadata); pdfDownloadBtn.addEventListener('click', downloadPDF); // Initial Setup renderParameterList(); // Populate metadata form with default data document.getElementById('algo-name').value = metadata.algo_name; document.getElementById('project-name').value = metadata.project_name; document.getElementById('algo-version').value = metadata.algo_version; document.getElementById('time-step').value = metadata.time_step; document.getElementById('primary-sensors').value = metadata.primary_sensors; document.getElementById('algo-purpose').value = metadata.algo_purpose; updateNavButtons(); });
Scroll to Top