Skip to content

Commit 36c8488

Browse files
meifonglowacolomb
andauthored
Add support for loading DCF configuration to remote node (#427)
Handle PDO-related objects through the associated methods in the PdoBase class when initializing a RemoteNode from an ObjectDictionary with provided values (DCF file usually). This avoids the locally cached mapping information to get out of sync with the PDO configuration parameters, and thus eliminates the need to read back those same objects. The PdoBase.read() method must honor DCF-provided values for this purpose. It previously only respected the OD default values when called with from_od=True. Co-authored-by: André Colomb <[email protected]>
1 parent 02ebc0c commit 36c8488

File tree

2 files changed

+22
-6
lines changed

2 files changed

+22
-6
lines changed

canopen/node/remote.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,16 +146,23 @@ def load_configuration(self) -> None:
146146
147147
Iterate through all objects in the Object Dictionary and download the
148148
values to the remote node via SDO.
149-
Then, to avoid PDO mapping conflicts, read back (upload) the PDO
150-
configuration via SDO.
149+
To avoid PDO mapping conflicts, PDO-related objects are handled through
150+
the methods :meth:`canopen.pdo.PdoBase.read` and
151+
:meth:`canopen.pdo.PdoBase.save`.
151152
152-
:see-also: :meth:`canopen.pdo.PdoBase.read`
153153
"""
154+
# First apply PDO configuration from object dictionary
155+
self.pdo.read(from_od=True)
156+
self.pdo.save()
157+
158+
# Now apply all other records in object dictionary
154159
for obj in self.object_dictionary.values():
160+
if 0x1400 <= obj.index < 0x1c00:
161+
# Ignore PDO related objects
162+
continue
155163
if isinstance(obj, ODRecord) or isinstance(obj, ODArray):
156164
for subobj in obj.values():
157165
if isinstance(subobj, ODVariable) and subobj.writable and (subobj.value is not None):
158166
self.__load_configuration_helper(subobj.index, subobj.subindex, subobj.name, subobj.value)
159167
elif isinstance(obj, ODVariable) and obj.writable and (obj.value is not None):
160168
self.__load_configuration_helper(obj.index, None, obj.name, obj.value)
161-
self.pdo.read() # reads the new configuration from the driver

canopen/pdo/base.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,11 +320,20 @@ def add_callback(self, callback: Callable[[PdoMap], None]) -> None:
320320
self.callbacks.append(callback)
321321

322322
def read(self, from_od=False) -> None:
323-
"""Read PDO configuration for this map using SDO."""
323+
"""Read PDO configuration for this map.
324+
325+
:param from_od:
326+
Read using SDO if False, read from object dictionary if True.
327+
When reading from object dictionary, if DCF populated a value, the
328+
DCF value will be used, otherwise the EDS default will be used instead.
329+
"""
324330

325331
def _raw_from(param):
326332
if from_od:
327-
return param.od.default
333+
if param.od.value is not None:
334+
return param.od.value
335+
else:
336+
return param.od.default
328337
return param.raw
329338

330339
cob_id = _raw_from(self.com_record[1])

0 commit comments

Comments
 (0)