DeviceConfiguration#

/***********************************************************************************
 *
 * Itala API - Copyright (C) 2022 Opto Engineering
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY SUFFERED BY LICENSE AS
 * A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 *
 ***********************************************************************************/

/**
 * @example DeviceConfiguration.cpp
 *
 * @brief "DeviceConfiguration" example shows how device parameters can
 * be configured using GenApi, in this case image width, height, pixel
 * format and exposure time. Novice GenApi users should read the
 * dedicated section of the Programmer's Guide available within Itala API
 * documentation.
 *
 * @see Grab.cpp
 */

// Include Itala API
#include "ItalaApi/Itala.h"

// Include the GenICam library (for strings and exceptions)
#include "GenICam.h"

#define INDENT "\t"

#define HEIGHT 1024
#define PIXEL_FORMAT "Mono8"
#define EXPOSURE_TIME 90000  // microseconds

template <class V, class T, class B = GenApi::IBase>
bool TrySetValue(const GenApi::CPointer<T, B>& ptr, V val) {
  // Check pointer validity, field availability and writability
  if (!IsAvailable(ptr) || !IsWritable(ptr)) {
    return false;
  }

  try {
    ptr->SetValue(val);
  } catch (GenICam::GenericException& e) {
    std::cout << e.what() << std::endl;
    return false;
  }
  return true;
}

bool TrySetValueFromString(GenApi::IValue* ptr, GenICam::gcstring val) {
  // Check pointer validity, field availability and writability
  if (!IsAvailable(ptr) || !IsWritable(ptr)) {
    return false;
  }

  try {
    ptr->FromString(val);
  } catch (GenICam::GenericException&) {
    return false;
  }
  return true;
}

void DeviceConfiguration_Sample() {
  std::cout << "***** DeviceConfiguration example started. *****" << std::endl << std::endl;

  Itala::ISystem* pSystem = Itala::CreateSystem();
  Itala::DeviceInfoList deviceInfos = pSystem->EnumerateDevices(700);

  if (deviceInfos.size() == 0) throw GENERIC_EXCEPTION("No devices found. Example canceled.");

  if (deviceInfos[0].AccessStatus() != Itala::DeviceAccessStatus::AvailableReadWrite)
    throw GENERIC_EXCEPTION("Target device is unaccessible in RW mode. Example canceled.");

  Itala::IDevice* pDevice = pSystem->CreateDevice(deviceInfos[0]);
  std::cout << "First device initialized." << std::endl << std::endl;
  std::cout << "Camera configuration started.. " << std::endl;

  GenApi::INodeMap& deviceNodeMap = pDevice->GetNodeMap();

  // Get the PixelFormat node
  GenApi::CEnumerationPtr pPixelFormat = deviceNodeMap.GetNode("PixelFormat");

  // Check its validity and if it's in a valid state for being modification
  if (!IsWritable(pPixelFormat))
    throw GENERIC_EXCEPTION("Unable to configure the pixel format. Aborting.");

  // Save the currently active pixel format as integer. This value will be
  // used during the deconfiguration phase to restore the original pixel
  // format.
  uint64_t originalPixelFormat = pPixelFormat->GetIntValue();

  // Set the desired pixel format from its string representation for convenience
  pPixelFormat->FromString(PIXEL_FORMAT);
  std::cout << "PixelFormat set to " << PIXEL_FORMAT << std::endl;

  // The same approach is then used for the other features.
  // Width
  GenApi::CIntegerPtr pWidth = deviceNodeMap.GetNode("Width");
  if (!IsReadable(pWidth))
    throw GENERIC_EXCEPTION("Unable to configure the image width. Aborting.");
  uint64_t originalWidth = pWidth->GetValue();

  // use an utility method to set the width from a string
  if (TrySetValueFromString(pWidth, "1024")) {
    std::cout << "Width set to " << pWidth->GetValue() << std::endl;
  } else {
    std::cout << "Unable to set Width." << std::endl;
  }

  // Height
  GenApi::CIntegerPtr pHeight = deviceNodeMap.GetNode("Height");
  if (!IsReadable(pHeight))
    throw GENERIC_EXCEPTION("Unable to configure the image height. Aborting.");
  uint64_t originalHeight = pHeight->GetValue();

  // use an utility method to set the width from an integer
  if (TrySetValue<int64_t>(pHeight, HEIGHT)) {
    std::cout << "Height set to " << pHeight->GetValue() << std::endl;
  } else {
    std::cout << "Unable to set Height." << std::endl;
  }

  // ExposureTime
  GenApi::CFloatPtr pExposureTime = deviceNodeMap.GetNode("ExposureTime");
  if (!IsReadable(pExposureTime))
    throw GENERIC_EXCEPTION("Unable to configure the exposure time. Aborting.");
  double originalExposureTime = pExposureTime->GetValue();

  // use an utility method to set the ExposureTime from a float
  if (TrySetValue<float64_t>(pExposureTime, EXPOSURE_TIME)) {
    std::cout << "ExposureTime set to " << pExposureTime->GetValue() << std::endl;
  } else {
    std::cout << "Unable to set ExposureTime." << std::endl;
  }

  std::cout << "Rolling back to original camera features state.. " << std::endl;
  pPixelFormat->SetIntValue(originalPixelFormat);
  pWidth->SetValue(originalWidth);
  pHeight->SetValue(originalHeight);
  pExposureTime->SetValue(originalExposureTime);

  pDevice->Dispose();
  pDevice = nullptr;
  std::cout << std::endl << "Device instance disposed." << std::endl;

  pSystem->Dispose();
  pSystem = nullptr;
  std::cout << "System instance disposed." << std::endl;
}

int main(int /*argc*/, char** /*argv*/) {
  try {
    DeviceConfiguration_Sample();
  } catch (GenICam::GenericException& e) {
    std::cout << e.what() << std::endl;
  }
}