Support a case where none of the GenTL entities does not have XML file but only the remote device does.
JamesMTSloan opened this issue · comments
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:
harvesters/src/harvesters/core.py
Lines 1754 to 1801 in 0835ce0
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 theexcept
block as above -
harvesters/src/harvesters/core.py
Line 1968 in 0835ce0
Should perhaps beself.remote_device.node_map.disconnect()
To Reproduce
Steps to reproduce the behaviour:
- Use a camera and CTI system in which the only node map present is found in the RemoteDevice
- Load the CTI and perform an
update()
with the camera connected - Call
create_image_acquirer()
- 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.
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
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.
@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?
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.
@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.
I think this can be closed and merged yeah. Cheers.
@JamesMTSloan Thanks. Cheers.