Camera registration
Cutters, plotters and lasers with a camera (or an optical sensor) can correct a job to the material: printed vinyl that has stretched, a sheet laid down a little turned, a roll that wanders as it feeds. ParametriQ CAD does this with camera registration extensions: before a machine profile that names one writes its job, the extension is told where the drawing's registration marks should be, and says where the camera found them. The job is then fitted to the marks - frame by frame along a long job - and written corrected, whatever the format.
How it works
- Place registration marks with the Registration Mark Tool: at the corners of the design, or, for a long job, in rows along the selection's length. Every circle (or dot) on the Registration layer is a mark.
- The marks are grouped into frames along the feed (the marks' longer side, unless the profile says X or Y): marks level with each other along the feed make a row, and each two neighbouring rows make a frame. Four corners are one frame; six rows along a roll are five. The first frame reaches back to the start of the job and the last on to its end.
- For each frame in turn, the extension's
registeris given the frame's marks where the drawing has them and gives back where they really are. - A homography (see HOMOGRAPHY) is fitted to each frame's marks - exactly with four, the least-squares best fit with more - or the profile's model. With fewer marks found than the model needs, the most flexible model they allow is used (three: affine; two: move, turn and scale; one: a move).
- If a frame's marks are further off the fit than the profile allows (the root mean square of their distances, in millimetres), the job is stopped and nothing is written. The report says how far off each frame was.
- The job is written with each element placed on the material: its curve cut where frames meet, each part moved by its own frame's fit. Lines stay straight; arcs and circles become the ellipses (or other curves) the fit makes of them, and each format writes them as it writes any curve. A drill hole is moved to where its centre goes and keeps its size.
With exactly four marks a homography always fits them exactly, so the error is 0 and a badly measured mark can't be caught. Give each frame more marks (Marks across 3 in the Registration Mark Tool gives six) to have the fit checked.
Machine coordinates
Marks are given, and found marks given back, in millimetres (whatever the drawing's units), with X and Y as in the drawing, from the drawing's origin - where the machine formats put the drawing. Set the machine's origin where the drawing's origin lies on the material, or have the extension measure from it. While a registered job is written, GP-GL and LightBurn keep that origin instead of moving the job to its lower left corner.
Written frame by frame ("frames": "perFrame"), each frame is measured and written from its own origin: its first
row of marks along the feed. That suits machines that feed the material on and set their origin again for each frame.
In each format
| Format | A job in one go (oneJob) |
Frame by frame (perFrame) |
|---|---|---|
| HP-GL | One file, every frame in machine coordinates | One file: each frame's program from its own origin, with PG; (HP-GL/2 Advance Full Page) between them to feed the material on |
| GP-GL | One file, from the drawing's origin | A file for each frame (name-f01.gpgl …): GP-GL has no feed command in the documented set this writes |
| G-code, DXF, CF2, LightBurn | One file | A file for each frame |
| Post-processors | Given the corrected cuts, as from any export | Run once for each frame, a file each |
Picture and page formats (PDF, SVG, the laser SVG, which places the job on its own page) aren't registered.
A roll cutter fed one job feeds the material itself as the coordinates go along it: check that your cutter takes the whole length in one job (most limit it).
Declaring a camera registration
cameraRegistration({
name: "My camera",
description: "Reads the marks with the cutter's camera.",
model: "homography", // or "affine", "similarity", "rigid", "translation", "auto"
maxError: 0.3, // mm: a frame's marks further off than this (RMS) stop the job
services: ["http://localhost:8765/"], // the addresses httpRequest may reach
options: { exposure: { label: "Exposure", type: "number", value: 10, unit: "ms" } },
begin(job, options) { }, // before the first frame (optional)
register(job, options) { // each frame
return job.marks.map(m => [m.x + 0.4, m.y - 0.2]);
},
end(report, options) { } // after the last (optional)
});
options are declared as for other extensions; a profile can set them. register may be an
async function or return a promise: it is waited for.
What register is given
| Property | Meaning |
|---|---|
marks |
The frame's marks where the drawing has them: each {index, x, y, diameter} (index: the mark's number in the job). |
expected |
The same positions, as {x, y}. |
frame |
{index, number, count, from, to, start, end, origin}: from 0 and from 1, how many, where it starts and ends along the feed (null: the job's own end), its first and last row of marks, and its origin. |
frames, axis |
How many frames the job has, and the feed: "x" or "y". |
extent |
The extent of all the job's marks: {minX, minY, maxX, maxY}. |
units |
Always "mm". |
name, profile, machine, format |
The drawing's name, and the machine profile, its machine and its export format. |
What register gives back
- A list with a position for each mark, in the same order:
[x, y]or{x, y}in millimetres, ornullfor a mark the camera couldn't find (it is left out of the fit). - Or
{ marks: [...] }. - Or
null: leave this frame as drawn.
Throwing an error stops the job, with the message.
Reaching a camera
An extension can't reach files or the network, except that while it measures (in begin, register and end) it can
send requests to the services it declares:
| Function | Meaning |
|---|---|
httpRequest(url, {method, headers, body, timeout}) |
Sends a request and waits for the answer: {status, ok, text, json} (json: the answer read as JSON, or null). method is "GET" if left out; a body that is an object or list is sent as JSON; timeout is in seconds (30 if left out). The url must start with one of the declared services. |
Each call of register must finish within the time an extension call is given (ten seconds): a camera that takes
longer should be driven by a service that measures in the background and is asked for its results.
In a machine profile
A profile names its registration in its file (see Profiles in files):
"registration": {
"extension": "Simulated camera",
"options": { "turn": 0.5 },
"model": "homography",
"maxError": 0.3,
"feed": "auto",
"frames": "oneJob",
"split": true
}
| Setting | Meaning |
|---|---|
extension |
The cameraRegistration's name. |
options |
Its options (the others as it declares them). |
model |
The fit; left out: the extension's, else a homography. |
maxError |
The most a frame's marks may be off (RMS, mm); left out: the extension's, else 0.5. |
feed |
"auto" (the marks' longer side), "x" or "y". |
frames |
"oneJob" or "perFrame" (see In each format). |
split |
true: elements are cut where frames meet, each part corrected by its own frame. false: each element kept whole, corrected by the frame its middle is in (no cut is split; best for small pieces). |
File › Send Using Machine Profile that profile then measures, fits and writes; the Interactive window lists each frame's marks found, its error and the worst mark, and how far apart neighbouring frames put the line where they meet.
The extensions that come with the app
The app's registration.js (copy it to your Extensions folder to change it) has:
- Simulated camera: finds each mark where a known turn, stretch, keystone and move put it, with measuring noise and a mark thrown out if asked: for trying registration out and testing a setup. The profile Vinyl cutter with camera registration (HP-GL) uses it.
- Camera service (HTTP): a template for a camera reached through a service on the same computer
(
http://localhost:8765/register): it posts each frame's job as JSON and reads{ "marks": [[x, y], …] }(or{ "skip": true }) back, and tells the service when the job begins and ends.
See also: Registration Mark Tool, Machine profiles, HOMOGRAPHY, Extensions, Drawing API.