C++ API reference

The Imatest Hardware Control package is a set of APIs and Graphical user interfaces to provide methods of controlling Imatest hardware devices. The APIs provide a consistent interface for sending and receiving commands from the devices typically over USB or other computer connection. The included ControlStudio program provides visual and interactive access to the devices.

Using the SDK

To begin using the Hardware Control API and Tools, Download the SDK zip file that corresponds to your OS. Various tools, SDKs and Bindings are provided inside the zip file to help facilitate control of Imatest hardware devices with a consistent API and GUI.

Development Concepts

Control Systems, Controllers, and Devices

The API has a primary class called ControlSystem. Typically 1 of these needs to be instantiated.

Controllers can be added to the ControlSystem. These objects control 1 or more devices and sometimes represent a hub or stand alone physical controller.

Devices can be added to the Controllers. Controllers Expect 1 or more (depending on the nature of the controller) devices that the controller is responsible for managing.

After adding Controllers and Devices, calling ControlSystem::initializeDevices() will connect (USB connection or similar) to all connected controllers and devices.

After this initialization is finished, Commands can be added to devices for runtime one-way or bi-directional control.

CommandPackage, and CommandStatus

A Command is created by creating a CommandPackage and adding it to a device, this will create a CommandStatus object that can be used to control the commands execution progress and monitor it's status:

//create a CommandPackage
auto cp1 = std::make_shared<DeviceCommandPackage>();

//create a CommandStatus object after adding the CommandPackage to the device.
auto cs = myDevice->addCommand(cp1.get());

A command will be created with the parameters given in the passed DeviceCommandPackage (cp1). The CommandStatus object (cs) can then be used to start/stop/update the command on the device:

//run the command until it is finished (blocking execution)
cs->runFull();

//start a command to run asynchronously ()
cs->runAsync();

//wait until the above command is finished.
cs->waitFinished();

A command can also be manual stepped during program execution by calling cs->update() methods.

while commands are running - parameters from the CommandPackage are directly used and accessed. (such as target positions for actuators etc.)

These parameters can be changed while a command is running - however it is not strictly thread safe - meaning a command could be making calculations on changing parameters before a final communication result is passed to the hardware. Thread-safe alterations to parameters can be made by utilizing the UpdatePackage facility:

//start an async command
cs->runASync();

//prepare an UpdatePackage which will be a deep copy of the original cp1 CommandPackage.
auto updatePackage = dynamic_cast<MovementCommandPackage*>(cp1->prepareUpdatePackage());

//update parameters
updatePackage->disp_target -= 1;

//mark the UpdatePackage as ready.  This will signal that the cp1 parameters be updated when the Command is ready to safely read the parameters before its next internal update.
cp1->markUpdatePackageReady();

//wait until command is finished at program end.
cs->waitFinished();

Feedback state information can be read from a command by using the CommandStatus::stateInfo() function, this will return a CommandStateInfo object containing the any relevent state information from the device. For example the current position and velocity of an actuator:

//start an async command
cs->runASync();

while (!cs->isFinished()) {

    //print the current position
    auto state = dynamic_cast<MovementStateInfo*>(cs->stateInfo());
    printf("position: %f, velocity: %f", state.currentPos, state.currentVel);
}

This can be used in tandum with Command UpdatePackages to achieve bi-directional control loops with a device.

Memory Management

ControlSystems, Controllers, Devices, Command Packages are created in user-side code. Management of the memory is left to the user-side code. The Library does not own and will not delete these objects.

ControlStatus Objects are created/owned by the library and released by the library.

ControlSystems must be un-initilized before user-side managed Controllers, Devices, and Command Packages are released by using the ControlSystem::uninitialize() command which will properly free ControlStatus objects and un-bind other objects tracked by the controlsystem and clean up any outstanding connections etc. It is important this is called before objects can be freed on user side code.

Using the ControlStudio GUI

The SDK also comes with a native GUI interface for connecting and controlling hardware. The Executable can be found in the bin directory of the SDK.