NGetAsFloat blocks EventDispatcher

Hello,

i have a problem with getting Events from the Event-Dispatcher.
In our app we need to get Disconnecting and Reconnecting Events from the Camera (we are using a C5-1280-GigE). I copied the C+±Example from here.
This works perfectly. Every event is printed.
But in our code we are polling a node (Input1Level) and this is not working.
To reproduce the problem i added the following code to the example:

    void getTrigger()
    {
        if (!isConnected_)
        {
            return;
        }

        NODEMAP nmap;
        NMHGetNodeMap(handle_, nmap);
        std::string nodeName = "Input1Level";
        NODE node;
        double nodeValue = -1.0;
        auto result = NMGetNode(nmap, nodeName.c_str(), node);
        if (result >= 0)
        {
                result = NGetAsFloat(node, nodeValue);
        }
    }

This method is called in the While-Loop of main with camera.getTrigger().

But when i call this, the EventDispatcher never calls the registered Callback for Disconnected or Reconnected Event (problem seems to be the NGetAsFloat call). It is only called if i increase the sleeping time in the while-loop to 2000 milliseconds. So with the 100 ms from the example it does not work. But for us it is no option to wait for 2 seconds. We must recognize the change as fast as possible.

I also tried to use the existing API-Method NRegisterUpdate for getting notified if the node changes.

    void RegisterNodeUpdate()
    {
        NODEMAP nmap;
        NMHGetNodeMap(handle_, nmap);
        std::string nodeName = "Input1Level";
        NODE node;
        auto result = NMGetNode(nmap, nodeName.c_str(), node);
        NODECALLBACK callb = nullptr;
        cvbres_t error = NRegisterUpdate(node, &Camera::OnNodeUpdate, this, callb);
        if( error )
            throw std::runtime_error("Error registering INotify event");
    }

I disabled the polling (getTrigger method) and i thought that the callback should be called when the node value changes. But the callback “OnNodeUpdate” is never called. The NRegisterUpdate returns with no error.

Maybe someone can help me to fix this issue or give me a hint what i can try.
I am developing under Windows 10 with Version 13.00.000 of CVB.
An update of the CVB-Software would be a bit difficult and i would only do it if i have no other possibility and i must be sure that it does not lead to the same problem.

Thanks in advance for helping,
Dominik

Hi @dominik19

After reproducing your situation, I was encountering the same problem with CVB 13.00.000. I also verified, that it does not occur in the current release. Therefore, I would strongly advise you to upgrade to 13.02.000. Our portability commitment on the C-API allows an upgrade while the interface stays the same. In addition, this release includes the new object oriented c++ wrappers.
If this is absolutely impossible, I would invite you to contact our support for a detailed analysis of your situation.

Regards

First, you leak your handles in both your methods. You need to call ReleaseObject on the NODEMAP and NODE handles when you are done with them.

Secondly the GenApi does not automatically poll node values. The Updated event is called on any change in the NODE. This can be because of a write on another NODE or because you call NMPoll and the NODE in question is pollable.

Also keep in mind that the Updated callback is stored in the handle object. Thus if you release it, the callback won’t be fired. Therefore you need to store the NODE handle somewhere and release it later.

The C++ API shipped with :cvb: 13.02.000 makes this much easier.

Regarding the connection handling, this is a different issue. It looks like there is a problem in :cvb: 13.00.000. Why is it problematic to update?

Thanks for your replies and the improvements of my code.
I have already talked to the support but they recommended to write into this forum.

An update would not be problematic but it would be time consuming since we need to update a lot of systems. Thats the reason why i must be sure that it works with the newer version.

I have removed all leaks from my code (thanks for your hints). The nodemap and the node are now members of the Camera-Class and released when Camera-Object gets destroyed.
My new getTrigger method looks like this now:

void getTrigger()
{
    if (!isConnected_)
    {
        return;
    }

    double nodeValue = -1.0;
    auto result = NGetAsFloat(inputNode_, nodeValue);
    if (result < 0)
    {
        CVC_ERROR_CODES errorCode = CVC_ERROR_CODES(CVC_ERROR_FROM_HRES(result));
        std::cout << "Error code: " << errorCode << std::endl;
    }
}

On our testsystem i have updated the CVB Version to 13.02. But this leads to nearly the same error (i did not use the C+±-Api, still using C-Api). If i set the sleeping time between the trigger-calls to less then 1000 milliseconds the event-handlers will not be called.
Could the C+±Api fix this error or is it just a wrapper around the C-Api-Calls which would mean that the same problem would exists if i change to the C+±Api?

@parsd Do i understand you correctly that a node value of this node will not call the registered callback since the updatedEvent is not triggered on a node value change? So polling is necessary?

Thanks in advance,
Dominik

The Cvb++ API is just a header only facade around our C-API making programming programming with :cvb: much easier and faster. Thus if there is a problem in the underlying libraries - which might be the case with the connection handling - then the Cvb++ API won’t help.

Regarding the GenApi: lets use the consultant answer: it depends :smiley:

If you use the GenApi and did not activate any events (e.g. GEV message channel) or chunk data, then the GenApi only updates if you, as the user, do something with it. The GenApiGrid for example uses a UI timer to regularly call NMPoll to ensure updates. So the Updated event is only called when you change anything yourself.

In the other cases the camera sends data:

  1. :cvb: can hook the transport layer events to the GenApi. Thus when such an event occurs the GenApi automatically updates. These are normally the features under the EventControl category.
  2. :cvb: can also hook into chunk data delivered with the frames. These are normally to be found under the ChunkDataControl category.

Also we are looking into the disconnected issue. As a work-around, until we have a solution, you can trigger your disconnected event yourself, when the getTrigger method reports an error (I think it was CVC_E_TIMEOUT?).

@parsd we also thought about this workaround. Another one should be that we reduce the polling time to more than 1 second if getTrigger reports an error. And reset the polling time when getTrigger runs without an error.

1 Like

@dominik19 The disconnection timeout issue is fixed now. You will need a new version of the siGevSvc.exe. Can you please send me your email address as PM or write to our support (support@stemmer-imaging.de) and ask for the siGevSvc.exe so I can send it to you?

2 Likes

This sounds great. I wrote an email to your support.
Is it correct that this new executable must be installed to “C:\Windows\System32”?

Thank you for the message. I sent you the updated files and the change will also be present in our next service release (CVB 13.02.002). You are correct, the siGevSvc is installed to “C:\Windows\System32” where it is run as Windows service. You can also use the new siGevSvc.exe to uninstall and install the service like so (for future reference):

- Start Cmd as Admin
- Switch to folder with new siGevSvc.exe (cd)
- Stop the old currently running service: siGevSvc.exe –o
- Remove old installed service: siGevSvc.exe –d
- Install new service: siGevSvc.exe –i
- Start new service: siGevSvc.exe -t
1 Like