Archived
568 lines
29 KiB
HTML
568 lines
29 KiB
HTML
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<title>Workflow: Milling Force Parameter Training | HiAPI-C# 2025 </title>
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta name="title" content="Workflow: Milling Force Parameter Training | HiAPI-C# 2025 ">
|
||
|
||
|
||
<link rel="icon" href="../img/HiAPI.favicon.ico">
|
||
<link rel="stylesheet" href="../public/docfx.min.css">
|
||
<link rel="stylesheet" href="../public/main.css">
|
||
<meta name="docfx:navrel" content="../toc.html">
|
||
<meta name="docfx:tocrel" content="toc.html">
|
||
|
||
<meta name="docfx:rel" content="../">
|
||
|
||
|
||
|
||
<meta name="loc:inThisArticle" content="In this article">
|
||
<meta name="loc:searchResultsCount" content="{count} results for "{query}"">
|
||
<meta name="loc:searchNoResults" content="No results for "{query}"">
|
||
<meta name="loc:tocFilter" content="Filter by title">
|
||
<meta name="loc:nextArticle" content="Next">
|
||
<meta name="loc:prevArticle" content="Previous">
|
||
<meta name="loc:themeLight" content="Light">
|
||
<meta name="loc:themeDark" content="Dark">
|
||
<meta name="loc:themeAuto" content="Auto">
|
||
<meta name="loc:changeTheme" content="Change theme">
|
||
<meta name="loc:copy" content="Copy">
|
||
<meta name="loc:downloadPdf" content="Download PDF">
|
||
|
||
<script type="module" src="./../public/docfx.min.js"></script>
|
||
|
||
<script>
|
||
const theme = localStorage.getItem('theme') || 'auto'
|
||
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme)
|
||
</script>
|
||
|
||
</head>
|
||
|
||
<body class="tex2jax_ignore" data-layout="" data-yaml-mime="">
|
||
<header class="bg-body border-bottom">
|
||
<nav id="autocollapse" class="navbar navbar-expand-md" role="navigation">
|
||
<div class="container-xxl flex-nowrap">
|
||
<a class="navbar-brand" href="../index.html">
|
||
<img id="logo" class="svg" src="../img/HiAPI.logo.png" alt="">
|
||
|
||
</a>
|
||
<button class="btn btn-lg d-md-none border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navpanel" aria-controls="navpanel" aria-expanded="false" aria-label="Toggle navigation">
|
||
<i class="bi bi-three-dots"></i>
|
||
</button>
|
||
<div class="collapse navbar-collapse" id="navpanel">
|
||
<div id="navbar">
|
||
<form class="search" role="search" id="search">
|
||
<i class="bi bi-search"></i>
|
||
<input class="form-control" id="search-query" type="search" disabled placeholder="Search" autocomplete="off" aria-label="Search">
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
</header>
|
||
|
||
<main class="container-xxl">
|
||
<div class="toc-offcanvas">
|
||
<div class="offcanvas-md offcanvas-start" tabindex="-1" id="tocOffcanvas" aria-labelledby="tocOffcanvasLabel">
|
||
<div class="offcanvas-header">
|
||
<h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#tocOffcanvas" aria-label="Close"></button>
|
||
</div>
|
||
<div class="offcanvas-body">
|
||
<nav class="toc" id="toc"></nav>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="content">
|
||
<div class="actionbar">
|
||
<button class="btn btn-lg border-0 d-md-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#tocOffcanvas" aria-controls="tocOffcanvas" aria-expanded="false" aria-label="Show table of contents">
|
||
<i class="bi bi-list"></i>
|
||
</button>
|
||
|
||
<nav id="breadcrumb"></nav>
|
||
</div>
|
||
|
||
<article data-uid="Workflow-ForceTraining">
|
||
<h1 id="workflow-milling-force-parameter-training">Workflow: Milling Force Parameter Training</h1>
|
||
|
||
<p>This workflow covers the end-to-end process of training milling force coefficients from sensor data, including data mapping, coefficient training, quality evaluation, and application of the trained parameters.</p>
|
||
<p>Milling coefficients are essential parameters for calculating milling forces. Training derives these coefficients from experimental sensor data (dynamometer or smart tool holder) mapped to simulated toolpaths.</p>
|
||
<pre><code class="lang-mermaid">flowchart TD
|
||
Prereq["Prerequisites<br>(sensor data, project setup)"]
|
||
Resolution["Configure resolution & enable physics"]
|
||
Mapping["Configure data mapping"]
|
||
Simulate["Run simulation with NC file"]
|
||
Export["Export simulation data<br>(WriteShotFiles, WriteStepFiles)"]
|
||
Map["Map sensor data to simulation"]
|
||
Train["Train milling parameters"]
|
||
Evaluate["Evaluate training quality"]
|
||
Apply["Load trained parameters"]
|
||
|
||
Prereq --> Resolution --> Mapping --> Simulate --> Export
|
||
Simulate --> Map --> Train --> Evaluate --> Apply
|
||
</code></pre>
|
||
<h2 id="1-prerequisites">1. Prerequisites</h2>
|
||
<div class="TIP">
|
||
<h5>Tip</h5>
|
||
<p>For the complete data-collection checklist behind a project, see <a class="xref" href="project-data-checklist.html">Project Data Checklist</a>.</p>
|
||
</div>
|
||
<p>Before training you need:</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Item</th>
|
||
<th>Description</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>HiNC project</strong></td>
|
||
<td>Machine tool, workpiece, fixture, tool house configured</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>NC file</strong></td>
|
||
<td>The NC program used during the physical cutting experiment</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Sensor data CSV</strong></td>
|
||
<td>Time-stamped force/torque data from a dynamometer or smart tool holder</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Controller data CSV</strong> (optional)</td>
|
||
<td>Machine controller log with <code>FileNo</code>, <code>LineNo</code>, <code>ActualTime</code> for two-layer mapping</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<div class="IMPORTANT">
|
||
<h5>Important</h5>
|
||
<p>Before training, the workpiece + fixture must be correctly placed relative to the work offset, otherwise the simulated engagement (and therefore the trained coefficients) is wrong. See <a href="../manual/setup/program-zero-alignment.html">Program Zero Alignment</a> — particularly the high-fidelity caution that the G54 used must reflect the <strong>real</strong> machine offset, and the rough-resolution check for catching a wrong setup at the opening plunge.</p>
|
||
</div>
|
||
<h3 id="sensor-data-file-format">Sensor Data File Format</h3>
|
||
<p>The CSV must contain a header row with a time column and at least one force/torque channel. Each
|
||
channel accepts more than one spelling, so a file written for an older release still reads:</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Source</th>
|
||
<th>Headers</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>Time</td>
|
||
<td><code>ActualTime</code>, or <code>ActualDateTime</code> for the absolute instant. <code>TimeTag</code> and <code>Time</code> are read for compatibility with older files.</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Dynamometer</td>
|
||
<td><code>Fx</code> or <code>Workpiece.Fx</code> (same for <code>y</code>, <code>z</code>)</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Smart tool holder</td>
|
||
<td><code>Mx</code> or <code>Holder.Mx</code> (same for <code>y</code>, <code>z</code>). <code>Spindle.Mx</code> is an obsolete spelling, read but not written.</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Accelerometer (optional)</td>
|
||
<td><code>Ax</code>, <code>Ay</code>, <code>Az</code> — one spelling only</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<pre><code class="lang-csv">ActualTime,CH1,CH2,Mx,My,Mz
|
||
18:23:54.703,-0.00398,-0.00034,-0.02923,0.10733,0.00409
|
||
18:23:54.704,-0.00194,0.00285,0.04155,-0.04457,0.00448
|
||
...
|
||
</code></pre>
|
||
<div class="TIP">
|
||
<h5>Tip</h5>
|
||
<p>Keep the completed training project archived. When the HiNC training algorithm is updated, you can re-run training from the same project.</p>
|
||
</div>
|
||
<hr>
|
||
<h2 id="2-configure-resolution-and-enable-physics">2. Configure Resolution and Enable Physics</h2>
|
||
<h3 id="resolution">Resolution</h3>
|
||
<p>Use a finer resolution than normal operation for training accuracy:</p>
|
||
<pre><code class="lang-csharp">MachiningResolution_mm = 0.0625; // half or less of production resolution
|
||
MachiningMotionResolution = FeedPerTooth;
|
||
</code></pre>
|
||
<div class="TIP">
|
||
<h5>Tip</h5>
|
||
<p>Training resolution should be ≤ 0.5× the production resolution for better accuracy.</p>
|
||
</div>
|
||
<h3 id="enable-physics">Enable Physics</h3>
|
||
<p><a class="xref" href="../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_EnablePhysics">EnablePhysics</a> must be enabled for force calculation:</p>
|
||
<pre><code class="lang-csharp">EnablePhysics = true;
|
||
</code></pre>
|
||
<h3 id="milling-force-cycle-division">Milling Force Cycle Division</h3>
|
||
<p><a class="xref" href="../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_MillingCycleDivisionNum">MillingCycleDivisionNum</a> is the number of angular divisions per spindle revolution used by the force evaluation. <strong>The default is 36, which is intended for normal simulation</strong> — force playback does not benefit from a finer division, and raising it only slows the physics down. <strong>Training is the exception</strong>: phase alignment and coefficient quality improve with a finer division, so set it in the training script:</p>
|
||
<pre><code class="lang-csharp">MillingCycleDivisionNum = 180; // training only; default 36 is for normal simulation
|
||
</code></pre>
|
||
<div class="NOTE">
|
||
<h5>Note</h5>
|
||
<p>This must be set <strong>before</strong> the simulation run that <code>TrainMillingPara</code> consumes.</p>
|
||
</div>
|
||
<p><strong>How much is enough — measured (2-flute D8, Al6061-T6, <code>MachiningResolution_mm</code> 0.03125, sensor series sampled at 0.1 ms):</strong></p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th><code>MillingCycleDivisionNum</code></th>
|
||
<th>R</th>
|
||
<th>Fc error @ t=0.2</th>
|
||
<th>Fn error @ t=0.2</th>
|
||
<th>ploughing coefficients</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>36 (default)</td>
|
||
<td>91.5 %</td>
|
||
<td>−6.7 %</td>
|
||
<td>−8.8 %</td>
|
||
<td>badly off (Kpc +40 %)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>180</strong></td>
|
||
<td><strong>95.2 %</strong></td>
|
||
<td><strong>−6.6 %</strong></td>
|
||
<td><strong>−6.1 %</strong></td>
|
||
<td>Kpc +10 %</td>
|
||
</tr>
|
||
<tr>
|
||
<td>720</td>
|
||
<td>95.2 %</td>
|
||
<td>−6.9 %</td>
|
||
<td>−6.3 %</td>
|
||
<td>Kpc +11 %</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p><strong>180 is the sweet spot: the default 36 is genuinely too coarse for training (the ploughing coefficients degrade badly), and 720 buys nothing while costing 4× the physics.</strong> Do not assume “larger is always better”.</p>
|
||
<div class="WARNING">
|
||
<h5>Warning</h5>
|
||
<p>The value is <strong>process-wide, not per-project</strong>: it is not saved into the <code>.hincproj</code>, and it survives <code>ResetRuntime()</code> and project switches. Two consequences: (a) a training script must always set it explicitly — a fresh service instance starts at 36; (b) after training, the same instance keeps the large value, so subsequent normal simulations run slower until you set it back (or restart the instance).</p>
|
||
</div>
|
||
<hr>
|
||
<h2 id="3-configure-data-mapping">3. Configure Data Mapping</h2>
|
||
<p>Depending on your data, choose one of the mapping strategies below.</p>
|
||
<h3 id="31-local-mapping-anchor-based">3.1 Local Mapping (Anchor-Based)</h3>
|
||
<p>For mapping sensor data to specific NC path segments:</p>
|
||
<p><strong>Step A — Specify input data:</strong></p>
|
||
<pre><code class="lang-csharp">ClearTimeMappingData();
|
||
AddTimeDataByFile("lineA", "Mapping/sensor1.csv", "18:25:51.7100", "18:26:12.9910");
|
||
AddTimeDataByFile("lineB", "Mapping/sensor1.csv", "18:26:30.5750", "18:27:12.2880");
|
||
</code></pre>
|
||
<p><strong>Step B — Specify NC paths</strong> (embedded in NC code comments):</p>
|
||
<pre><code>X13. F20 ;@LineSelection("lineA", FirstTouch, ShiftTime_s(2), LineEnd, ShiftDistance_mm(-1));
|
||
X25. F10 ;@LineSelection("lineB", FirstTouch, null, LastTouch, null);
|
||
</code></pre>
|
||
<p>Anchor options: <code>LineBegin</code>, <code>LineEnd</code>, <code>FirstTouch</code>, <code>LastTouch</code>.
|
||
Offset options: <code>null</code>, <code>ShiftTime_s(<seconds>)</code>, <code>ShiftDistance_mm(<mm>)</code>.</p>
|
||
<h3 id="32-two-layer-chained-mapping-controller--sensor">3.2 Two-Layer Chained Mapping (Controller + Sensor)</h3>
|
||
<p>When you have both controller data and sensor data:</p>
|
||
<pre><code class="lang-csharp">PlayNcFile("NC/machining.nc");
|
||
MapSingleByCsvFile("Data/controller.csv"); // maps FileNo/LineNo → ActualTime
|
||
MapSeriesByCsvFile("Data/sensor.csv"); // ActualTime → sensor series
|
||
</code></pre>
|
||
<div class="NOTE">
|
||
<h5>Note</h5>
|
||
<p><strong>Why two-layer mapping?</strong> Running the NC through the system interpreter produces more accurate simulation paths than direct CSV playback. The controller data bridges simulation steps to real time via <code>FileNo</code>/<code>LineNo</code>, and the sensor data bridges real time to force/torque readings.</p>
|
||
</div>
|
||
<h3 id="-train-on-the-steady-part-of-the-cut--it-is-the-largest-single-lever">⚠ Train on the steady part of the cut — it is the largest single lever</h3>
|
||
<p><a class="xref" href="../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_MapSeriesByCsvFile_">MapSeriesByCsvFile</a> pairs each step with a window of sensor
|
||
samples. The window is anchored at the step's <strong>end</strong> time and runs forward for one cycle period, so
|
||
the samples a step is fitted against are the ones its <strong>neighbours</strong> produced, never its own.</p>
|
||
<p><strong>While the cut is steady, that costs nothing.</strong> A neighbouring step cutting the same arc at the
|
||
same chip load produces, at a given rotation angle, the same force this step would have produced, so
|
||
the borrowed samples are extra data rather than extra error. The pairing turns into a systematic
|
||
bias only where the <strong>cutter–workpiece engagement changes across the window</strong> — cutter entry, pass
|
||
exit, corners, depth changes.</p>
|
||
<p>Measured on the D8 2-flute Al6061-T6 case (one source file at a 1 ms sampling period; only the
|
||
training set and the <code>CycleSamplingMode</code> window vary):</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>training set</th>
|
||
<th>window</th>
|
||
<th>Fc error @ t=0.2</th>
|
||
<th>Fn error @ t=0.2</th>
|
||
<th>R</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>whole path (1076 cutting steps)</td>
|
||
<td><code>SpindleCycle</code> (default)</td>
|
||
<td>−9.3 %</td>
|
||
<td>−9.9 %</td>
|
||
<td>94.3 %</td>
|
||
</tr>
|
||
<tr>
|
||
<td>whole path</td>
|
||
<td><code>FluteCycle</code></td>
|
||
<td>−7.1 %</td>
|
||
<td>−8.1 %</td>
|
||
<td>95.7 %</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>steady part only (~800 steps)</strong></td>
|
||
<td><code>SpindleCycle</code> (default)</td>
|
||
<td><strong>−3.3 %</strong></td>
|
||
<td><strong>−2.3 %</strong></td>
|
||
<td><strong>98.5 %</strong></td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>steady part only (~800 steps)</strong></td>
|
||
<td><code>FluteCycle</code></td>
|
||
<td><strong>−3.2 %</strong></td>
|
||
<td><strong>−2.4 %</strong></td>
|
||
<td><strong>98.6 %</strong></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>Two things to read off it. First, <strong>restricting training to the steady part is worth more than any
|
||
other setting</strong> — here it more than halved the error, and did so at the coarsest sampling period.
|
||
Second, <strong>once the transient is gone the window choice stops mattering</strong> (0.06 percentage points
|
||
between the two modes, versus 2.2 on the whole path): <code>FluteCycle</code>'s advantage on the whole path was
|
||
only ever a shorter exposure to the entry and exit ramps. Keep the <code>SpindleCycle</code> default and its
|
||
larger sample count.</p>
|
||
<p>In this case the transient was 272 of the 1076 cutting steps: the entry ramp, where the radial
|
||
engagement builds from 0.09 mm to the nominal 2 mm, and the pass exit, where it climbs to 5 mm as
|
||
the cutter runs off the far corner. Select the training section by requiring the engagement to be
|
||
constant — <code>CuttingWidth_mm</code> and <code>CuttingDepth_mm</code> steady across neighbouring steps — rather than by
|
||
eyeballing the toolpath.</p>
|
||
<div class="NOTE">
|
||
<h5>Note</h5>
|
||
<p><strong>Gaps in the sensor data are handled.</strong> A step whose pairing window contains no measured row —
|
||
an acquisition dropout, or rows removed to keep the steady section only — is excluded from the
|
||
mapping, and a single <code>Map-ShotGap--StepsSkipped</code> warning reports how many steps were skipped.
|
||
A window-edge row is only interpolated when the rows bracketing the edge span at most two
|
||
spindle revolutions; rows farther apart sit across a gap, and no value is fabricated from them.
|
||
Watch for that warning after mapping measured data: a large count means the acquisition and the
|
||
play do not overlap the way you think they do.</p>
|
||
</div>
|
||
<div class="WARNING">
|
||
<h5>Warning</h5>
|
||
<p><a class="xref" href="../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_MachiningResolution_mm">MachiningResolution_mm</a> must not be too coarse for
|
||
training: at 1/16 of the cutter diameter and coarser (D8 case: 0.0625 and 0.125), usable
|
||
samples dropped by half and the phase pairing degraded badly — at 0.0625 it failed to
|
||
recognise one of the six cutting passes outright, and coefficients came out wildly wrong
|
||
(Fc −12 % to −33 %). Around 1/256 of the diameter (0.03125 here) the result saturates;
|
||
refining further showed no benefit.</p>
|
||
</div>
|
||
<hr>
|
||
<h2 id="4-run-simulation">4. Run Simulation</h2>
|
||
<pre><code class="lang-csharp">PlayNcFile("NC/file1.nc");
|
||
</code></pre>
|
||
<div class="WARNING">
|
||
<h5>Warning</h5>
|
||
<p>During training, <strong>do not</strong>:</p>
|
||
<ul>
|
||
<li>Adjust workpiece, tool, or controller resolution settings</li>
|
||
<li>Use the NC player reset button (close the project instead)</li>
|
||
<li>Save the project (system training configuration may overwrite tool resolution settings)</li>
|
||
</ul>
|
||
</div>
|
||
<hr>
|
||
<h2 id="5-export-simulation-data">5. Export Simulation Data</h2>
|
||
<p>Export step data and waveform data for analysis:</p>
|
||
<pre><code class="lang-csharp">WriteStepFiles("Output/[NcName].step.csv");
|
||
WriteShotFiles("Output/[NcName].shot.csv", 0.1); // 2nd arg = sampling period in ms
|
||
</code></pre>
|
||
<p>The shot file opens with <code>FileNo</code>, <code>LineNo</code>, <code>Time</code> and the mission's M-codes, then carries the time-resolved force columns: <code>Tool.Fx/Fy/Fz</code>, <code>Workpiece.Fx/Fy/Fz</code>, <code>Holder.Mx/My/Mz</code> — the same holder spelling the reader writes, not the obsolete <code>Spindle.M*</code>. A play driven from a controller CSV appends <code>ActualDateTime</code>; an NC-simulated play has no controller instant to stamp and omits that column.</p>
|
||
<h3 id="-the-shot-sampling-period-is-the-dominant-accuracy-lever">⚠ The shot sampling period is the dominant accuracy lever</h3>
|
||
<p>The second argument of <a class="xref" href="../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_WriteShotFiles_">WriteShotFiles</a> is the sampling period in <strong>milliseconds</strong>, and when a simulated shot file is fed back into training it — not the angular division count, not the machining resolution — sets the accuracy ceiling. Each row is interpolated from the per-division force waveform, so the information per revolution is <code>min(MillingCycleDivisionNum, samples per revolution)</code>, where</p>
|
||
<pre><code>samples per revolution = 60000 / (rpm × samplingPeriod_ms)
|
||
</code></pre>
|
||
<p>Measured on the same case (2-flute D8, Al6061-T6, <code>MachiningResolution_mm</code> 0.03125, S1270 → one revolution = 47.2 ms):</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>sampling period</th>
|
||
<th>samples / rev</th>
|
||
<th>R</th>
|
||
<th>Fc error @ t=0.2</th>
|
||
<th>Fn error @ t=0.2</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>1 ms</td>
|
||
<td>47</td>
|
||
<td>94.2 %</td>
|
||
<td>−9.3 %</td>
|
||
<td>−9.9 %</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>0.1 ms</strong></td>
|
||
<td><strong>472</strong></td>
|
||
<td><strong>95.2 %</strong></td>
|
||
<td><strong>−6.6 %</strong></td>
|
||
<td><strong>−6.1 %</strong></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>At 1 ms the waveform is sampled only ~47×/rev, and raising <code>MillingCycleDivisionNum</code> from 180 to 720 changes nothing because the extra grid points are pure interpolation of the same data. <strong>Pick the sampling period first</strong>: for training on simulated data use a period at or below the division period (<code>60000 / (rpm × MillingCycleDivisionNum)</code> ms); when comparing against a real measurement, match the sampling period to the physical DAQ rate, otherwise the two sides carry different information densities and the comparison is biased.</p>
|
||
<div class="NOTE">
|
||
<h5>Note</h5>
|
||
<p>A fine period makes large files — the case above went from 13 MB at 1 ms to 128 MB at 0.1 ms for a 6-cut program. Budget disk accordingly, and do not commit such files to a repository.</p>
|
||
</div>
|
||
<p>For coordinate system explanations, see <a class="xref" href="../technique/milling-physics/milling-physics-coordinates.html">Milling Physics Coordinates</a>.</p>
|
||
<hr>
|
||
<h2 id="6-train-milling-parameters">6. Train Milling Parameters</h2>
|
||
<h3 id="trainmillingpara-new-training">TrainMillingPara (New Training)</h3>
|
||
<p><a class="xref" href="../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_TrainMillingPara_">TrainMillingPara</a> trains new coefficients independently of any existing workpiece parameters.</p>
|
||
<pre><code class="lang-csharp">TrainMillingPara(Fx|Fy|Fz, "StainlessSteel.mp");
|
||
</code></pre>
|
||
<h3 id="retrainmillingpara-calibration">ReTrainMillingPara (Calibration)</h3>
|
||
<p><a class="xref" href="../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_ReTrainMillingPara_">ReTrainMillingPara</a> calibrates existing coefficients (10% original weight, 90% new sample weight).</p>
|
||
<pre><code class="lang-csharp">ReTrainMillingPara(Fz|Mx|My|Mz, "StainlessSteel.mp");
|
||
</code></pre>
|
||
<h3 id="sample-flag-requirements">Sample Flag Requirements</h3>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Command</th>
|
||
<th>Minimum Data Types</th>
|
||
<th>Feed Per Tooth Requirement</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>TrainMillingPara</code></td>
|
||
<td><code>Fx\|Fy\|Fz</code> (dynamometer) or <code>Fz\|Mx\|My\|Mz</code> (smart tool holder)</td>
|
||
<td>At least one sample with different feed per tooth</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>ReTrainMillingPara</code></td>
|
||
<td>No restriction</td>
|
||
<td>No restriction</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<div class="WARNING">
|
||
<h5>Warning</h5>
|
||
<p>Using only <code>Mx|My|Mz</code> without <code>Fz</code> loses one degree of freedom (torque = r × F loses the r-direction), making coefficient training unreliable. Always include <code>Fz</code> when using torque data.</p>
|
||
</div>
|
||
<p>The feed-per-tooth entry above is what the command refuses to run without, not what a usable
|
||
training needs. One sample at a different feed satisfies it; separating the shear coefficients from
|
||
the ploughing ones takes a <strong>range</strong> of chip loads across the passes.</p>
|
||
<h3 id="training-conditions">Training Conditions</h3>
|
||
<ul>
|
||
<li>Samples should have <strong>stable, repeatable waveforms</strong> for at least two spindle revolutions</li>
|
||
<li>Under unstable conditions, plowing coefficients tend to be over-estimated</li>
|
||
<li><strong>Stable samples are necessary and not sufficient.</strong> Whether the coefficients can be recovered
|
||
from a cut set at all is decided by what that set spans, not by how clean it is: a set with one
|
||
helix angle leaves a combination of the shear coefficients exactly unobservable, and a set with a
|
||
narrow feed-per-tooth range cannot separate shear from ploughing. Design the set before cutting —
|
||
see <a href="../technique/measurement/training-cut-set-design.html">Designing a Training Cut Set</a></li>
|
||
</ul>
|
||
<hr>
|
||
<h2 id="7-evaluate-training-quality">7. Evaluate Training Quality</h2>
|
||
<p>After training, the system reports three quality metrics:</p>
|
||
<h3 id="correlation-coefficient-r">Correlation Coefficient (R)</h3>
|
||
<p>A single value for the overall result. Ranges from 0 to 1; for new tools, expect 0.95–0.999.</p>
|
||
<h3 id="training-error-ratio-trainingerrratio">Training Error Ratio (TrainingErrRatio)</h3>
|
||
<p>A per-step variable registered automatically after training. Lower values indicate better step-level quality:</p>
|
||
<div class="math">
|
||
\[
|
||
\text{TrainingErrRatio} = \sqrt{\frac{\sum_{i} e_i^2}{\sqrt{\sum_{i} y_i^2 \cdot \sum_{i} \hat{y}_i^2}}}
|
||
\]</div>
|
||
<h3 id="angle-offset-angleoffset">Angle Offset (AngleOffset)</h3>
|
||
<p>A per-step variable representing the cutter rotation phase difference between measured and simulated data:</p>
|
||
<div class="math">
|
||
\[
|
||
\theta_{offset} = \frac{2\pi \cdot i_{min}}{N_{div}}
|
||
\]</div>
|
||
<div class="TIP">
|
||
<h5>Tip</h5>
|
||
<p>If <code>AngleOffset</code> varies significantly across segments in the same training batch, the spindle may have experienced speed changes, data gaps, or the system could not accurately analyze the samples.</p>
|
||
</div>
|
||
<hr>
|
||
<h2 id="8-load-trained-parameters">8. Load Trained Parameters</h2>
|
||
<p>After training, load the new coefficients into the workpiece:</p>
|
||
<pre><code class="lang-csharp">LoadCuttingParaByFile("StainlessSteel.mp");
|
||
</code></pre>
|
||
<div class="WARNING">
|
||
<h5>Warning</h5>
|
||
<p>If the training output file path is the same as the tool's existing cutting parameter file, <strong>reload the project</strong> after training to ensure the new parameters take effect.</p>
|
||
</div>
|
||
<hr>
|
||
<h2 id="xml-configuration-gui-workflow">XML Configuration (GUI Workflow)</h2>
|
||
<p>When using the GUI-based training workflow, configure the <code>.hincproj</code> file:</p>
|
||
<pre><code class="lang-xml"><MillingParaGridTrainingDestinationFile>MillingPara/trainedPara.mp</MillingParaGridTrainingDestinationFile>
|
||
|
||
<MillingParaTraining>
|
||
<IsMzEnabled>false</IsMzEnabled>
|
||
<ForceOutlierRatio>2</ForceOutlierRatio>
|
||
<LeadParaTemplate>
|
||
<RakeFaceCuttingParaMap>
|
||
<FluteFormNum>1</FluteFormNum>
|
||
<NAngleDivisionNum>0</NAngleDivisionNum>
|
||
<EcAngleDivisionNum>0</EcAngleDivisionNum>
|
||
</RakeFaceCuttingParaMap>
|
||
</LeadParaTemplate>
|
||
<ResultParaTemplate>
|
||
<RakeFaceCuttingParaMap>
|
||
<FluteFormNum>1</FluteFormNum>
|
||
<NAngleDivisionNum>0</NAngleDivisionNum>
|
||
<EcAngleDivisionNum>0</EcAngleDivisionNum>
|
||
</RakeFaceCuttingParaMap>
|
||
</ResultParaTemplate>
|
||
</MillingParaTraining>
|
||
</code></pre>
|
||
<p>Set <code>IsMzEnabled</code> to <code>true</code> if mapped data contains axial spindle torque from a smart tool holder.</p>
|
||
<hr>
|
||
<h2 id="complete-script-example">Complete Script Example</h2>
|
||
<pre><code class="lang-csharp">MachiningResolution_mm = 0.0625;
|
||
EnablePhysics = true;
|
||
MillingCycleDivisionNum = 180; // training only; default 36 suits normal simulation, 720 buys nothing
|
||
|
||
ClearTimeMappingData();
|
||
AddTimeDataByFile("lineA", "Mapping/sensor1.csv", "18:25:51.7100", "18:26:12.9910");
|
||
AddTimeDataByFile("lineB", "Mapping/sensor1.csv", "18:26:30.5750", "18:27:12.2880");
|
||
|
||
PlayNcFile("NC/file1.nc");
|
||
|
||
TrainMillingPara(Fx|Fy|Fz, "MillingPara/trained.mp");
|
||
LoadCuttingParaByFile("MillingPara/trained.mp");
|
||
|
||
WriteStepFiles("Output/[NcName].step.csv");
|
||
WriteShotFiles("Output/[NcName].shot.csv", 0.1);
|
||
</code></pre>
|
||
<h2 id="see-also">See Also</h2>
|
||
<ul>
|
||
<li><a class="xref" href="../technique/milling-physics/milling-physics-coordinates.html">Milling Physics Coordinates</a> — coordinate system reference</li>
|
||
<li><a href="sensor-mapping.html">Sensor Mapping Workflow</a> — detailed mapping workflow</li>
|
||
<li><a class="xref" href="basic-simulation.html">Workflow: Basic Machining Simulation</a> — basic simulation setup</li>
|
||
<li><a class="xref" href="nc-optimization.html">Workflow: NC Optimization</a> — optimization after training</li>
|
||
<li><a class="xref" href="../technique/scripting/step.html">Step</a> — step data reference</li>
|
||
<li><a class="xref" href="../technique/scripting/session-shell.html">SessionShell</a> — SessionShell quick-reference</li>
|
||
<li><a href="examples/milling-training-dynamometer.html">Training with a Dynamometer (Example)</a></li>
|
||
<li><a href="examples/mapping-demo.html">Cascading Mapping (Example)</a></li>
|
||
</ul>
|
||
|
||
</article>
|
||
|
||
<div class="contribution d-print-none">
|
||
</div>
|
||
|
||
<div class="next-article d-print-none border-top" id="nextArticle"></div>
|
||
|
||
</div>
|
||
|
||
<div class="affix">
|
||
<nav id="affix"></nav>
|
||
</div>
|
||
</main>
|
||
|
||
<div class="container-xxl search-results" id="search-results"></div>
|
||
|
||
<footer class="border-top text-secondary">
|
||
<div class="container-xxl">
|
||
<div class="flex-fill">
|
||
<span> Copyright © 2025 <a href='https://superhightech.com.tw'>Tech Coordinate</a>. All rights reserved. <a href='https://superhightech.com.tw'>超級高科技股份有限公司</a> © 2025 版權所有 </span>
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
</body>
|
||
</html>
|