Table of Contents

Class StepFeedSolver

Namespace
Hi.NcOpt
Assembly
HiMech.dll

Runner-agnostic per-step feed solver core of the NC optimization process: computes per-step feed adjustments from milling physics (force / yielding / spindle torque / spindle power / thermal yield / custom criteria and relief-face collision), constrains them over extended segments, propagates acceleration limits backward, and builds tool deflection compensation.

public class StepFeedSolver
Inheritance
StepFeedSolver
Inherited Members
Extension Methods

Remarks

Ported from HiNc NcOptProc (frozen HardNc baseline): extension-window walkers, force/feed-per-tooth solver family, feed boundaries, BuildStepAdjustment(ICuttingPara, Dictionary<int, StepOptContext>, List<MachiningStep>, IProgress<IMessage>, CancellationToken, KeyValuePair<int, StepOptContext>, StepLuggage, StepBrief, StepAdjustmentLogger, SourceFloorOverTargetTally, SpindleWarningsSaid), ParallelBuildStepAdjustments(ICuttingPara, Dictionary<int, StepOptContext>, List<MachiningStep>, Func<string, string>, IProgress<IMessage>, CancellationToken), ConstrainIndividualFeedrate(ICuttingPara, MachiningToolHouse, bool, List<INcOptPiecePack>, List<MachiningStep>, Dictionary<int, StepOptContext>, IProgress<IMessage>), BuildCompensation(ICuttingPara, List<INcOptPiecePack>, List<MachiningStep>, SortedList<int, NcOptOption>, IProgress<IMessage>) and the acceleration family. The two HardNc seams are parameterized: the stored step luggage is read through a ReadBulkDelegate<TData> one segment of StepLuggageSegmentSize step indices at a time, on the solver's own thread before each parallel pass over the segment (was a SequentialBulkReader<MillingStepLuggage>.GetStep per step from the parallel workers, every call queued behind one lock), and the per-source-file log path derivation is injected via a Func<T, TResult> (was the HardNcUtil [NcFile]/[NcName] template constants).

Constructors

StepFeedSolver(ReadBulkDelegate<StepLuggage>, ReadBulkDelegate<StepBrief>)

Ctor.

public StepFeedSolver(ReadBulkDelegate<StepLuggage> readStepLuggages, ReadBulkDelegate<StepBrief> readStepBriefs)

Parameters

readStepLuggages ReadBulkDelegate<StepLuggage>

Reads the stored StepLuggage rows of a step index range, [begin, end). Called on the solver's thread, never from a parallel worker, once per segment of StepLuggageSegmentSize indices the solver touches. A faulted read the delegate reports and answers null for leaves the segment's steps without luggage: a touched one keeps its simulated feedrate, as a step without a stored row does (one that cuts nothing is set no limit, as ever).

readStepBriefs ReadBulkDelegate<StepBrief>

Reads the stored briefs' rows (StepBrief) of a step index range, [begin, end), on the same terms, beside the luggage rows: a step's four physics constraints (yielding stress, spindle torque and power, thermal yield) read its stored force brief and sequential physics state, and the compensation pass's fast path reads its stored force brief – the brief-into-DB chain's C4a; the resident copies on the steps are not read. A step whose row the segment does not hold is asked itself (its creation cache, then the host); one without briefs anywhere has no physics constraint applied and no deflection to compensate, as a step without luggage keeps its simulated feed. A faulted read the delegate reports and answers null for is taken as a faulted luggage read is: the segment's touched steps keep their simulated feed in the feed solve (one that cuts nothing is set no limit, as ever), and in the compensation build a step of the segment whose destination feed is still its commanded one when the build runs is compensated with nothing – asked of nobody for their own copy either way, one report for the segment, not one per step.

Fields

StepLuggageSegmentSize

Step indices per read of the step cache: the solver groups the steps it works on into segments of this many indices (AlignedSegments(IEnumerable<int>, int)), reads each segment once into a dictionary and runs its parallel pass over that segment before it reads the next, so at most one segment's rows are held.

public const int StepLuggageSegmentSize = 2048

Field Value

int

Properties

CoreNum

Parallel computation thread num. 0 is special number to use all cores. Wired from the HiNC:OptCoreNum configuration by HiNcRclUtil alongside the legacy HardNc NcOptProc.CoreNum.

public static int CoreNum { get; set; }

Property Value

int

EnableStepAdjustmentLog

Enable create log file for building individual StepAdjustment process. Wired by the SessionShell.EnableIndividualStepAdjustmentLog proxy setter alongside the legacy HardNc NcOptProc.EnableIndividualStepAdjustmentLog.

public static bool EnableStepAdjustmentLog { get; set; }

Property Value

bool

Methods

AccelerationConstrainAllFeedrate(List<INcOptPiecePack>, List<MachiningStep>, SortedList<int, NcOptOption>, Dictionary<int, INcOptPiecePack>, IProgress<IMessage>)

Constrain the feedrate of all steps by the maximum acceleration: walks every step forward and recursively propagates the acceleration limit backward when a step's feedrate cannot be reached.

public static void AccelerationConstrainAllFeedrate(List<INcOptPiecePack> piecePackList, List<MachiningStep> machiningSteps, SortedList<int, NcOptOption> stepIndexToSeedOptionSortedList, Dictionary<int, INcOptPiecePack> stepIndexToPackDictionary, IProgress<IMessage> mixedProgress)

Parameters

piecePackList List<INcOptPiecePack>

The list of piece packs to process.

machiningSteps List<MachiningStep>

The list of machining steps.

stepIndexToSeedOptionSortedList SortedList<int, NcOptOption>

Sorted list mapping step index to seed optimization option.

stepIndexToPackDictionary Dictionary<int, INcOptPiecePack>

Dictionary mapping step index to its owning pack. The packs here carry at least 1 step each.

mixedProgress IProgress<IMessage>

The message host for logging.

BuildCompensation(ICuttingPara, List<INcOptPiecePack>, List<MachiningStep>, SortedList<int, NcOptOption>, IProgress<IMessage>)

Builds tool deflection compensation for every non-arc piece pack, writing each step's compensation vector into the PACK's own adjustment (StepAdjustmentList / StepAdjustment) — the object the writeback plan builder reads.

public void BuildCompensation(ICuttingPara millingPara, List<INcOptPiecePack> piecePackList, List<MachiningStep> machiningSteps, SortedList<int, NcOptOption> stepIndexToSeedOptionSortedList, IProgress<IMessage> mixedProgress)

Parameters

millingPara ICuttingPara

The cutting parameters.

piecePackList List<INcOptPiecePack>

The list of piece packs to process.

machiningSteps List<MachiningStep>

The list of machining steps.

stepIndexToSeedOptionSortedList SortedList<int, NcOptOption>

Sorted list mapping step index to seed optimization option.

mixedProgress IProgress<IMessage>

The message host for logging.

Remarks

Fixed-handoff port of HiNc NcOptProc.BuildCompensation (frozen HardNc baseline). History note — the baseline carries a data-flow defect that is deliberately NOT reproduced: it writes the compensation into the StepAdjustment of the context dictionary while its output generation reads the pack's own adjustment, whose compensation stays null from construction — so HardNc never emitted a compensated coordinate. This port redirects the assignment to the pack adjustments, closing the handoff (the context/pack object separation itself is intentional and stays, StepOptContext).

A second divergence follows from the redirect: the per-step fast path compares MachineMotionStep.CommandedClFeedrate_mmds against the PACK adjustment's post-flatten/acceleration DstFeedrate_mmds — the value the writeback chain continues from — whereas the baseline compared the context-side value those passes never touch. The pack value is the saner recompute trigger: the simulated deflection is reused exactly when the destination feedrate still equals the simulated one.

Ported gates: arc packs are skipped whole (IsArc — arc lines never build compensation), PreservedPiecePack builds nothing, and a step only builds when its seed option's CompensationMask is non-zero. A mono pack's single shared adjustment is written per step (the last step wins), mirroring the baseline's build side; the writeback deliberately consumes compensation on splition fragments only (see StepAdjustment).

ConstrainIndividualFeedrate(ICuttingPara, MachiningToolHouse, bool, List<INcOptPiecePack>, List<MachiningStep>, Dictionary<int, StepOptContext>, IProgress<IMessage>)

Constrains individual feedrate for each step.

public static void ConstrainIndividualFeedrate(ICuttingPara millingPara, MachiningToolHouse millingToolHouse, bool isFlatConstraining, List<INcOptPiecePack> piecePackList, List<MachiningStep> machiningSteps, Dictionary<int, StepOptContext> stepIndexToStepOptContextDictionary, IProgress<IMessage> mixedProgress)

Parameters

millingPara ICuttingPara

The cutting parameters.

millingToolHouse MachiningToolHouse

The machining tool house.

isFlatConstraining bool

Flat constraining process is the pre-process that constrains neighbor steps to the same feedrate; non-flat constraining process is the post-process.

piecePackList List<INcOptPiecePack>

The list of piece packs to process.

machiningSteps List<MachiningStep>

The list of machining steps.

stepIndexToStepOptContextDictionary Dictionary<int, StepOptContext>

Dictionary mapping step index to optimization context.

mixedProgress IProgress<IMessage>

The message host for logging.

GetIndexByPostDistance(List<MachiningStep>, int, double)

Get index by post distance. The index position is larger than the distance or is at end or is stepIndex. Or the index is endIndex(size of the machiningSteps) or is stepIndex.

public static int GetIndexByPostDistance(List<MachiningStep> machiningSteps, int stepIndex, double extendedPostDistance)

Parameters

machiningSteps List<MachiningStep>

All machining steps.

stepIndex int

The target step index the window extends from.

extendedPostDistance double

The forward extension distance in mm.

Returns

int

The walked index.

GetIndexByPreDistance(List<MachiningStep>, int, double)

Get index by pre-distance. The position of index is before the distance. i.e. the distance is larger from extendedPreDistance. Or the index is 0 or is stepIndex.

public static int GetIndexByPreDistance(List<MachiningStep> machiningSteps, int stepIndex, double extendedPreDistance)

Parameters

machiningSteps List<MachiningStep>

All machining steps.

stepIndex int

The target step index the window extends from.

extendedPreDistance double

The backward extension distance in mm.

Returns

int

The walked index.

GetSourceFeedrateFloor_mmds(MachiningStep, NcOptOption)

The source-feedrate floor of a step in mm/s (EnableSourceFeedrateFloor): the option's ratio of the feedrate the source program commanded on the step. 0 — no floor — when the option is off, when feedrate optimization is off (the written feed is then the source's, so a floor could hold nothing and must not be logged or reported as holding anything), or when the step carries no usable commanded feedrate.

public static double GetSourceFeedrateFloor_mmds(MachiningStep machiningStep, NcOptOption ncOptOption)

Parameters

machiningStep MachiningStep

The machining step.

ncOptOption NcOptOption

The optimization option effective on the step.

Returns

double

The floor in mm/s, or 0 for none.

GetTouchedFeedPerToothBoundary_mm(MachiningStep, NcOptOption)

Get the feed-per-tooth boundary in mm of a touched step by composing the option limits and the cutter optimization limits. If the composed limits conflict, the smallest wins (conservation principle).

public static Range<double> GetTouchedFeedPerToothBoundary_mm(MachiningStep machiningStep, NcOptOption ncOptOption)

Parameters

machiningStep MachiningStep

The machining step.

ncOptOption NcOptOption

The optimization option effective on the step.

Returns

Range<double>

The composed feed-per-tooth boundary in mm.

Remarks

rapid is not concern

GetTouchedFeedrateBoundary_mmds(MachiningStep, NcOptOption)

Get the feedrate boundary in mm/s of a touched step. When the tool flute num is known the boundary derives from GetTouchedFeedPerToothBoundary_mm(MachiningStep, NcOptOption); otherwise from the option's plain feedrate limits.

public static Range<double> GetTouchedFeedrateBoundary_mmds(MachiningStep machiningStep, NcOptOption ncOptOption)

Parameters

machiningStep MachiningStep

The machining step.

ncOptOption NcOptOption

The optimization option effective on the step.

Returns

Range<double>

The composed feedrate boundary in mm/s.

Remarks

rapid is not concern

ParallelBuildStepAdjustments(ICuttingPara, Dictionary<int, StepOptContext>, List<MachiningStep>, Func<string, string>, IProgress<IMessage>, CancellationToken)

Build the per-step StepAdjustment of every entry of stepIndexToStepOptContextDictionary in parallel. When EnableStepAdjustmentLog is on, one .IndependentStepAdjustment.log file is created per source NC file; one that cannot be opened throws out of the pass before its first step, the logs opened before it shut.

public void ParallelBuildStepAdjustments(ICuttingPara millingPara, Dictionary<int, StepOptContext> stepIndexToStepOptContextDictionary, List<MachiningStep> machiningSteps, Func<string, string> getLogBaseFilePath, IProgress<IMessage> messageProgress, CancellationToken cancellationToken)

Parameters

millingPara ICuttingPara

The cutting parameters.

stepIndexToStepOptContextDictionary Dictionary<int, StepOptContext>

Dictionary mapping step index to optimization context.

machiningSteps List<MachiningStep>

The raw strip-pose step projection, UNFILTERED, in strip order (position == MachiningStep.StepIndex; entries may be null).

getLogBaseFilePath Func<string, string>

Maps a source NC file path to the absolute base output path of its adjustment log; the solver appends the .IndependentStepAdjustment.log suffix. This is the runner-agnostic replacement for the HardNc [NcFile]/[NcName] template constants — Hi.Common.PathUtils.PathUtil.GetPathByTemplate may be used by the caller with its own keyword strings.

messageProgress IProgress<IMessage>

The message host for logging.

cancellationToken CancellationToken

Ends the pass at the next segment or step without throwing: the steps it did not reach are left unsolved, the adjustment logs are shut without the lines they still buffer, and the pass closes with NcOpt-Feed–Canceled where a completed one closes with NcOpt-Feed–Built.

Remarks

Step-index key space: every step-keyed collection here — the context dictionary keys, the logger seed sets (built from StepIndex) and the Enqueue(int, string) keys (the dictionary entry keys) — lives in ONE space: the step's position in machiningSteps, which equals the intrinsic MachiningStep.StepIndex (the strip pos index) because the list is the raw unfiltered strip-pose projection (mirrors the oracle, NcOptProc). Null-step tolerance likewise mirrors the oracle: steps are read directly with no extra null guards, exactly as the oracle reads them.