Repository navigation
Object Dictionary does not get updated #520
Description
Activity
You're right in your expectation about the OD getting updated. That's what a
LocalNodeshould be doing through itsSdoServermember.Now I think you might be looking at the wrong thing and therefore coming to wrong conclusions. The
ODVariableholds all the metadata about the object, and especially the actual value for a local SDO node. TheSdoVariableis pretty much only an adapter to make SDO reading and writing easier. It points back to its associatedODVariable.Now accessing local data through SDO is not wrong, as you might have thought. It basically just accesses the current cached data in the OD. There is no network overhead involved when calling this for a
LocalNode. But of course you can also just look up theODVariableobject and use that directly the data should be identical.If not, how can I access an Variable with index and subindex?
There is a
get_variable()method on both the object dictionary and the SDO server class. That's how you easily find the right variable. But beware of the second argument's default value: if not specified, it will give you subindex 0 of any record or array.tag version 2.1.0.
Hello, just to add more details as I encounter exactly the same situation : Try to simulate a node and access local object dictionnary.- Usage of create_node to load an hardware EDS. My default eds file value for object 0x1006 ('Communication cycle period') is 50000
- From external equipement, i am using SDO to write into object 0x1006 (.phys) 40000. (This object is the the sync period).
- On the local node, i have tried to get the 0x1006 object value by using this methods:
syncCycle = node.object_dictionary[0x1006] syncCycle = node.object_dictionary['Communication cycle period'] syncCycle = node.object_dictionary['Communication cycle period']|0] syncCycle = node.object_dictionary[0x1006][0] syncCycle = node.object_dictionary.getVariable(0x1006) syncCycle = node.object_dictionary.getVariable(0x1006,0)All above method return an object which is the copy of the eds file and not the updated values.
The object properties are as follow:- values = None
- default = 50000
- default_raw = 50000
I found correct data updated inside another object named node.datastore which is access by sdo methods.
It confirms that the only thing that is working is passing by SDO methods to access the object dictionnary even in Local node.
Working exemple:syncCycle = node.sdo[0x1006].phys syncCycle = node.sdo['Communication cycle period'].physWhat is missleading, is that inside the documentation https://canopen.readthedocs.io/en/latest/od.html, we may read:
device_name_obj = node.object_dictionary['ManufacturerDeviceName'] vendor_id_obj = node.object_dictionary[0x1018][1] actual_speed = node.object_dictionary['ApplicationStatus.ActualSpeed'] command_all = node.object_dictionary['ApplicationCommands.CommandAll']The above code found in the library documentation does not work for local node as it's value is not updated by SDO
The documentation should be updated.
Regards
JulienI think you may be misunderstanding the docs here. The mentioned examples give you access to the
ODVariableobject, which serves as a descriptor of the OD entry. It holds the metadata, such as min / max / default value in its attributes. The additional.valueattribute is populated when dealing with DCF files, where values for a concrete device instance can be recorded for commissioning. In contrast, EDS files follow the same format, but are more like a blueprint description of all matching devices, not a single instance.What you want to achieve is basically a local data store of the objects' contents. That is not what the Object Dictionary implementation in this library does. But it is available by accessing the
LocalNode.data_storeattribute. However, that works only based on numeric index / subindex and it holds only the rawbytesfor an object. If you want to work with the content, you better access it through theLocalNode.sdointerface. That gives you access to theSdoServerclass instance, which works both for access from the bus, as well as for local access from within your program.I guess you figured this out on your own, but somehow came to the conclusion that this would be the wrong way. As far as I can see, it is the intended and most useful way to access the data. Because all the logic of interpreting the raw byte content according to the OD description does not need to be duplicated when it's already handled in the SDO access classes.
Of course, you can also use the callbacks-based functionality in
SdoServerto implement your own data storage. It's just that theObjectDictionaryclass is not meant for that purpose.Thank it clarify the distinction between OD entry and actual data values. My main confusion is that i am using others C++ canOpen stacks and they consider OD has data true storage. We have EDS properties and data values in the same object. This library do otherwise.
Maybe a comment that OD stand for Object Descriptor and not Object Dictionary in the doc may help others like me that are coming from C++ world.Thanks again for the explanation.
I have a real CAN-network with one device connected. This device tries to interact with another node that I want to simulate by a LocalNode object, which workds fine. I created an object dictionary with one ODVariable with the particular index and subindex on which the real device tries to perform an SDO Download (e.g. 0x1F51, 0x01) and assigned it to the LocalNode object.
The SDO Download completes successfully what I can observe via candump. However, when I try to access the value via the object dictionary from the local node, I can't see the updated value but the default one from the initialization. The only way I can access the updated value is via "node.sdo[0x1F51].raw", which is an SdoVariable and not the original ODVariable. At this point, I can not provide any subindex and when a second ODVariable got assigned before with the same index but different subindex, I only can check the updated value from the most recently added Variable.
I don't know if I understand wrong the concept of the different variable classes, but my guess was that the object dictionary of the LocalNode gets updated when another Node performs SDO Downloads.
If not, how can I access an Variable with index and subindex?