This repository has been archived on 2026-10-11. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
HiNC-2025-win-desktop-Deploy/App/wwwroot/HiAPI-docsite/workflows/force-training.html
T
2026-09-09 18:06:21 +08:00

568 lines
29 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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 &quot;{query}&quot;">
<meta name="loc:searchNoResults" content="No results for &quot;{query}&quot;">
<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[&quot;Prerequisites&lt;br&gt;(sensor data, project setup)&quot;]
Resolution[&quot;Configure resolution &amp; enable physics&quot;]
Mapping[&quot;Configure data mapping&quot;]
Simulate[&quot;Run simulation with NC file&quot;]
Export[&quot;Export simulation data&lt;br&gt;(WriteShotFiles, WriteStepFiles)&quot;]
Map[&quot;Map sensor data to simulation&quot;]
Train[&quot;Train milling parameters&quot;]
Evaluate[&quot;Evaluate training quality&quot;]
Apply[&quot;Load trained parameters&quot;]
Prereq --&gt; Resolution --&gt; Mapping --&gt; Simulate --&gt; Export
Simulate --&gt; Map --&gt; Train --&gt; Evaluate --&gt; 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 &ldquo;larger is always better&rdquo;.</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(&quot;lineA&quot;, &quot;Mapping/sensor1.csv&quot;, &quot;18:25:51.7100&quot;, &quot;18:26:12.9910&quot;);
AddTimeDataByFile(&quot;lineB&quot;, &quot;Mapping/sensor1.csv&quot;, &quot;18:26:30.5750&quot;, &quot;18:27:12.2880&quot;);
</code></pre>
<p><strong>Step B — Specify NC paths</strong> (embedded in NC code comments):</p>
<pre><code>X13. F20 ;@LineSelection(&quot;lineA&quot;, FirstTouch, ShiftTime_s(2), LineEnd, ShiftDistance_mm(-1));
X25. F10 ;@LineSelection(&quot;lineB&quot;, 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(&lt;seconds&gt;)</code>, <code>ShiftDistance_mm(&lt;mm&gt;)</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(&quot;NC/machining.nc&quot;);
MapSingleByCsvFile(&quot;Data/controller.csv&quot;); // maps FileNo/LineNo → ActualTime
MapSeriesByCsvFile(&quot;Data/sensor.csv&quot;); // 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(&quot;NC/file1.nc&quot;);
</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(&quot;Output/[NcName].step.csv&quot;);
WriteShotFiles(&quot;Output/[NcName].shot.csv&quot;, 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, &quot;StainlessSteel.mp&quot;);
</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, &quot;StainlessSteel.mp&quot;);
</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(&quot;StainlessSteel.mp&quot;);
</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">&lt;MillingParaGridTrainingDestinationFile&gt;MillingPara/trainedPara.mp&lt;/MillingParaGridTrainingDestinationFile&gt;
&lt;MillingParaTraining&gt;
&lt;IsMzEnabled&gt;false&lt;/IsMzEnabled&gt;
&lt;ForceOutlierRatio&gt;2&lt;/ForceOutlierRatio&gt;
&lt;LeadParaTemplate&gt;
&lt;RakeFaceCuttingParaMap&gt;
&lt;FluteFormNum&gt;1&lt;/FluteFormNum&gt;
&lt;NAngleDivisionNum&gt;0&lt;/NAngleDivisionNum&gt;
&lt;EcAngleDivisionNum&gt;0&lt;/EcAngleDivisionNum&gt;
&lt;/RakeFaceCuttingParaMap&gt;
&lt;/LeadParaTemplate&gt;
&lt;ResultParaTemplate&gt;
&lt;RakeFaceCuttingParaMap&gt;
&lt;FluteFormNum&gt;1&lt;/FluteFormNum&gt;
&lt;NAngleDivisionNum&gt;0&lt;/NAngleDivisionNum&gt;
&lt;EcAngleDivisionNum&gt;0&lt;/EcAngleDivisionNum&gt;
&lt;/RakeFaceCuttingParaMap&gt;
&lt;/ResultParaTemplate&gt;
&lt;/MillingParaTraining&gt;
</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(&quot;lineA&quot;, &quot;Mapping/sensor1.csv&quot;, &quot;18:25:51.7100&quot;, &quot;18:26:12.9910&quot;);
AddTimeDataByFile(&quot;lineB&quot;, &quot;Mapping/sensor1.csv&quot;, &quot;18:26:30.5750&quot;, &quot;18:27:12.2880&quot;);
PlayNcFile(&quot;NC/file1.nc&quot;);
TrainMillingPara(Fx|Fy|Fz, &quot;MillingPara/trained.mp&quot;);
LoadCuttingParaByFile(&quot;MillingPara/trained.mp&quot;);
WriteStepFiles(&quot;Output/[NcName].step.csv&quot;);
WriteShotFiles(&quot;Output/[NcName].shot.csv&quot;, 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>