Skip to content

Commit ebad5da

Browse files
authored
DS402: Increase delay to check status on homing start. (#252)
* ds402: Increase delay to check status on homing start. The Statusword is examined immediately after setting the Controlword command to start homing. That is very likely to fail because of the round-trip time until the Statusword is actually updated from a TPDO. To work around that, the delay between each check of the Statusword should be moved before the actual comparison, and its default value increased. Introduce a new constant TIMEOUT_CHECK_HOMING to configure that with a default value of 100 ms. This replaces the previously used INTERVAL_CHECK_STATE which is only 10 ms by default. An even better solution would be to wait for the Statusword to be updated by a received PDO, but that would be much more complex. * Apply interval to is_homed() method as well. Same problem as in the homing() method, PDO updates of the Statusword need at least one SYNC / PDO cycle duration. * Factor out common _homing_status() method. Move the common code from is_homed() and homing() to a method for internal use. Add a comment why the delay is necessary and how it should possibly be replaced by an RPDO reception check. Should the latter be implemented, there will be only one place to change it.
1 parent 8523a68 commit ebad5da

File tree

1 file changed

+15
-12
lines changed

1 file changed

+15
-12
lines changed

canopen/profiles/p402.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ class BaseNode402(RemoteNode):
204204
TIMEOUT_SWITCH_STATE_SINGLE = 0.4 # seconds
205205
INTERVAL_CHECK_STATE = 0.01 # seconds
206206
TIMEOUT_HOMING_DEFAULT = 30 # seconds
207+
INTERVAL_CHECK_HOMING = 0.1 # seconds
207208

208209
def __init__(self, node_id, object_dictionary):
209210
super(BaseNode402, self).__init__(node_id, object_dictionary)
@@ -275,6 +276,18 @@ def is_faulted(self):
275276
bitmask, bits = State402.SW_MASK['FAULT']
276277
return self.statusword & bitmask == bits
277278

279+
def _homing_status(self):
280+
"""Interpret the current Statusword bits as homing state string."""
281+
# Wait to make sure an RPDO was received. Should better check for reception
282+
# instead of this hard-coded delay, but at least it can be configured per node.
283+
time.sleep(self.INTERVAL_CHECK_HOMING)
284+
status = None
285+
for key, value in Homing.STATES.items():
286+
bitmask, bits = value
287+
if self.statusword & bitmask == bits:
288+
status = key
289+
return status
290+
278291
def is_homed(self, restore_op_mode=False):
279292
"""Switch to homing mode and determine its status.
280293
@@ -286,11 +299,7 @@ def is_homed(self, restore_op_mode=False):
286299
if previous_op_mode != 'HOMING':
287300
logger.info('Switch to HOMING from %s', previous_op_mode)
288301
self.op_mode = 'HOMING'
289-
homingstatus = None
290-
for key, value in Homing.STATES.items():
291-
bitmask, bits = value
292-
if self.statusword & bitmask == bits:
293-
homingstatus = key
302+
homingstatus = self._homing_status()
294303
if restore_op_mode:
295304
self.op_mode = previous_op_mode
296305
return homingstatus in ('TARGET REACHED', 'ATTAINED')
@@ -311,16 +320,10 @@ def homing(self, timeout=TIMEOUT_HOMING_DEFAULT):
311320
t = time.monotonic() + timeout
312321
try:
313322
while homingstatus not in ('TARGET REACHED', 'ATTAINED'):
314-
for key, value in Homing.STATES.items():
315-
# check if the Statusword after applying the bitmask
316-
# corresponds with the needed bits to determine the current status
317-
bitmask, bits = value
318-
if self.statusword & bitmask == bits:
319-
homingstatus = key
323+
homingstatus = self._homing_status()
320324
if homingstatus in ('INTERRUPTED', 'ERROR VELOCITY IS NOT ZERO',
321325
'ERROR VELOCITY IS ZERO'):
322326
raise RuntimeError('Unable to home. Reason: {0}'.format(homingstatus))
323-
time.sleep(self.INTERVAL_CHECK_STATE)
324327
if time.monotonic() > t:
325328
raise RuntimeError('Unable to home, timeout reached')
326329
logger.info('Homing mode carried out successfully.')

0 commit comments

Comments
 (0)