简体   繁体   中英

"Node is not writable" exception after a camera crash

I'm using the Spinnaker SDK for controlling FLIR cameras. If at any moment the application crashes with a camera being used, every next execution of the application throws an AccessException , like:

Spinnaker::GenApi::CommandNode::Execute: Message = GenICam::AccessException= Node is not writable. : AccessException thrown in node 'UserSetLoad' while calling 'UserSetLoad.Execute()'

The only solution I've found so far is to unplug and plug in the camera, but this is not an acceptable solution in some environments where the application is going to be used.

Here a sample code (not fully compilable since it is extracted from a larger codebase, but gives you an idea of the workflow):

// System instance is prepared before using the camera
Spinnaker::SystemPtr m_system = Spinnaker::System::GetInstance();

// Method in class that initializes the camera 
bool initCamera(int index)
{
  SmartCameraList cameras(m_system->GetCameras());

  const auto cameras_count = cameras.GetSize();
  if (cameras_count < 1) { return false; }

  if (index >= (int)cameras_count) { return false; }

  m_camera = cameras[index];

  if (!m_camera) { return false; }

  if (m_camera->IsInitialized()) { return false; } // passes
  m_camera->DeInit(); // does nothing
  m_camera->Init();
  if (!m_camera->IsInitialized()) { return false; } // passes

  // Default properties
  try {
    m_camera->UserSetSelector.SetValue(UserSetSelector_Default);
    m_camera->UserSetDefault.SetValue(UserSetDefault_Default);
    m_camera->UserSetLoad.Execute(); //< thrown here

    m_camera->BalanceWhiteAuto.SetValue(BalanceWhiteAuto_Continuous);
    m_camera->SensorShutterMode.SetValue(SensorShutterMode_Global);
  } catch (Spinnaker::Exception e) {
    std::cout << e.GetFullErrorMessage() << '\n';
    return false;
  }

  return true;
}

// m_system->ReleaseInstance() is called when the application finishes using the camera

As you can see, camera is correctly initialized, but it seems that something else is holding the camera.

I've checked in official forums, looking for more generic GenICam related issues and nothing.

Is there any way to reset the camera before using it?

I solved this issue by connecting and disconnecting to the camera SW wise.

Starting capture by launching the following code in a separate thread:


void Cam::MainThread(){
    m_cameraHandler->BeginAcquisition();
    while(m_threadCtx.wait(ZERO_DURATION)){ //sleepwait
        try {

            ImagePtr pResultImage = m_cameraHandler->GetNextImage(1000);
            const size_t width = pResultImage->GetWidth();
            const size_t height = pResultImage->GetHeight();

            cv::Mat_<uint16_t> img(height,width);
            memcpy(img.data,pResultImage->GetData(),pResultImage->GetWidth()*pResultImage->GetHeight()*sizeof(uint16_t));
                        
            if (pResultImage->IsIncomplete())
                cout << "Error";
            else {
                pResultImage->Release();
            }
        }
        catch (Spinnaker::Exception& e)
        {
            CLerror << "Error: " << e.what();
        }
    }
}

Then stopping the camera

    m_threadCtx.stop();
    m_pMainThread->join();
    m_cameraHandler->EndAcquisition();
    m_cameraHandler->DeInit();
    m_cameraHandler = nullptr;
    m_spCameraList = nullptr;

    delete(m_pMainThread);

After that you can open the camera and upload the file again and it should work.

worked for me

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM