# OpenPnP.CSharp **Repository Path**: flyingtoad/open-pn-p.-csharp ## Basic Information - **Project Name**: OpenPnP.CSharp - **Description**: No description available - **Primary Language**: Unknown - **License**: GPL-3.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-05 - **Last Updated**: 2026-08-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README
# OpenPnP C# · Offline Simulation Workbench [简体中文](README.md) | **English** [![version](https://img.shields.io/badge/version-1.2.0--simulator--workbench--preview-blue)](https://github.com/userqz1/OpenPnP.CSharp/releases) [![.NET](https://img.shields.io/badge/.NET-10.0-512BD4)](https://dotnet.microsoft.com/) [![platform](https://img.shields.io/badge/platform-Windows%20x64-0078D4)](#runtime-requirements) [![tests](https://img.shields.io/badge/tests-1170%20passing-success)](#quality-gates) [![hardware](https://img.shields.io/badge/hardware-LOCKED-red)](#safety-boundary) [![license](https://img.shields.io/badge/license-GPL--3.0-green)](LICENSE.txt) **An independent C#/.NET offline workbench for pick-and-place. It loads real OpenPnP configuration and job files, runs deterministic machine simulation and recorded-image vision, and presents the whole flow in a WPF desktop application.**
--- > [!WARNING] > ### Hardware Locked > > This project contains **no** serial, TCP, USB, live-camera or device-discovery > backend, and must **not** be used to connect to or control a physical machine. > Passing the simulator is not physical-safety or placement-accuracy > certification. --- ## What this is Upstream [OpenPnP](https://github.com/openpnp/openpnp) is a Java/Swing pick-and-place application. This is an **independent C#/.NET reimplementation** scoped to the **offline** part of it: - reads real `machine.xml`, `parts.xml`, `packages.xml`, `boards.xml`, `panels.xml`, `vision-settings.xml` and `.job.xml`; - runs a complete pick-and-place job through a **deterministic simulator**, touching no hardware; - runs vision pipelines over **recorded images**, opening no camera; - presents Job, Vision, Simulator and Diagnostics workspaces in a WPF desktop app. It is not a replacement for OpenPnP. It is an **offline verification sandbox**: run a configuration and a job end to end with no machine, no consumables and no risk. ### Why determinism matters The same input produces **byte-identical** output on any two runs. The simulation reads no wall clock, uses no random numbers and does not depend on thread scheduling — time is a logical tick and randomness is a fixed seed. That is the point rather than an implementation detail: **the output can serve as a regression baseline**. Any behavioural change is caught by a byte comparison instead of being hidden behind "looks about right". --- ## Features | Capability | Notes | |---|---| | **Configuration loading** | Strict parsing of the OpenPnP configuration family; unknown elements/attributes are rejected with a named error code, never silently dropped | | **Byte-exact round trip** | Read and write back reproduces the source document byte for byte (3-space indent, LF, 5-character escape set) | | **Deterministic simulation** | Logical clock plus fixed seed; two independent processes agree byte for byte | | **Pick-and-place jobs** | Full job processor: panels, nested references, skip and failure handling | | **Feeder runtime** | One-shot FeedTickets, three-level nested retry (part / feed / pick), multi-nozzle batching | | **Recorded-image vision** | Finite stage pipeline: template match, circular detection, bottom vision, fiducial location | | **G-code rendering** | Full command stream rendered and transcribed over an in-memory scripted transport — **no port is opened** | | **Connection lifecycle** | Connect → Handshake → ReadPosition → Enable → Home, each explicitly authorized | | **Configuration administration** | Add, edit and remove parts, packages and vision settings, plus save-a-copy | | **Importers** | Headless placement text import (KiCad / Altium style coordinate files) | | **Diagnostics export** | Deterministic, non-overwriting run evidence | --- ## Screenshots
### Job workspace Job workspace ### Simulator workspace Simulator workspace ### Vision workspace Vision workspace ### Diagnostics workspace Diagnostics workspace
> The permanent `OFFLINE ONLY` badge and `EMERGENCY STOP` button are not decoration: the first is enforced by the composition root, and the second is independent of the UI and the scheduler. --- ## Runtime requirements ### Running the application | Item | Requirement | |---|---| | OS | Windows 10 1809+ / Windows 11, **x64** | | Runtime | [.NET 10 Desktop Runtime](https://dotnet.microsoft.com/download/dotnet/10.0) | | Display | 1366×768 or above; verified at 1366/1920 and 100%/125%/150% DPI | | Hardware | **None.** No machine, serial device or camera is needed | The release package is framework-dependent and does not bundle the .NET runtime. ### Building from source | Item | Version | |---|---| | .NET SDK | 10.0.302 (pinned by `global.json`) | | OS | Windows (required by WPF and the `net10.0-windows` target) | | Native dependency | OpenCvSharp (win-x64 / win-x86 natives included) | > Non-Windows platforms can build and test everything except `OpenPnP.Desktop.Wpf`. --- ## Quick start ### Option 1 — download the preview package 1. Download the latest package from [Releases](https://github.com/userqz1/OpenPnP.CSharp/releases); 2. extract it anywhere; 3. run `OpenPnP.Desktop.Wpf.exe`; 4. click **Open** and pick a `.job.xml` — sample projects ship in `test-data/`. ### Option 2 — run from source ```bash git clone https://github.com/userqz1/OpenPnP.CSharp.git cd OpenPnP.CSharp ``` ```bash pwsh tools/Build.ps1 ``` ```bash pwsh tools/Test.ps1 ``` ```bash pwsh tools/Check-NoHardware.ps1 ``` Release build (zero warnings is the pass condition), full test run, and the offline gate that scans the sources for forbidden device APIs. ### Option 3 — headless smoke ```bash dotnet run --project tools/OpenPnP.ProductSmoke -c Release -- verify product/fixtures result.json ``` Loads three built-in fixtures, runs complete jobs and writes deterministic evidence JSON, touching no hardware. --- ## Architecture Dependencies point one way. **WPF never appears in Domain or Application**, and architecture tests enforce it: ``` ┌──────────────────────────────────────────────────────────────┐ │ Desktop.Wpf MVVM shell, no business logic │ │ net10.0-windows │ └───────────────────────────┬──────────────────────────────────┘ │ ┌───────────────────────────▼──────────────────────────────────┐ │ Application.Offline offline workbench service │ │ load → job → vision → diagnostics │ └───────────────────────────┬──────────────────────────────────┘ │ ┌───────────────────────────▼──────────────────────────────────┐ │ Application hardware-neutral contracts │ │ MachineSessionStateMachine │ │ MachineCommandScheduler (one FIFO) │ │ DeterministicPnpJobProcessor │ └──────┬─────────────────┬──────────────────┬──────────────────┘ │ │ │ ┌──────▼───────┐ ┌───────▼────────┐ ┌──────▼─────────┐ │ Hardware. │ │ Hardware. │ │ Vision │ │ Simulator │ │ Gcode │ │ finite stages │ │ deterministic│ │ IGcodeTransport│ │ Vision. │ │ models │ │ in-memory only │ │ OpenCvSharp │ └──────┬───────┘ └───────┬────────┘ └──────┬─────────┘ │ │ │ ┌──────▼─────────────────▼──────────────────▼──────────────────┐ │ Persistence.OpenPnpXml hand-written strict readers and │ │ byte-exact Simple-XML writers │ └───────────────────────────┬──────────────────────────────────┘ │ ┌───────────────────────────▼──────────────────────────────────┐ │ Domain Length / LengthUnit / Location │ │ Package / Part / Footprint │ │ Job / Board / Placement │ │ JavaDouble / JavaTextFormat │ └──────────────────────────────────────────────────────────────┘ ``` ### Design constraints 1. **Java numeric semantics.** `JavaDouble` and `JavaTextFormat` reproduce Java's double and formatting behaviour, including where half-way rounding differs. All numeric formatting goes through them; `double.ToString` at a call site is forbidden. 2. **Explicit invariance.** `InvariantGlobalization` is deliberately **not** set, so every format and parse site must pass `CultureInfo.InvariantCulture` explicitly, mirroring Java's explicit `Locale.US`. 3. **Quantities keep their units.** `Length` and `Location` never degrade to bare numbers. 4. **One scheduler.** Every machine command goes through the same FIFO scheduler and state machine; there is no bypass. 5. **The connection lifecycle is explicit authorization.** `MachineSessionStateMachine` performs no I/O and holds no transport, timer or clock. A caller authorizes a transition, does its own I/O, then reports the outcome. A refusal throws *before* returning, so a refused operation cannot have written a byte. 6. **Byte-exact XML.** 3-space indent, LF, no declaration, the 5-character escape set (`& < > " '`), `@Version`-driven strict/lenient behaviour. Unknown data is rejected with a named error code rather than silently dropped. --- ## Safety boundary This is a hardware-locked product, and the boundary is held by structure rather than by convention: | Boundary | How it is held | |---|---| | No serial / TCP / USB | No `SerialPort`, `TcpClient` or `Socket` exists in the sources; `Check-NoHardware.ps1` gates it | | No live camera | No `VideoCapture` or device enumeration; vision consumes recorded images only | | No device discovery | The composition root offers no endpoint selector | | G-code is rendered only | The single `IGcodeTransport` implementation is an in-memory scripted transport | | Emergency stop is independent | It does not pass through the UI or the scheduler | | Evidence is auditable | Every run records `hardwareTouched=false` | > **Passing this simulator is not physical-safety approval.** Axis direction, homing, limits, acceleration, IO mapping, collision and recovery logic all require human review before any real machine is involved. --- ## Quality gates | Gate | Current | |---|---| | .NET suite | **1170 / 1170** | | Java characterization (upstream oracle) | **617 / 617** | | Release build | **0 warnings, 0 errors** (`TreatWarningsAsErrors`) | | Forbidden device API scan | **0 hits** | | Standalone repository suite | **1158 / 1158** | | Default numeric tolerance | **0** (exact) | ### Migration method The port proceeds one verifiable slice at a time, and every slice produces evidence against Java behaviour rather than an impression that it works. - **Golden Master baselines** record raw and normalized output, a SHA-256 manifest and comparison results; - **Two-process repeatability** is required — two runs in one process can agree by accident and hide ordering defects; - **Baselines are immutable** — a behavioural change creates a new version with a recorded supersede reason; - **Zero tolerance by default** — any nonzero tolerance needs an approved per-field policy. --- ## Relationship to upstream OpenPnP - The Java implementation is the **behavioural oracle** and is never modified to make C# pass; - ported areas are backed by Java characterization tests and byte-exact baselines; - **not ported**, explicitly: real serial/TCP transports, live cameras, feeder execution, the Swing UI, and the full scripting surface; - this project does not claim feature parity with upstream, and does not claim to replace it for controlling a real machine. --- ## FAQ **Can I control my machine with this?** No, by design. No hardware backend exists in the product, and a source scan gate prevents one from being introduced. **Why is the package large?** It carries the win-x64 and win-x86 OpenCvSharp natives. The managed assemblies are small. **Linux / macOS?** The core libraries target `net10.0` and build and test anywhere. The WPF shell is Windows-only. **Will it load my existing OpenPnP configuration?** Yes — that is the point. The parser is strict: an element or attribute it does not know is a named error rather than a silent skip, which is what keeps the round trip lossless. **How far can I trust the simulation?** As far as "it deterministically reproduces characterized behaviour". It does not model physical error, mechanical backlash or process variation, and it is not a placement-accuracy predictor. --- ## License [GPL-3.0](LICENSE.txt), matching upstream OpenPnP. Upstream is copyright the [OpenPnP contributors](https://github.com/openpnp/openpnp); see [SOURCE-NOTICE.md](SOURCE-NOTICE.md) for what this repository reimplements.