Skip to content

Developer Guide

Overview

JsSetup is a tool to create, edit and manage ScanSystem Definition Files. The JoeScan Pinchot API is the programming interface to integrate JS-50 scanners into your application. The API can be complex to manage, as many parameters must be set for a specific scanning task. Also, keeping all the necessary parameters in code is not a good solution, because even small changes may necessitate a recompilation of your application. Most users of the API therefore have developed ad-hoc solutions to keep ScanSystem parameters as settings for their applications.

JoeScan JsSetup is our attempt to standardize the persistence model for ScanSystem parameters. With JsSetup, we provide:

  • a well defined and structured persistence format in the form of a JSON file (ScanSystem Definition File)
  • parser code for the file format, available for C++ and .NET, that behind-the-scenes makes all necessary API calls for you.
  • an editor application with a large amount of convenience functions and error checking (the JsSetup Application)

Of course, using the framework outlined above is completely optional, the Pinchot API is completely sufficient to build complete scanning systems.

Frequently Asked Questions

Can the API write ScanSystem Definition Files?

As of JsSetup v1.0/Pinchot 16.2, the API does not have a persistence layer built in, so writing a ScanSystem you constructed via the API is not possible. Going from JsSetup to the API is a one-way-street, however, we are exploring the possibility of integrating the persistence layer into the Pinchot interface, providing for a complete round-trip solution. Stay tuned!

Can I add my own data to the ScanSystem Definition File?

You certainly can, which makes using the file format quite handy as a general purpose configuration storage for your scanning application. Simply create a top level key in the JSON structure, named "Vendor":

"Vendor": {
    "SuperOptimizerCo": "yes",
    "NuclearLaunchCode": "password123",
    "AttemptWorldDomination": true
}
Anything under the top level Vendor key is under your control, you can add all valid JSON elements in there. JsSetup and the parser will ignore anything in Vendor and just keep it around verbatim, even when saving the file. If you need to access your configuration, run the file through a JSON parser, and ignore everything that is not under Vendor. We are also planning to offer access to the string via the parser. Please check with JoeScan support if you are interested in this option.

Are there things I can do in the API that JsSetup does not support?

There is a small number of differences in how JsSetup and the API work with ScanSystems:

  • mixing ScanHeads of different types: see here. In theory, the API can use laser-driven and camera-driven models together, however, in practice that rarely makes sense.
  • override exposure parameters per phase element: the API does provide the ability to set different exposure parameters per phase element, JsSetup does not support that.
  • use same phase element multiple times: the API allows using the same phase element multiple times (provided the phases are not adjacent), JsSetup does not support that. Note that Frame Scanning also disallows phase element re-use.
  • bitmap based Exclusion Masks. The API allows for the usage of bit masks as Exclusion Masks, JsSetup stores excluded regions as rectangular regions, and renders them on-the-fly into bitmaps.
  • the experimental brightness correction interfaces in the API are not mapped to a JsSetup workspace (yet), this is a planned feature for a future release.

Using the parser

First, add the parser to your application via NuGet: search for JoeScan.Pinchot.Parser and add it to your project.

The parser source code is also distributed with the JsSetup Installer, so alternatively you can copy ScanSystemParser.cs into your project.

using JoeScan.Pinchot.Parser;

var scanSystem = ScanSystemParser.CreateFromFile(<your file name here>);
// you now have a fully instantiated and configured ScanSystem object
scanSystem.Connect(TimeSpan.FromSeconds(1));
// check for Minimum Scan Period
var period = scanSystem.GetMinScanPeriod();
// and get started scanning
scanSystem.StartScanning(period, DataFormat.XYQuarter, ScanningMode.Frame);
That is all there is to using the ScanSystem parser. Error handling has been omitted for clarity.

The parser source code is distributed as a single header file: jsSetupConfigParser.hpp. It is included in the JsSetup Installer, as well as in the download for the Pinchot API, available here. Look for an example in the folder c-api\examples\04-jsSetupConfigParser.

int main(int argc, char *argv[])
{
    if (2 != argc) {
        std::cout << "Usage: " << argv[0] << " FILE" << std::endl;
        return 1;
    }

    // Path to JSON config file.
    std::string path = argv[1];

    // Scan System and Scan Head vector declared here, but uninitialized. Will
    // be initialized in the `jsSetupConfigParse` function.
    jsScanSystem system;
    std::vector<jsScanHead> heads;

    int r = joescan::jsSetupConfigParse(path, system, heads, &logger);

    // Check the results of parsing the configuration file.
    if (0 > r) {
        // The Scan System and Scan Heads should be assumed to be in an
        // indeterminate state; only action to take is to free the Scan System.
        std::cout << "Configuration failed" << std::endl;
        r = 1;
    } else {
        // Scan System and Scan Heads are fully configured.
        std::cout << "Configured successfully" << std::endl;
    }

    // Any user code that needs to be run before scanning should be placed here.
    // After everything is setup and initialized, then connect and begin scanning.

    // Free the Scan System and all of its resources.
    jsScanSystemFree(system);

    return r;
}

/// Log output from `jsSetupConfigParse`
void logger(jsError err, std::string msg)
{
    std::cout << msg << std::endl;
    if (0 != err) {
        // If `err` is non-zero, `jsSetupConfigParse` failed parsing or initializing
        // something in the JSON file.
        const char *err_str = nullptr;
        jsGetError(err, &err_str);
        std::cout << "jsError (" << err << "): " << err_str << std::endl;
    }
}

Comments