LiquidLens#

/***********************************************************************************
*
* 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 LiquidLens.cpp
 *
 * @brief "LiquidLens" example shows how to control optics
 * with integrated liquid lens technology directly from the device,
 * in both current and power mode. The liquid lens functionality is
 * exposed as a custom set of GenICam features in the device nodemap.
 * WARNING: To avoid additional complexity, the following example
 * doesn't restore the initial liquid lens configuration, just its
 * activation state.
 *
 * @see DefectivePixelCorrection.cpp
 * @see Events.cpp
 */

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

// Include the GenICam library
#include "GenICam.h"

#define INDENT "\t"

void LiquidLens_Sample()
{
  std::cout << "***** LiquidLens 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;

  // Enable the liquid lens functionality. Keep the original activation state and restore
  // it at the end of the program.
  GenApi::CBooleanPtr pOeLiquidLensEnable = pDevice->GetNodeMap().GetNode("oeLiquidLensEnable");
  if (!IsWritable(pOeLiquidLensEnable))
    throw GENERIC_EXCEPTION("Unable to activate liquid lens functionality. Aborting.");
  bool originalOeLiquidLensEnable = pOeLiquidLensEnable->GetValue();
  pOeLiquidLensEnable->SetValue(true);

  std::cout << "Liquid lens functionality enabled." << std::endl;

  // Gather some information about the connected liquid lens.
  GenApi::CFloatPtr pOeLiquidLensTemperature = pDevice->GetNodeMap().GetNode("oeLiquidLensTemperature");
  if (!IsReadable(pOeLiquidLensTemperature))
    throw GENERIC_EXCEPTION("Unable to read liquid lens temperature. Aborting.");

  GenApi::CStringPtr pOeLiquidLensSerialNumber = pDevice->GetNodeMap().GetNode("oeLiquidLensSerialNumber");
  if (!IsReadable(pOeLiquidLensTemperature))
    throw GENERIC_EXCEPTION("Unable to read liquid lens serial number. Aborting.");

  std::cout << "Connected lens is " << pOeLiquidLensSerialNumber->GetValue() << std::endl;
  std::cout << "Lens temperature: " << pOeLiquidLensTemperature->GetValue() << " C\370" << std::endl << std::endl;

  // Liquid lenses can be controlled in current or power mode. In the first case, the
  // input given to the lens is an amount of current which results in certain
  // optical power. The second case is the opposite: by specifing the optical power
  // as input, the liquid lens absorbs a certain amount of current.
  // Let's start with current mode.
  GenApi::CEnumerationPtr pOeLiquidLensMode = pDevice->GetNodeMap().GetNode("oeLiquidLensMode");
  if (!IsWritable(pOeLiquidLensEnable))
    throw GENERIC_EXCEPTION("Unable to configure the liquid lens mode. Aborting.");
  pOeLiquidLensMode->FromString("CurrentMode");

  std::cout << INDENT << "Current mode enabled." << std::endl;

  // Get the maximum positive amount of current allowed by the lens so that it can be set.
  GenApi::CFloatPtr pOeLiquidLensMaxPositiveCurrent = pDevice->GetNodeMap().GetNode("oeLiquidLensMaxPositiveCurrent");
  if (!IsReadable(pOeLiquidLensMaxPositiveCurrent))
    throw GENERIC_EXCEPTION("Unable to get the maximum current of the liquid lens mode. Aborting.");

  // Get the node for electrical current set.
  GenApi::CFloatPtr pOeLiquidLensCurrent = pDevice->GetNodeMap().GetNode("oeLiquidLensCurrent");
  if (!IsWritable(pOeLiquidLensCurrent))
    throw GENERIC_EXCEPTION("Unable to configure the amount of current of the lens. Aborting.");
  pOeLiquidLensCurrent->SetValue(pOeLiquidLensMaxPositiveCurrent->GetValue());

  // Get the lens power node and read the amount of optical power resulting from the
  // electrical current set.
  GenApi::CFloatPtr pOeLiquidLensPower = pDevice->GetNodeMap().GetNode("oeLiquidLensPower");
  if (!IsWritable(pOeLiquidLensCurrent))
    throw GENERIC_EXCEPTION("Unable to configure the amount of power of the lens. Aborting.");

  std::cout << INDENT << "Lens set to the maximum allowed current, " << pOeLiquidLensMaxPositiveCurrent->GetValue() << " mA." << std::endl;
  std::cout << INDENT << "Resulting lens power is " << pOeLiquidLensPower->GetValue() << " dpt." << std::endl << std::endl;

  // Switch to power mode.
  pOeLiquidLensMode->FromString("PowerMode");
  std::cout << INDENT << "Power mode enabled." << std::endl;

  // Get the minimum lens power allowed as input and set it.
  double minLensPower = pOeLiquidLensPower->GetMin();
  pOeLiquidLensPower->SetValue(minLensPower);

  std::cout << INDENT << "Lens set to the minimum power allowed, " << pOeLiquidLensPower->GetValue() << " dpt." << std::endl;
  std::cout << INDENT << "Resulting lens current is " << pOeLiquidLensCurrent->GetValue() << " mA." << std::endl << std::endl;

  // Restore the original lens activation state.
  pOeLiquidLensEnable->SetValue(originalOeLiquidLensEnable);


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

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

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