Skip to content

Documentation doesn't clearly state what happens after an abort #482

Open
@atomictom

Description

@atomictom

By @hamishwillee's suggestion, I'm opening this because I was trying to figure out what happens after a connection abort (i.e. heartbeat_timeout is exceeded), and the documentation does not make it clear. After looking through dronekit/init.py, I see on lines 1099-1102:

                if self._heartbeat_error and self._heartbeat_error > 0 and time.time(
                ) - self._heartbeat_lastreceived > self._heartbeat_error:
                    raise APIException('No heartbeat in %s seconds, aborting.' %
                                       self._heartbeat_error)

Looking at dronekit/mavlink.py, I can see that the exception will cause the handler thread to exit:

            try:
                while True:
                    # Downtime
                    time.sleep(0.05)

                    # Loop listeners.
                    for fn in self.loop_listeners:
                        fn(self)

...

            except APIException as e:
                errprinter('>>> ' + str(e.message))
                self._alive = False
                self.master.close()
                self._death_error = e
                return

I think the documentation could be improved by stating that the abort will cause the connection to permanently close (while a heartbeat_warning will not), and that if this behavior is not desired, to set the timeout to a large value. If an abort occurs, @hamishwillee suggested that the only recourse would be a reconnect, and the documentation should state this. Also, in the case of an abort, I'm not sure how to detect it from a script (to go about doing a reconnect).

One other issue, is that a reconnect would issue a new vehicle object, but all the decorated message/attribute listeners on the top level (say in a module) would have already been initialized, and would not be updated. Meaning if you expect a reconnect, you would need to re-declare all your decorated handlers with the new vehicle object (probably inside an initialization function).

Edit to illustrate my point:

# Is only called when the module is imported, cannot be updated...
@vehicle.on_attribute('location')
def listener(...)
    ...
def initialize(vehicle):
    # Called each time we call initialize. Sets up listeners on new vehicle
    @vehicle.on_attribute('location') 
    def listener(...)
         ...

It might also be worth considering if it should be possible to disable it completely (say, pass in a timeout of -1).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions