Skip to content

Height Map Tool - Surface Compensation for CNC Milling#798

Open
krudoy wants to merge 3 commits intoSienci-Labs:masterfrom
krudoy:feature/heat-map-tool-support
Open

Height Map Tool - Surface Compensation for CNC Milling#798
krudoy wants to merge 3 commits intoSienci-Labs:masterfrom
krudoy:feature/heat-map-tool-support

Conversation

@krudoy
Copy link
Contributor

@krudoy krudoy commented Feb 4, 2026

Summary

  • Adds a new Height Map tool to gSender that allows users to probe uneven workpiece surfaces and automatically compensate G-code Z-heights for accurate machining
  • Implements a complete probing workflow, bilinear interpolation engine, and G-code transformation pipeline
  • No new dependencies — built entirely on existing libraries and infrastructure

Problem

When machining on surfaces that are not perfectly flat (e.g., PCB blanks, warped stock, uneven wasteboard), the Z-height variations cause inconsistent cut depths. This is especially critical for shallow operations like PCB trace isolation where even 0.1mm of surface variation can ruin a job.

Solution

A dedicated Height Map tool that:

  1. Probes a grid of points across the workpiece surface using the GRBL G38.2 probe command
  2. Interpolates Z-offsets at any XY position using bilinear interpolation
  3. Transforms loaded G-code by segmenting moves and applying per-segment Z-offsets
  4. Exports the compensated G-code for use in the main workspace

Features

Surface Probing Workflow

  • Configurable grid bounds (min/max X and Y) with "Grab Position" buttons to set values from the current machine position
  • Two grid resolution modes: spacing-based (e.g., every 10mm) and point-count (e.g., 5×5 grid)
  • Zigzag probe pattern for minimized travel distance between points
  • Configurable probing safety parameters: Z clearance height, probe feed rate, max probe depth
  • Real-time progress tracking with visual progress bar
  • Abort capability with feedhold and reset commands

Bilinear Interpolation Engine

  • Computes Z-offsets at arbitrary XY positions from the four surrounding probe points
  • Handles out-of-bounds coordinates via clamping and extrapolation
  • Robust edge-case handling for points on grid boundaries

G-code Transformation

  • Parses G0/G1 moves and applies interpolated Z-offsets
  • Line segmentation: long moves are subdivided into shorter segments (configurable segment length) so Z-compensation varies continuously along the path
  • Respects G90 (absolute) / G91 (incremental) modes — only transforms in absolute mode
  • Adds header comments documenting the applied height map bounds and point count
  • Validates whether G-code extents fit within the probed area and warns if they don't

Height Map Persistence

  • Save maps as .gshmap JSON files including all configuration values
  • Load saved maps (.gshmap, .json, .map formats) with full config restoration
  • Maps can be reused across multiple G-code files and sessions

Double-Apply Protection

  • Detects if the loaded file already has _heightmap in its name
  • Shows a warning dialog before compounding height map adjustments
  • User can override and apply anyway if intentional

Unit Support

  • Full metric and imperial unit handling
  • Automatic unit conversion when workspace units change
  • Appropriate minimum value enforcement per unit system

UI Layout

Two-panel design:

Left Panel (Controls) Right Panel (Preview)
Grid Bounds (X/Y range inputs + grab buttons) 3D toolpath visualizer showing transformed G-code
Grid Resolution (spacing or point count toggle) Reuses the existing gSender Visualizer component
Probing Safety (Z clearance, feed rate, depth) Empty state with instructions when no G-code generated
Segment Length
Grid Preview (SVG 2D visualization)
Map Status & Progress
Map Management (Save / Load / Clear)
Action Buttons

Grid Visualizer (SVG)

  • Color-coded probe points: gray (unprobed), gold (current), green (probed), blue→green→red gradient (by Z value)
  • Grid lines at each probe coordinate
  • Interactive tooltips showing X, Y, Z values on hover
  • Color legend bar showing Z range
  • Origin marker and axis labels

Files Changed

New Files (9)

File Purpose
src/app/src/features/HeightMap/definitions.ts TypeScript interfaces, types, and default constants (HeightMapPoint, HeightMapBounds, HeightMapConfig, HeightMapState, etc.)
src/app/src/features/HeightMap/index.tsx Main React component — full tool UI, probing controller logic, G-code generation, map save/load
src/app/src/features/HeightMap/components/GridVisualizer.tsx SVG-based 2D grid preview with color-coded points, tooltips, and Z-range legend
src/app/src/features/HeightMap/components/ToolpathVisualizer.tsx 3D toolpath preview wrapper using existing Visualizer component
src/app/src/features/HeightMap/utils/interpolation.ts Bilinear interpolation, probe grid calculation, bounds checking
src/app/src/features/HeightMap/utils/probeRoutine.ts G-code probe command generation, height map construction from results, normalization, validation
src/app/src/features/HeightMap/utils/gcodeTransformer.ts G-code parsing, line segmentation, Z-offset application, bounds validation
src/app/src/features/HeightMap/REQUIREMENTS.md UI requirements document based on mockup analysis
src/app/src/features/HeightMap/__tests__/HeightMap.test.md Comprehensive test plan (70+ unit tests, integration, E2E, edge cases, performance)

Modified Files (4)

File Change
src/app/src/react-routes.tsx Added Height Map tool card (with MdLandscape icon) and /tools/height-map route
src/app/src/store/defaultState/index.ts Added heightMap widget default state to the global store
src/app/src/store/definitions.ts Added HeightMapState type to the global State interface
.gitignore Added /.claude directory

Architecture Decisions

  • Client-side only: No backend/server changes required. Communicates with the machine via existing controller.command() and serial port event infrastructure
  • No new dependencies: Uses only existing packages (lucide-react, react-icons, react-router, lodash, pubsub-js, react-redux)
  • Reuses existing Visualizer: The 3D preview leverages the secondary visualizer mode already built into gSender for the Surfacing tool
  • Widget persistence: Configuration is saved via the existing WidgetConfig system for automatic persistence across sessions
  • Modular utility layer: Interpolation, probe routine generation, and G-code transformation are separated into pure utility functions for testability

Test Plan

  • Configure grid bounds and resolution, verify probe grid preview updates correctly
  • Run a probe routine on a connected machine, verify all points are probed in zigzag order
  • Abort a probe mid-routine, verify machine stops and state resets
  • Load a G-code file, generate transformed G-code, verify Z-offsets are applied correctly in the 3D preview
  • Export transformed G-code, verify the output file contains correct Z-compensated moves
  • Save a height map, close the tool, reopen and load the saved map — verify all config values restore
  • Test double-apply warning: load an already-compensated file, verify warning dialog appears
  • Switch between metric and imperial units, verify all values convert correctly
  • Test with G-code that extends beyond the probed area, verify out-of-bounds warning appears
  • Load to Main Visualizer, verify transformed G-code appears in the primary workspace

krudoy and others added 3 commits January 23, 2026 21:22
## Summary

This PR adds a complete **Height Map** feature to gSender that allows users to compensate for uneven stock surfaces by probing a grid of points and automatically adjusting G-code Z-heights during job execution.

## Features

### Grid Configuration
- Define probing area with X/Y min/max bounds
- Set grid resolution via spacing or point count
- **@grab** button to capture current machine XY position for min bounds
- **Use File Bounds** button to automatically set bounds from loaded G-code file

### Probing System
- Automated probe routine that visits each grid point sequentially
- Safe Z clearance movement between probe points (raise Z first, then move XY, then probe)
- Real-time progress tracking with visual feedback
- Abort capability during probing
- Configurable parameters:
  - Z clearance height
  - Probe feed rate
  - Maximum probe depth

### Height Map Processing
- Z-value normalization (lowest probed point becomes Z=0)
- Bilinear interpolation for Z adjustments between probe points
- Save/load height map files (.map JSON format)
- Visual grid representation with color-coded height values

### G-code Transformation
- Apply height map compensation to loaded G-code
- Segment subdivision for accuracy on long moves
- Double-apply warning protection (prevents applying height map twice)
- Preview transformed toolpath in secondary visualizer
- Export transformed G-code to file
- Load transformed G-code directly to main visualizer for execution

## Technical Implementation

### New Files

| File | Description |
|------|-------------|
| src/app/src/features/HeightMap/index.tsx | Main HeightMap component with UI and probing logic |
| src/app/src/features/HeightMap/definitions.ts | TypeScript types and interfaces |
| src/app/src/features/HeightMap/components/GridVisualizer.tsx | Grid visualization with height colors |
| src/app/src/features/HeightMap/components/ToolpathVisualizer.tsx | Toolpath preview component |
| src/app/src/features/HeightMap/utils/gcodeTransformer.ts | G-code transformation with Z-offset application |
| src/app/src/features/HeightMap/utils/interpolation.ts | Bilinear interpolation and grid calculation |
| src/app/src/features/HeightMap/utils/probeRoutine.ts | Probe command generation and height map utilities |

### Modified Files

| File | Changes |
|------|---------|
| src/app/src/react-routes.tsx | Added HeightMap route and ToolCard entry |
| src/app/src/store/definitions.ts | Added HeightMapState to store interface |
| src/app/src/store/defaultState/index.ts | Added default heightMap state values |
| src/app/src/store/index.ts | Added Heightmap toolbar command |

### Key Technical Details

1. **Probe Response Handling**: Listens to serialport:read events and parses PRB responses in format [PRB:x.xxx,y.yyy,z.zzz:result]
2. **Safe Probing Sequence**: Each probe point follows the sequence:
   - Raise Z to clearance height
   - Move XY to probe position
   - Execute probe command (G38.2)

3. **Height Map Normalization**: After probing completes, Z values are normalized so the lowest point becomes Z=0, making the map relative to the stock surface
4. **G-code Transformation**:
   - Parses G-code lines for movement commands (G0, G1, G2, G3)
   - Subdivides long segments based on configurable segment length
   - Applies bilinear interpolated Z-offset at each point
   - Preserves original G-code structure and comments

## Testing

The feature has been tested with:
- Various grid configurations (spacing-based and point-count-based)
- Different probe feed rates and depths
- G-code files with various toolpath patterns
- Save/load of height map files

## Screenshots

The Height Map tool is accessible from the Tools menu with a landscape icon. The interface includes:
- Grid bounds configuration panel
- Probing parameters panel
- Grid size mode toggle (spacing vs point count)
- Visual grid display with probe points
- Action buttons for probing, saving, loading, and applying

## Breaking Changes

None - this is a new feature addition.

## Dependencies

No new dependencies added.
The import used 'app/lib/fileUpload' (camelCase) but the actual file
is 'app/lib/fileupload' (lowercase). This broke the build on Linux CI.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant