Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support a case where none of the GenTL entities does not have XML file but only the remote device does. #159

Closed
JamesMTSloan opened this issue May 15, 2020 · 7 comments
Labels
bug Something isn't working
Milestone

Comments

@JamesMTSloan
Copy link

Describe the bug
I am testing the potential use of Harvester with a private (not freely available) CTI and camera. In this particular System > Interface > Device > RemoteDevice scenario I believe that only the RemoteDevice has a node map available.

In ImageAcquirer.__init__() it seems to me that this case is almost, but not quite, supported:

try:
node_map = _get_port_connected_node_map(
port=system.port, logger=self._logger,
xml_dir_to_store=self._xml_dir
)
except GenericException as e:
self._logger.error(e, exc_info=True)
else:
self._system = System(module=system, node_map=node_map)
#
try:
node_map = _get_port_connected_node_map(
port=interface.port, logger=self._logger,
xml_dir_to_store=self._xml_dir
)
except GenericException as e:
self._logger.error(e, exc_info=True)
else:
self._interface = Interface(
module=interface, node_map=node_map, parent=self._system
)
#
try:
node_map = _get_port_connected_node_map(
port=device.local_port, logger=self._logger,
xml_dir_to_store=self._xml_dir
) # Local device's node map
except GenericException as e:
self._logger.error(e, exc_info=True)
else:
self._device = Device(
module=device, node_map=node_map, parent=self._interface
)
#
try:
node_map = _get_port_connected_node_map(
port=device.remote_port, logger=self._logger,
file_path=file_path, xml_dir_to_store=self._xml_dir
) # Remote device's node map
except GenericException as e:
self._logger.error(e, exc_info=True)
else:
self._remote_device = RemoteDevice(
module=self._device, node_map=node_map, parent=self._device
)

The first issue I encounter is that _get_port_connected_node_map() throws LogicalErrorException('The target port does not hold any URL.'), which is not caught by the GenericException block. I don't know if this is intended behaviour or not, but if I modify each except block to except (GenericException, LogicalErrorException) as e: it will then keep trying to extract the node map from the next component in the chain.

However, with the above modification once the node map of the RemoteDevice is loaded it attempts to create RemoteDevice with a reference to its parent self._device. In this scenario this object has not been created because the node map could not be found.

Now, all of this is dependent on my scenario of only having a valid node map for RemoteDevice being a valid scenario; please let me know if this is not the case with GenICam. I see that System, Interface, Device and RemoteDevice all accept None as a potential argument for node_map so this would suggest that no single one of them requires a valid node map.

If this is the case then perhaps the following would be a suitable fix:

        try:
            node_map = _get_port_connected_node_map(
                port=system.port, logger=self._logger,
                xml_dir=self._xml_dir
            )
        except (GenericException, LogicalErrorException) as e:
            self._logger.error(e, exc_info=True)
            node_map = None
        self._system = System(module=system, node_map=node_map)

        #
        try:
            node_map = _get_port_connected_node_map(
                port=interface.port, logger=self._logger,
                xml_dir=self._xml_dir
            )
        except (GenericException, LogicalErrorException) as e:
            self._logger.error(e, exc_info=True)
            node_map = None
        self._interface = Interface(
            module=interface, node_map=node_map, parent=self._system
        )

        #
        try:
            node_map = _get_port_connected_node_map(
                port=device.local_port, logger=self._logger,
                xml_dir=self._xml_dir
            )  # Local device's node map
        except (GenericException, LogicalErrorException) as e:
            self._logger.error(e, exc_info=True)
            node_map = None
        self._device = Device(
            module=device, node_map=node_map, parent=self._interface
        )

        #
        try:
            node_map = _get_port_connected_node_map(
                port=device.remote_port, logger=self._logger,
                file_path=file_path, xml_dir=self._xml_dir
            )  # Remote device's node map
        except (GenericException, LogicalErrorException) as e:
            self._logger.error(e, exc_info=True)
            node_map = None
        self._remote_device = RemoteDevice(
            module=self._device, node_map=node_map, parent=self._device
        )

If at least one node map is required then this could easily be checked for.

This would then lead to two other changes:

  • ImageAcquirer._setup_data_streams() would require the same change to the except block as above

  • self.device.node_map.disconnect()

    Should perhaps be self.remote_device.node_map.disconnect()

To Reproduce
Steps to reproduce the behaviour:

  1. Use a camera and CTI system in which the only node map present is found in the RemoteDevice
  2. Load the CTI and perform an update() with the camera connected
  3. Call create_image_acquirer()
  4. See error

Expected behaviour
I expected the System, Interface and Device objects to be created without node maps, with all information contained by RemoteDevice.

Desktop (please complete the following information):

  • OS: Windows10
  • Python: 3.7
  • Harvester: 1.2.0
  • GenTL Producer: Own
  • Camera: Own

Thanks for your work on this project. Your attitude and enthusiasm are delightful.

@kazunarikudo
Copy link
Member

@JamesMTSloan

Hi James, thank you for trying out Harvester. Do you mean you have a scenario where none of the GenTL entities other than a remote device has its XML file? If so, it's also a totally valid use case but I had never thought about it before. Okay, I will change Harvester so that it can handle your use case. I will let you know once I created a development branch that you can try.

Thanks for your work on this project. Your attitude and enthusiasm are delightful.

Thank you for your kind words. However, to be honest, I do not know if I'm doing something valuable for other people. Yeah, I'd be happy if their works are making other people happy though. But sometimes it's annoying to handle a case where I need to respond to some rude/lazy/sloppy guys...

Anyway, I've got your use case and I'll ping you once it turned available. /Kazunari

@kazunarikudo kazunarikudo added the bug Something isn't working label May 15, 2020
@kazunarikudo kazunarikudo changed the title Using Harvester with only one node map (in RemoteDevice) Support a case where none of the GenTL entities does not have XML file but only the remote device does. May 15, 2020
@JamesMTSloan
Copy link
Author

Yes that is indeed the scenario I am trying to describe. Great, thanks.

I'm sure it has already been valuable for many people, for example it has already helped me locate some flaws in our CTI implementation. The longer this is around and the more mature it gets, the more likely it is that it will have played some part in positive projects and end-applications.

kazunarikudo added a commit that referenced this issue May 15, 2020
Now Harvester accepts a use case where none of GenTL entities does not
provide device description XML file.
@kazunarikudo
Copy link
Member

@JamesMTSloan Hi, James. I have just pushed the change to a development branch called _issue_159. Could you try that out when you can and let me know if it worked for you, please?

@kazunarikudo kazunarikudo added this to the 1.2.1 milestone May 15, 2020
@JamesMTSloan
Copy link
Author

OK that looks good to me, I seem to get the same funcionality that I was able to reach after my own tweaks. Thanks for getting round to this so quickly.

My only comment on the code would be that you have added an import for itertools that it looks like you didn't use in the end.

kazunarikudo added a commit that referenced this issue May 15, 2020
Removed itertools.
@kazunarikudo
Copy link
Member

@JamesMTSloan I have just removed that import statement. Thanks! If you are okay to merge the changes in the master please let me know anytime. I'll do that when I can.

@JamesMTSloan
Copy link
Author

I think this can be closed and merged yeah. Cheers.

@kazunarikudo
Copy link
Member

@JamesMTSloan Thanks. Cheers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants