GrabTrigger#

/***********************************************************************************
*
* 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 GrabTrigger.cpp
 *
 * @brief "GrabTrigger" is an extension of the simple Grab example which introduces
 * the trigger functionality. A triggered acquisition consist of a signal (hardware or
 * virtual, i.e. a command) sent to the camera by the user. When a trigger is received,
 * the camera acquires a frame and makes it available for grab. As usual, the
 * trigger functionality is available via GenApi.
 *
 * Suggested examples:
 * @see GrabChunks.cpp
 * @see Events.cpp
 */

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

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

#define INDENT "\t"
#define ACQUIRE_COUNT 5

void GrabTrigger_Sample()
{
  std::cout << "Grab trigger 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("No devices found. Example canceled.");

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

  std::cout << std::endl << "Configuring trigger mode.." << std::endl;

  // Select the "action" that must be performed when the trigger is received.
  GenApi::CEnumerationPtr pTriggerSelector = pDevice->GetNodeMap().GetNode("TriggerSelector");
  if (!IsWritable(pTriggerSelector))
    throw GENERIC_EXCEPTION("Unable to select the trigger type. Aborting.");
  pTriggerSelector->FromString("FrameBurstStart");

  // Set the source of the trigger. In this case, a software trigger (which is
  // just a command) is used.
  GenApi::CEnumerationPtr pTriggerSource = pDevice->GetNodeMap().GetNode("TriggerSource");
  if (!IsWritable(pTriggerSource))
    throw GENERIC_EXCEPTION("Unable to configure the trigger. Aborting.");
  int64_t originalTriggerSource = pTriggerSource->GetIntValue();
  pTriggerSource->FromString("Software");

  // Finally, enable the trigger mode.
  GenApi::CEnumerationPtr pTriggerMode = pDevice->GetNodeMap().GetNode("TriggerMode");
  if (!IsWritable(pTriggerMode))
    throw GENERIC_EXCEPTION("Unable to configure the trigger. Aborting.");
  int64_t originalTriggerMode = pTriggerMode->GetIntValue();
  pTriggerMode->FromString("On");

  pDevice->StartAcquisition();
  std::cout << "Acquisition started." << std::endl << std::endl;

  Itala::IImage* pImage = 0;
  for (size_t i = 0; i < ACQUIRE_COUNT; i++)
  {
    // Send the software trigger to acquire the image.
    GenApi::CCommandPtr pTriggerSoftware = pDevice->GetNodeMap().GetNode("TriggerSoftware");
    if (!IsWritable(pTriggerSoftware))
      throw GENERIC_EXCEPTION("Unable to send software trigger command. Aborting.");
    pTriggerSoftware->Execute();

    std::cout << INDENT << "Software trigger sent, image acquired. " << std::endl;
    std::cout << INDENT << "Press Enter to grab the acquired image." << std::endl;
    std::cin.ignore(1000000000, '\n');

    pImage = pDevice->GetNextImage(1000);
    if (pImage->IsIncomplete())
    {
      // Report some info if the image is partially filled.
      std::cout << INDENT << "Image " << i << " is incomplete." << std::endl;
      std::cout << INDENT << INDENT << "Bytes filled: " << pImage->GetBytesFilled() << "/" << pImage->GetPayloadSize() << std::endl;
      std::cout << INDENT << INDENT << "Timestamp: " << pImage->GetTimestamp() << std::endl;
    }
    else
    {
      std::cout << INDENT << "Image " << i << " grabbed." << std::endl;
    }

    // DO SOMETHING WITH THE IMAGE..

    pImage->Dispose();
    pImage = nullptr;

    std::cout << std::endl;
  }

  pDevice->StopAcquisition();

  // Restore the original values
  pTriggerSource->SetIntValue(originalTriggerSource);
  pTriggerMode->SetIntValue(originalTriggerMode);

  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
  {
    GrabTrigger_Sample();
  }
  catch (GenICam::GenericException& e)
  {
    std::cout << e.what()  << std::endl;
  }
}