From 0dffc61048babfe0fb213f9feb0b09935f50aa4c Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 23 Sep 2015 17:02:17 +1000 Subject: [PATCH 001/475] DKPY2 fixes to getting started, running examples, and developer setup windows. Consequent fixups to links elsewhere --- docs/about/license.rst | 2 +- docs/about/overview.rst | 2 +- docs/contributing/developer_setup_windows.rst | 52 +---- docs/examples/running_examples.rst | 54 ++---- docs/guide/getting_started.rst | 181 ++++++++---------- docs/guide/migrating.rst | 20 +- docs/guide/sitl_setup.rst | 2 +- docs/guide/vehicle_state_and_parameters.rst | 2 +- examples/vehicle_state/vehicle_state.py | 3 - 9 files changed, 117 insertions(+), 201 deletions(-) diff --git a/docs/about/license.rst b/docs/about/license.rst index a7b95cc12..1fe406e2d 100644 --- a/docs/about/license.rst +++ b/docs/about/license.rst @@ -2,7 +2,7 @@ Open Source Licence ======================= -DroneKit-Python is licensed under the *Apache License Version 2.0, January 2004 (http://www.apache.org/licenses/). This is present in the `LICENSE `_ file in the source tree, and reproduced below: +DroneKit-Python is licensed under the *Apache License Version 2.0, January 2004* (http://www.apache.org/licenses/). This is present in the `LICENSE `_ file in the source tree, and reproduced below: .. include:: ../../LICENSE :literal: \ No newline at end of file diff --git a/docs/about/overview.rst b/docs/about/overview.rst index f0221b13f..f9372f8a2 100644 --- a/docs/about/overview.rst +++ b/docs/about/overview.rst @@ -13,7 +13,7 @@ Open source community DroneKit-Python is an open source and community-driven project. You can find all the source code on `Github here `_ and check out our permissive :doc:`Apache v2 Licence `. -If you want to join the community, then see our :doc:`contributing section ` for lots of ideas on how you can help. +If you want to join the community, then see our :doc:`contributing section <../contributing/index>` for lots of ideas on how you can help. Compatibility diff --git a/docs/contributing/developer_setup_windows.rst b/docs/contributing/developer_setup_windows.rst index 81d7e90b1..494775d0c 100644 --- a/docs/contributing/developer_setup_windows.rst +++ b/docs/contributing/developer_setup_windows.rst @@ -6,60 +6,12 @@ Building DroneKit-Python on Windows This article shows how to set up an environment for *developing* DroneKit-Python on Windows. -.. tip:: - - If you just want to *use* DroneKit-Python on Windows then easiest way to get started is to use the - :ref:`Windows Installer <_get_started_install_dk_windows>`. The installer is rebuilt with every patch - release, so you can always be up to date with the latest features and bug fixes. - Install DroneKit using WinPython command line ============================================= -First set up a command line DroneKit-Python installation using *WinPython*. This Python distribution already includes most of the needed dependencies (though you will need remove *python-dateutil* as the installation comes bundled with a version that does not work with *DroneKit*). - -The steps to install this package and the most important add-on modules are: - -#. Download and run the correct `WinPython installer `_ (**v2.7**) for your platform (win32 vs win64). - - * Run the installer as an administrator (**Right-click** on file, select **Run as Administrator**). - * When prompted for the destination location, specify **C:\Program Files (x86)** - (the default location is under the **Downloads** folder). - -#. Register the Python that came from *WinPython* as the preferred interpreter for your machine: - Open the folder where you installed WinPython, run *WinPython Control Panel* and choose **Advanced/Register Distribution**. - - .. image:: http://dev.ardupilot.com/wp-content/uploads/sites/6/2014/03/Screenshot-from-2014-09-03-083816.png - -#. Install DroneKit-Python and its remaining dependencies (including `MAVProxy `_) from the public PyPi repository: - - Open the *WinPython Command Prompt* and run the following two commands: - - .. code:: bash - - pip uninstall python-dateutil - pip install dronekit - -The dependencies above are all that are required to build DroneKit-Python and the *MAVProxy command line* (i.e. the minimum needed for testing). -If you also want the *MAVProxy console* and map install: - -#. OpenCV - - * `Download and install OpenCV version 2.4 for Windows `_ (this can be extracted anywhere) - * Copy/paste the file :file:`cv2.pyd` from :file:`OpenCV\\build\\python\\2.7\\x64\\` to :file:`site_packages` - on your Python installation (e.g. :file:`\\python-2.7.6.amd64\\Lib\\site-packages`). -#. WxPython - - * `Download and install WxPython `_. Make sure the target - path is your WinPython installation. -#. Console - - * Open the WinPython command prompt and enter: - - .. code:: bash - - pip install console +First set up a command line DroneKit-Python installation using *WinPython*. This process is the same as described in :ref:`Getting Started `. @@ -78,7 +30,7 @@ Fetch and build DroneKit source python setup.py install - + Updating DroneKit ================= diff --git a/docs/examples/running_examples.rst b/docs/examples/running_examples.rst index 7bfd2e898..2989bb3b4 100644 --- a/docs/examples/running_examples.rst +++ b/docs/examples/running_examples.rst @@ -4,8 +4,11 @@ Running the Examples ==================== -General instructions for running the example source code are given below (more explicit instructions may be -provided in the documentation for each example): +General instructions for running the `example source code `_ are given below. + +.. tip:: + + More explicit instructions may be provided within the documentation for each example, and on the command line using the ``-h`` (help) parameter. #. Get the DroneKit-Python example source code onto your local machine. The easiest way to do this is to clone the **dronekit-python** repository from Github. On the command prompt enter: @@ -14,49 +17,30 @@ provided in the documentation for each example): git clone http://github.com/dronekit/dronekit-python.git - .. tip:: - - The :ref:`Windows Installation ` copies the example code here: - :file:`C:\\Program Files (x86)\\MAVProxy\\examples\\`. - -#. Start MAVProxy and :ref:`connect to the vehicle `. For example: - - * To connect to a simulated vehicle when starting *MAVProxy* (from the command line): - - .. code-block:: bash - - mavproxy.py --master=127.0.0.1:14550 - * To connect to a simulated vehicle after starting MAVProxy (for example, on Windows): - - .. code-block:: bash - - link add 127.0.0.1:14550 - -#. You should already have set up *MAVProxy* to :ref:`load DroneKit automatically `. - If not, manually load the library using: + +#. Navigate to the example you wish to run (or specify the full path in the next step). The examples are all stored in + subdirectories of **dronekit-python\\examples\\**. + + To run the :ref:`vehicle_state ` example, you would navigate as shown: .. code-block:: bash - module load dronekit.module.api - -#. Once the *MAVProxy* console is running, start the example by entering: + cd dronekit-python\examples\vehicle_state\ - .. code-block:: bash - api start absolute_path_to_example/example_name.py - - .. tip:: +#. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: - If you start *MAVProxy* from the same directory as the target script you can omit - the full file path: + .. code-block:: bash - .. code-block:: bash + python vehicle_state.py --connect 127.0.0.1:14550 - api start example_name.py - + .. note:: + + The examples all use the ``--connect`` parameter to pass the :ref:`connection string ` into the script. + The command above would be used to connect to :ref:`SITL ` running on the local machine via UDP port 14550. + .. warning:: Propellers should be removed before testing examples indoors (on real vehicles). - diff --git a/docs/guide/getting_started.rst b/docs/guide/getting_started.rst index 349c748ec..1cd97adf9 100644 --- a/docs/guide/getting_started.rst +++ b/docs/guide/getting_started.rst @@ -9,9 +9,8 @@ on the vehicle and communicate with the autopilot via a serial port. However, du prototype apps on a standard Mac, Windows, or Linux computer using a *simulated* autopilot. -This topic explains how to set up and run DroneKit-Python (within MAVProxy) on the different host operating systems -and then run a basic DroneKit app. - +This topic explains how to set up and run DroneKit-Python on the different host operating systems +and then create and run a basic DroneKit app. @@ -21,7 +20,7 @@ Setting up the vehicle/autopilot For information on how to set up a vehicle (real and simulated) see: * :ref:`supported-companion-computers` for links to tested hardware/software configurations for a number of onboard Linux computers. -* :ref:`sitle_setup` for links explaining how to set up a simulated vehicle for Copter, Plane, or Rover. +* :ref:`sitl_setup` for links explaining how to set up a simulated vehicle for Copter, Plane, or Rover. @@ -40,11 +39,10 @@ If you are using Ubuntu or Debian Linux you can get most of the *DroneKit* depen .. code:: bash - sudo apt-get install python-pip python-dev python-opencv python-serial python-pyparsing python-wxgtk2.8 + sudo apt-get install python-pip python-dev -The remaining dependencies (including `MAVProxy `_), are -installed when you get DroneKit-Python from the public PyPi repository: +The remaining dependencies are installed when you get DroneKit-Python from the public PyPi repository: .. code:: bash @@ -61,151 +59,129 @@ installed when you get DroneKit-Python from the public PyPi repository: Installing DroneKit on Mac OSX ------------------------------ -If you're on Mac OSX, you can use `Homebrew `_ to install *WXMac*. +Install DroneKit-Python and its dependencies from the public PyPi repository: .. code:: bash - brew tap homebrew/science - brew install wxmac wxpython opencv - + sudo pip install droneapi numpy + -Uninstall *python-dateutil* (OSX and Windows come bundled with a version that is not supported for some dependencies): -.. code:: bash - - sudo pip uninstall python-dateutil +.. _get_started_install_dk_windows: -Install DroneKit-Python and its remaining dependencies (including `MAVProxy `_) from the public PyPi repository: +Installing DroneKit on Windows +------------------------------ -.. code:: bash +Set up a command line DroneKit-Python installation using *WinPython* (this Python distribution already includes most of the needed dependencies). +<<<<<<< HEAD sudo pip install pyparsing sudo pip install dronekit +======= +#. Download and run the correct `WinPython installer `_ (**v2.7**) for your platform (win32 vs win64). + + * Run the installer as an administrator (**Right-click** on file, select **Run as Administrator**). + * When prompted for the destination location, specify **C:\\Program Files (x86)** + (the default location is under the **Downloads** folder). +>>>>>>> DKPY2 fixes to getting started, running examples, and developer setup windows. Consequent fixups to links elsewhere +#. Register the Python that came from *WinPython* as the preferred interpreter for your machine: -.. _get_started_install_dk_windows: + Open the folder where you installed WinPython, run *WinPython Control Panel* and choose **Advanced/Register Distribution**. -Installing DroneKit on Windows ------------------------------- + .. image:: http://dev.ardupilot.com/wp-content/uploads/sites/6/2014/03/Screenshot-from-2014-09-03-083816.png -The easiest way to set up DroneKit-Python on Windows is to use the Windows Installer. -This is applied over the top of the *MAVProxy* Windows installation and includes all needed -dependencies and the DroneKit-Python examples. +#. Install DroneKit-Python and its remaining dependencies from the public PyPi repository: -.. tip:: + Open the *WinPython Command Prompt* and run the following command: - A new version of the Windows Installer is created with every patch revision (`get old versions - here `_). - Don't forget to update regularly for bug fixes and new features! - -To install DroneKit-Python using the installer: + .. code:: bash -#. Download and run the `latest MAVProxy installer `_ - — accept all prompts. -#. Download and run the `latest DroneKit installer `_ - — accept all prompts (install in the same location as MAVProxy). + pip install droneapi -The installer packages DroneKit-Python as an application, which is launched by double-clicking an icon -in the system GUI. After the *MAVProxy prompt* and *console* have started you can -:ref:`connect to the vehicle ` (instead of setting the -connection when starting *MAVProxy*). You will still need to :ref:`load DroneKit ` (not done by the installer -- see `#267 `_). The examples are copied to :file:`C:\\Program Files (x86)\\MAVProxy\\examples\\`. + + +.. _get_started_connect_string: -It is also possible to set up DroneKit-Python on the command line (see :ref:`dronekit_development_windows`). +.. _get_started_connecting: +Connecting to a Vehicle +======================= -.. _starting-mavproxy: +The connection to the vehicle is set up within the DroneKit script. Scripts import and call the :py:func:`connect()` method. +After connecting this returns a :py:class:`Vehicle ` object from which you can get/set parameters +and attributes, and control vehicle movement. -Starting MAVProxy -================= +.. code:: python -Before executing DroneKit scripts you must first start *MAVProxy* and connect to your autopilot (simulated or real). -The connection to the vehicle can be set up on the command line when starting *MAVProxy* or after MAVProxy is running. + from droneapi import connect + + # Connect to UDP endpoint. + vehicle = connect('127.0.0.1:14550', await_params=True) + +.. note:: -.. tip:: + Calling ``connect()`` with ``await_params=True`` (as shown above) ensures that the method will not return until + :py:attr:`Vehicle.parameters ` is fully populated with values from the vehicle. + Vehicle *attributes* are populated in parallel but are not guaranteed to have values when ``connect()`` completes + (an attribute will have value ``None`` if a corresponding MAVLink message has not been received - for example, + if the attribute is not supported by the vehicle). - If you're using DroneKit-Python from the Windows installer there is no way to pass command line options to MAVProxy; - you will have to start MAVProxy by double-clicking its icon and then :ref:`connect to the target vehicle after MAVProxy - has started `. +The example above connects to the udp address ``127.0.0.1:14550``. The table below shows addresses to use some of +the more common connection types: -Connecting at startup ---------------------- -The table below shows the command lines used to start *MAVProxy* for the respective connection types: -.. list-table:: MAVProxy connection options +.. list-table:: Connection string options :widths: 10 10 :header-rows: 1 * - Connection type - - MAVProxy command + - Connection string * - Linux computer connected to the vehicle via USB - - ``mavproxy.py --master=/dev/ttyUSB0`` + - ``/dev/ttyUSB0`` * - Linux computer connected to the vehicle via Serial port (RaspberryPi example) - - ``mavproxy.py --master=/dev/ttyAMA0 --baudrate 57600`` + - ``/dev/ttyAMA0 --baudrate 57600`` * - SITL connected to the vehicle via UDP - - ``mavproxy.py --master=127.0.0.1:14550`` + - ``127.0.0.1:14550`` * - OSX computer connected to the vehicle via USB - - ``mavproxy.py --master=/dev/cu.usbmodem1`` + - ``dev/cu.usbmodem1`` * - Windows computer connected to the vehicle via USB - - ``mavproxy.py --master=/dev/cu.usbmodem1`` - -For other connection options see the `MAVProxy documentation `_. + - ``/dev/cu.usbmodem1`` -.. _starting-mavproxy_set_link_when_mavproxy_running: - -Connecting after startup ------------------------- - -To connect to the autopilot once *MAVProxy* has already started use ``link add `` in the *MAVProxy command prompt*, where ```` -takes the same values as ``master`` in the table above. For example, to set up a connection to SITL running on the local computer at port 14550 do: - -.. code:: bash - - link add 127.0.0.1:14550 - -If you're connecting using a serial port you may need to first set up the baud rate first (the default is 57600). You can change the default baudrate used for -new connections as shown: - -.. code:: bash - - set baudrate 57600 #Set the default baud rate for new connections (do before calling "link add") - -See `Link Management `_ (MAVProxy documentation) for more information. - - - - -.. _loading-dronekit: - -Loading DroneKit -================ - -*DroneKit* is implemented as a *MAVProxy* module (MAVProxy is installed automatically with DroneKit). -The best way to load the *DroneKit* module into *MAVProxy* is to -`add it to the startup script `_ (**mavinit.scr**). - -Linux/MAC OSX: - -.. code:: bash +.. tip:: +<<<<<<< HEAD echo "module load dronekit.module.api" >> ~/.mavinit.scr +======= + The strings above are the same as you would use if connecting with MAVProxy. For other options see the + `MAVProxy documentation `_. +>>>>>>> DKPY2 fixes to getting started, running examples, and developer setup windows. Consequent fixups to links elsewhere -Windows: + +You can start this simple script in the same way you would start any other standalone Python script. -.. code:: bash +.. code-block:: bash +<<<<<<< HEAD echo module load dronekit.module.api >> %HOMEPATH%\AppData\Local\MAVProxy\mavinit.scr +======= + python your_dronekit_script.py +>>>>>>> DKPY2 fixes to getting started, running examples, and developer setup windows. Consequent fixups to links elsewhere -Alternatively you can choose to manually (re)load *DroneKit* into *MAVProxy* every time you need it: +<<<<<<< HEAD .. code-block:: bash :emphasize-lines: 1 MANUAL> module load dronekit.module.api DroneAPI loaded MANUAL> +======= +.. todo:: Connect method here needs to link to the function, but it isn't exported yet. Fix that once the API tidied. + +>>>>>>> DKPY2 fixes to getting started, running examples, and developer setup windows. Consequent fixups to links elsewhere @@ -214,6 +190,7 @@ Alternatively you can choose to manually (re)load *DroneKit* into *MAVProxy* eve Running an app/example ====================== +<<<<<<< HEAD This section shows how to run the :ref:`Vehicle State ` example, which reads and writes :ref:`vehicle state and parameter ` information. @@ -289,5 +266,9 @@ The steps are: Got MAVLink msg: COMMAND_ACK {command : 11, result : 0} ... +======= +This SDK has :ref:`numerous examples `. We recommend you start with :ref:`example-vehicle-state`, +which reads and writes :ref:`vehicle state and parameter ` information. +>>>>>>> DKPY2 fixes to getting started, running examples, and developer setup windows. Consequent fixups to links elsewhere -For more information on running the examples (and other apps) see :ref:`running_examples_top`. +For general information on running the examples (and other apps) see :ref:`running_examples_top`. diff --git a/docs/guide/migrating.rst b/docs/guide/migrating.rst index fca08b729..2af1ec245 100644 --- a/docs/guide/migrating.rst +++ b/docs/guide/migrating.rst @@ -52,20 +52,22 @@ You must specify the target vehicle address in your script (in DKPY 1.x this was The code fragment below shows how you import the :py:func:`connect() ` method and use it to return a connected :py:class:`Vehicle ` object. The address string passed to ``connect()`` takes the same -values as were passed to MAVProxy when setting up a connection in DKPY 1.x (in this case, a SITL instance running on the same computer). +values as were passed to *MAVProxy* when setting up a connection in DKPY 1.x (in this case, a SITL instance running on the same computer). .. code:: python from dronekit import connect - # Connect to the Vehicle - vehicle = connect('127.0.0.1:14550') - - # Wait for attributes to accumulate. - time.sleep(5) + # Connect to the Vehicle (in this case a UDP endpoint) + vehicle = connect('127.0.0.1:14550', await_params=True) + + +The ``await_params=True`` parameter ensures that ``connect()`` won't return until +:py:attr:`Vehicle.parameters ` has been populated. +This also allows *MAVLink* messages to arrive from the connected vehicle +and populate other ``Vehicle`` attributes. -The thread is normally suspended for a few seconds after connecting. This allows *MAVLink* messages to arrive from the connected vehicle -and populate the ``Vehicle`` attributes (before they are read). The vehicle can then be used in exactly the same way as in DKPY 1.x. +The vehicle can then be used in exactly the same way as in DKPY 1.x. .. note:: @@ -116,7 +118,7 @@ use whatever method you like. .. note:: In DKPY 1.x the script's ``sys.argv`` values were the values passed to MAVProxy when it was - started. To access arguments passed to the script from *MAVProxy you used the ``local_arguments`` array. + started. To access arguments passed to the script from *MAVProxy* you used the ``local_arguments`` array. For example if you started a script as shown below: .. code:: bash diff --git a/docs/guide/sitl_setup.rst b/docs/guide/sitl_setup.rst index 76cd5d839..a83e4bd5f 100644 --- a/docs/guide/sitl_setup.rst +++ b/docs/guide/sitl_setup.rst @@ -1,4 +1,4 @@ -.. _sitle_setup: +.. _sitl_setup: ===================================== Setting up a Simulated Vehicle (SITL) diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index b0b220d9d..0054ffbd3 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -74,7 +74,7 @@ Attributes will also return ``None`` if the associated hardware is not present .. tip:: - If you're using a :ref:`simulated vehicle ` you can add support for optional hardware including + If you're using a :ref:`simulated vehicle ` you can add support for optional hardware including `rangefinders `_ and `optical flow sensors `_. diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index f33eb5228..7f8a9cb41 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -23,9 +23,6 @@ print 'Connecting to vehicle on: %s' % args.connect vehicle = connect(args.connect, await_params=True) -# Wait for attribtues to accumulate. -time.sleep(5) - # Get all vehicle attributes (state) print "\nGet all vehicle attribute values:" print " Location: %s" % vehicle.location From 4c6f5d6b6c85453c887d1bd1cd273a99fe19105f Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 30 Sep 2015 16:35:46 +1000 Subject: [PATCH 002/475] Migrate simple_goto.py --- examples/simple_goto/simple_goto.py | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/examples/simple_goto/simple_goto.py b/examples/simple_goto/simple_goto.py index fb7caeb49..555935e7e 100644 --- a/examples/simple_goto/simple_goto.py +++ b/examples/simple_goto/simple_goto.py @@ -1,18 +1,30 @@ """ simple_goto.py: GUIDED mode "simple goto" example (Copter Only) -The example demonstrates how to arm and takeoff in Copter and how to navigate to -points using Vehicle.commands.goto. +Demonstrates how to arm and takeoff in Copter and how to navigate to points using Vehicle.commands.goto. Full documentation is provided at http://python.dronekit.io/examples/simple_goto.html """ import time +from dronekit import connect from dronekit.lib import VehicleMode, Location from pymavlink import mavutil +import time + + +#Set up option parsing to get connection string +import argparse +parser = argparse.ArgumentParser(description='Print out vehicle state information. Connects to SITL on local PC by default.') +parser.add_argument('--connect', default='127.0.0.1:14550', + help="vehicle connection target. Default '127.0.0.1:14550'") +args = parser.parse_args() + + +# Connect to the Vehicle +print 'Connecting to vehicle on: %s' % args.connect +vehicle = connect(args.connect, await_params=True) -api = local_connect() -vehicle = api.get_vehicles()[0] def arm_and_takeoff(aTargetAltitude): """ @@ -34,7 +46,7 @@ def arm_and_takeoff(aTargetAltitude): vehicle.armed = True vehicle.flush() - while not vehicle.armed and not api.exit: + while not vehicle.armed: print " Waiting for arming..." time.sleep(1) @@ -44,7 +56,7 @@ def arm_and_takeoff(aTargetAltitude): # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.commands.takeoff will execute immediately). - while not api.exit: + while True: print " Altitude: ", vehicle.location.alt if vehicle.location.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. print "Reached target altitude" @@ -72,4 +84,4 @@ def arm_and_takeoff(aTargetAltitude): print "Returning to Launch" vehicle.mode = VehicleMode("RTL") -vehicle.flush() \ No newline at end of file +vehicle.flush() From a88acc688a26dfe97db73758a87756012b17e6ea Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 30 Sep 2015 17:42:27 +1000 Subject: [PATCH 003/475] Migrate guided_set_speed_yaw.py to DKPY2 --- .../guided_set_speed_yaw.py | 25 ++++++++++++++----- examples/guided_set_speed_yaw/readme.md | 3 --- 2 files changed, 19 insertions(+), 9 deletions(-) delete mode 100644 examples/guided_set_speed_yaw/readme.md diff --git a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py index 2729dfc19..ad0134e61 100644 --- a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py +++ b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py @@ -1,16 +1,29 @@ """ +guided_set_speed_yaw.py: (Copter Only) + This example shows how to move/direct Copter and send commands in GUIDED mode using DroneKit Python. Example documentation: http://python.dronekit.io/examples/guided-set-speed-yaw-demo.html """ +from dronekit import connect from dronekit.lib import VehicleMode, Location from pymavlink import mavutil import time import math -api = local_connect() -vehicle = api.get_vehicles()[0] + +#Set up option parsing to get connection string +import argparse +parser = argparse.ArgumentParser(description='Print out vehicle state information. Connects to SITL on local PC by default.') +parser.add_argument('--connect', default='127.0.0.1:14550', + help="vehicle connection target. Default '127.0.0.1:14550'") +args = parser.parse_args() + + +# Connect to the Vehicle +print 'Connecting to vehicle on: %s' % args.connect +vehicle = connect(args.connect, await_params=True) def arm_and_takeoff(aTargetAltitude): @@ -32,7 +45,7 @@ def arm_and_takeoff(aTargetAltitude): vehicle.armed = True vehicle.flush() - while not vehicle.armed and not api.exit: + while not vehicle.armed: print " Waiting for arming..." time.sleep(1) @@ -42,7 +55,7 @@ def arm_and_takeoff(aTargetAltitude): # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.commands.takeoff will execute immediately). - while not api.exit: + while True: print " Altitude: ", vehicle.location.alt if vehicle.location.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. print "Reached target altitude" @@ -341,7 +354,7 @@ def goto(dNorth, dEast, gotoFunction=vehicle.commands.goto): vehicle.flush() - while not api.exit and vehicle.mode.name=="GUIDED": #Stop action if we are no longer in guided mode. + while vehicle.mode.name=="GUIDED": #Stop action if we are no longer in guided mode. remainingDistance=get_distance_metres(vehicle.location, targetLocation) print "Distance to target: ", remainingDistance if remainingDistance<=targetDistance*0.01: #Just below target, in case of undershoot. @@ -460,7 +473,7 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z): goto(0, 260, goto_position_target_global_int) print("Set speed to 10m/s (max).") -set_speed(10, goto_position_target_global_int) +set_speed(10) print("Position North 100 West 130") goto(100, -130, goto_position_target_global_int) diff --git a/examples/guided_set_speed_yaw/readme.md b/examples/guided_set_speed_yaw/readme.md deleted file mode 100644 index 0908d4fac..000000000 --- a/examples/guided_set_speed_yaw/readme.md +++ /dev/null @@ -1,3 +0,0 @@ -# Guided Demo - -Please check the documentation folder for more info \ No newline at end of file From f832e8b5af28d446fa006d641e75604db5d47189 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 12 Oct 2015 11:41:11 +1100 Subject: [PATCH 004/475] Remove git merge rubbish --- docs/guide/getting_started.rst | 113 ++------------------------------- 1 file changed, 7 insertions(+), 106 deletions(-) diff --git a/docs/guide/getting_started.rst b/docs/guide/getting_started.rst index 1cd97adf9..865ba1537 100644 --- a/docs/guide/getting_started.rst +++ b/docs/guide/getting_started.rst @@ -63,7 +63,7 @@ Install DroneKit-Python and its dependencies from the public PyPi repository: .. code:: bash - sudo pip install droneapi numpy + sudo pip install dronekit @@ -74,16 +74,12 @@ Installing DroneKit on Windows Set up a command line DroneKit-Python installation using *WinPython* (this Python distribution already includes most of the needed dependencies). -<<<<<<< HEAD - sudo pip install pyparsing - sudo pip install dronekit -======= + #. Download and run the correct `WinPython installer `_ (**v2.7**) for your platform (win32 vs win64). * Run the installer as an administrator (**Right-click** on file, select **Run as Administrator**). * When prompted for the destination location, specify **C:\\Program Files (x86)** (the default location is under the **Downloads** folder). ->>>>>>> DKPY2 fixes to getting started, running examples, and developer setup windows. Consequent fixups to links elsewhere #. Register the Python that came from *WinPython* as the preferred interpreter for your machine: @@ -97,7 +93,7 @@ Set up a command line DroneKit-Python installation using *WinPython* (this Pytho .. code:: bash - pip install droneapi + pip install dronekit @@ -109,12 +105,12 @@ Connecting to a Vehicle ======================= The connection to the vehicle is set up within the DroneKit script. Scripts import and call the :py:func:`connect()` method. -After connecting this returns a :py:class:`Vehicle ` object from which you can get/set parameters +After connecting this returns a :py:class:`Vehicle ` object from which you can get/set parameters and attributes, and control vehicle movement. .. code:: python - from droneapi import connect + from dronekit import connect # Connect to UDP endpoint. vehicle = connect('127.0.0.1:14550', await_params=True) @@ -122,7 +118,7 @@ and attributes, and control vehicle movement. .. note:: Calling ``connect()`` with ``await_params=True`` (as shown above) ensures that the method will not return until - :py:attr:`Vehicle.parameters ` is fully populated with values from the vehicle. + :py:attr:`Vehicle.parameters ` is fully populated with values from the vehicle. Vehicle *attributes* are populated in parallel but are not guaranteed to have values when ``connect()`` completes (an attribute will have value ``None`` if a corresponding MAVLink message has not been received - for example, if the attribute is not supported by the vehicle). @@ -151,37 +147,20 @@ the more common connection types: .. tip:: -<<<<<<< HEAD - echo "module load dronekit.module.api" >> ~/.mavinit.scr -======= The strings above are the same as you would use if connecting with MAVProxy. For other options see the `MAVProxy documentation `_. ->>>>>>> DKPY2 fixes to getting started, running examples, and developer setup windows. Consequent fixups to links elsewhere You can start this simple script in the same way you would start any other standalone Python script. .. code-block:: bash -<<<<<<< HEAD - echo module load dronekit.module.api >> %HOMEPATH%\AppData\Local\MAVProxy\mavinit.scr -======= python your_dronekit_script.py ->>>>>>> DKPY2 fixes to getting started, running examples, and developer setup windows. Consequent fixups to links elsewhere -<<<<<<< HEAD -.. code-block:: bash - :emphasize-lines: 1 - - MANUAL> module load dronekit.module.api - DroneAPI loaded - MANUAL> -======= .. todo:: Connect method here needs to link to the function, but it isn't exported yet. Fix that once the API tidied. - ->>>>>>> DKPY2 fixes to getting started, running examples, and developer setup windows. Consequent fixups to links elsewhere + @@ -190,85 +169,7 @@ You can start this simple script in the same way you would start any other stand Running an app/example ====================== -<<<<<<< HEAD -This section shows how to run the :ref:`Vehicle State ` example, -which reads and writes :ref:`vehicle state and parameter ` information. - -.. warning:: - - This example doesn't take off, but it does arm the motors. Don't run any example indoors on a real vehicle - unless you have first removed its propellers. - -The steps are: - -#. Get the DroneKit-Python example source code onto your local machine. - - The easiest way to do this is to clone the **dronekit-python** repository from Github. - On the command prompt enter: - - .. code-block:: bash - - git clone http://github.com/dronekit/dronekit-python.git - - .. tip:: - - The :ref:`Windows Installation ` copies the example code here: - :file:`C:\\Program Files (x86)\\MAVProxy\\examples\\`. - -#. Start MAVProxy and :ref:`connect to the vehicle `. For example: - - * To connect to a simulated vehicle when starting *MAVProxy* (from the command line): - - .. code-block:: bash - - mavproxy.py --master=127.0.0.1:14550 - - * To connect to a simulated vehicle after starting *MAVProxy* (for example, on Windows): - - .. code-block:: bash - - link add 127.0.0.1:14550 - -#. You should already have set up *MAVProxy* to :ref:`load DroneKit automatically `. - If not, manually load the library using: - - .. code-block:: bash - - module load dronekit.module.api - -#. Once the *MAVProxy* console is running, start ``vehicle_state.py`` by entering ``api start`` followed by the - full file path of the script. For example: - - .. code-block:: bash - - api start "C:\Program Files (x86)\MAVProxy\examples\vehicle_state\vehicle_state.py" - - - The output should look something like that shown below - - .. code-block:: bash - :emphasize-lines: 1 - - MANUAL> api start "C:\Program Files (x86)\MAVProxy\examples\vehicle_state\vehicle_state.py" - STABILIZE> - - Get all vehicle attribute values: - Location: Attitude: Attitude:pitch=-0.00405988190323,yaw=-0.0973932668567,roll=-0.00393210304901 - Velocity: [0.06, -0.07, 0.0] - GPS: GPSInfo:fix=3,num_sat=10 - groundspeed: 0.0 - airspeed: 0.0 - mount_status: [None, None, None] - Mode: STABILIZE - Armed: False - Set Vehicle.mode=GUIDED (currently: STABILIZE) - Waiting for mode change ... - Got MAVLink msg: COMMAND_ACK {command : 11, result : 0} - ... - -======= This SDK has :ref:`numerous examples `. We recommend you start with :ref:`example-vehicle-state`, which reads and writes :ref:`vehicle state and parameter ` information. ->>>>>>> DKPY2 fixes to getting started, running examples, and developer setup windows. Consequent fixups to links elsewhere For general information on running the examples (and other apps) see :ref:`running_examples_top`. From 3b6ad13994d4f0f48f3e90bccff57b711c2e9281 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 8 Oct 2015 16:40:07 -0400 Subject: [PATCH 005/475] Supports reading and sending waypoints. --- dronekit/__init__.py | 57 ++++++++++++++++++++++++- dronekit/module/api.py | 6 +-- examples/vehicle_state/vehicle_state.py | 17 -------- 3 files changed, 58 insertions(+), 22 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index b55ea395c..d650e9eb3 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -5,7 +5,7 @@ import os import platform import re -from pymavlink import mavutil +from pymavlink import mavutil, mavwp from Queue import Empty from pkgutil import extend_path @@ -128,6 +128,26 @@ def __init__(self, master, status_printer=None): self.status_printer = status_printer + # waypoints + self.wploader = mavwp.MAVWPLoader() + self.wp_loaded = True + + def fetch(self): + """ + Fetch waypoints. + """ + self.wp_loaded = False + print('FETCHING WAYPOINTs') + self.master.waypoint_request_list_send() + + def send_all_waypoints(self): + """ + Send waypoints to master. + """ + self.master.waypoint_clear_all_send() + if self.wploader.count() > 0: + self.master.waypoint_count_send(self.wploader.count()) + def fix_targets(self, message): pass # """Set correct target IDs for our vehicle""" @@ -278,6 +298,7 @@ def mavlink_thread(): # Downtime time.sleep(0.05) + # Parameter watchdog. # Check the time duration for last "new" params exceeds watchdog. if params.start: if None not in params.mav_param_set: @@ -294,6 +315,8 @@ def mavlink_thread(): duration = repeat_duration last_new_param = time.time() + # TODO: Waypoint watching / re-requesting + # Send 1 heartbeat per second if time.time() - last_heartbeat_sent > 1: send_heartbeat(self.master) @@ -351,6 +374,7 @@ def mavlink_thread(): if not msg: break + # Parmater: receive values if msg.get_type() == 'PARAM_VALUE': # If we discover a new param count, assume we # are receiving a new param set. @@ -374,7 +398,36 @@ def mavlink_thread(): import traceback traceback.print_exc() - elif msg.get_type() == 'HEARTBEAT': + # Waypoint receive + if not self.wp_loaded: + if msg.get_type() in ['WAYPOINT_COUNT','MISSION_COUNT']: + self.wploader.clear() + self.wploader.expected_count = msg.count + self.master.waypoint_request_send(0) + if msg.get_type() in ['WAYPOINT', 'MISSION_ITEM']: + if msg.seq > self.wploader.count(): + # Unexpected waypoint + pass + elif msg.seq < self.wploader.count(): + # Waypoint duplicate + pass + else: + self.wploader.add(msg) + + if msg.seq + 1 < self.wploader.expected_count: + self.master.waypoint_request_send(msg.seq + 1) + else: + self.wp_loaded = True + if msg.get_type() in ["WAYPOINT_CURRENT", "MISSION_CURRENT"]: + self.last_waypoint = msg.seq + + # Waypoint send to master + # TODO + if msg.get_type() in ["WAYPOINT_REQUEST", "MISSION_REQUEST"]: + pass + + # Heartbeat: armed + mode update + if msg.get_type() == 'HEARTBEAT': self.status.armed = (msg.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED) != 0 self.status.flightmode = {v: k for k, v in self.master.mode_mapping().items()}[msg.custom_mode] last_heartbeat_received = time.time() diff --git a/dronekit/module/api.py b/dronekit/module/api.py index 17962aca5..0f91dd18a 100644 --- a/dronekit/module/api.py +++ b/dronekit/module/api.py @@ -60,8 +60,8 @@ def download(self): def wait_valid(self): '''Block the calling thread until waypoints have been downloaded''' # FIXME this is a super crufty spin-wait, also we should give the user the option of specifying a timeout - while (self.__wp.wp_op is not None) and not self.__module.api.exit: - time.sleep(0.200) + while not self.__module.wp_loaded: + time.sleep(0.1) def takeoff(self, alt=None): if alt is not None: @@ -138,7 +138,7 @@ def __init__(self, module): def flush(self): if self.wpts_dirty: - self.__module.module('wp').send_all_waypoints() + self.__module.send_all_waypoints() self.wpts_dirty = False # diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 7f8a9cb41..128f422b8 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -103,23 +103,6 @@ def mavrx_debug_handler(message): print "Remove the MAVLink callback handler (stop getting messages)" vehicle.unset_mavlink_callback() - - -# Overriding an RC channel -# NOTE: CHANNEL OVERRIDES may be useful for simulating user input and when implementing certain types of joystick control. -#DO NOT use unless there is no other choice (there almost always is!) -print "\nOverriding RC channels for roll and yaw" -vehicle.channel_override = { "1" : 900, "4" : 1000 } -vehicle.flush() -print " Current overrides are:", vehicle.channel_override -print " Channel default values:", vehicle.channel_readback # All channel values before override - -# Cancel override by setting channels to 0 -print " Cancelling override" -vehicle.channel_override = { "1" : 0, "4" : 0 } -vehicle.flush() - - ## Reset variables to sensible values. print "\nReset vehicle attributes/parameters and exit" vehicle.mode = VehicleMode("STABILIZE") From 981480d3d52c79cde205650298d4bd59067071d4 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 8 Oct 2015 16:40:30 -0400 Subject: [PATCH 006/475] Removes some read-only, deprecated properties. --- dronekit/module/api.py | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/dronekit/module/api.py b/dronekit/module/api.py index 0f91dd18a..7e901a7ca 100644 --- a/dronekit/module/api.py +++ b/dronekit/module/api.py @@ -35,14 +35,10 @@ def __setitem__(self, name, value): def wait_valid(self): '''Block the calling thread until parameters have been downloaded''' # FIXME this is a super crufty spin-wait, also we should give the user the option of specifying a timeout - pstate = self.__param.pstate + pstate = self.__module.pstate while (pstate.mav_param_count == 0 or len(pstate.mav_param_set) != pstate.mav_param_count) and not self.__module.api.exit: time.sleep(0.200) - @property - def __param(self): - return self.__module.module('param') - class MPCommandSequence(CommandSequence): """ See CommandSequence baseclass for documentation. @@ -54,7 +50,7 @@ def __init__(self, module): def download(self): '''Download all waypoints from the vehicle''' self.wait_valid() - self.__wp.fetch() + self.__module.fetch() # BIG FIXME - wait for full wpt download before allowing any of the accessors to work def wait_valid(self): @@ -90,23 +86,19 @@ def goto(self, l): def clear(self): '''Clears the command list''' self.wait_valid() - self.__wp.wploader.clear() + self.__module.wploader.clear() self.__module.vehicle.wpts_dirty = True def add(self, cmd): '''Add a new command at the end of the command list''' self.wait_valid() self.__module.fix_targets(cmd) - self.__wp.wploader.add(cmd, comment = 'Added by DroneAPI') + self.__module.wploader.add(cmd, comment = 'Added by DroneAPI') self.__module.vehicle.wpts_dirty = True - @property - def __wp(self): - return self.__module.module('wp') - @property def count(self): - return self.__wp.wploader.count() + return self.__module.wploader.count() @property def next(self): @@ -122,10 +114,10 @@ def next(self, index): self.__module.master.waypoint_set_current_send(index) def __getitem__(self, index): - return self.__wp.wploader.wp(index) + return self.__module.wploader.wp(index) def __setitem__(self, index, value): - self.__wp.wploader.set(value, index) + self.__module.wploader.set(value, index) self.__module.vehicle.wpts_dirty = True class MPVehicle(Vehicle): @@ -236,10 +228,6 @@ def channel_override(self, newch): def channel_readback(self): return self.__module.rc_readback - @property - def __rc(self): - return self.__module.module('rc') - @property def commands(self): """ From d3a36fa6fcb96a8a1c97165c41877f2d3d706b15 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 8 Oct 2015 16:50:44 -0400 Subject: [PATCH 007/475] Removes stray print. --- dronekit/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index d650e9eb3..8f760c08b 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -137,7 +137,6 @@ def fetch(self): Fetch waypoints. """ self.wp_loaded = False - print('FETCHING WAYPOINTs') self.master.waypoint_request_list_send() def send_all_waypoints(self): From b990e13e79ac8834c8e03eb77957a046292ff753 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 8 Oct 2015 17:22:48 -0400 Subject: [PATCH 008/475] Removes synthetic clock. --- dronekit/tools/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/tools/__init__.py b/dronekit/tools/__init__.py index 14f3f48ab..cad05cc3e 100644 --- a/dronekit/tools/__init__.py +++ b/dronekit/tools/__init__.py @@ -3,7 +3,7 @@ from dronekit.sitl import SITL sitl = SITL('copter', '3.3-rc5') -sitl_args = ['-I0', '-S', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] +sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] if 'SITL_SPEEDUP' in os.environ: sitl_args += ['--speedup', str(os.environ['SITL_SPEEDUP'])] From a4ed667a60dc693062d022bcfbc43b993114316e Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 9 Oct 2015 09:05:20 -0400 Subject: [PATCH 009/475] Adds ekf_of flag. --- dronekit/__init__.py | 9 +++++++++ dronekit/module/api.py | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 8f760c08b..107c4172c 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -7,6 +7,7 @@ import re from pymavlink import mavutil, mavwp from Queue import Empty +from pymavlink.dialects.v10 import ardupilotmega from pkgutil import extend_path __path__ = extend_path(__path__, __name__) @@ -110,6 +111,7 @@ def __init__(self, master, status_printer=None): self.epv = None self.satellites_visible = None self.fix_type = None # FIXME support multiple GPSs per vehicle - possibly by using componentId + self.ekf_ok = False self.rngfnd_distance = None self.rngfnd_voltage = None @@ -251,6 +253,13 @@ def set(chnum, v): self.rngfnd_distance = m.distance self.rngfnd_voltage = m.voltage self.__on_change('rangefinder') + elif typ == "EKF_STATUS_REPORT": + # use same check that ArduCopter::system.pde::position_ok() is using + if self.vehicle.armed: + self.ekf_ok = ((m.flags&ardupilotmega.EKF_POS_HORIZ_ABS) > 0) and (m.flags&ardupilotmega.EKF_CONST_POS_MODE == 0) + else: + self.ekf_ok = ((m.flags&ardupilotmega.EKF_POS_HORIZ_ABS) > 0) or ((m.flags&ardupilotmega.EKF_PRED_POS_HORIZ_ABS) > 0) + self.__on_change('ekf_ok') if self.api: for v in self.api.get_vehicles(): diff --git a/dronekit/module/api.py b/dronekit/module/api.py index 7e901a7ca..976dfd3c2 100644 --- a/dronekit/module/api.py +++ b/dronekit/module/api.py @@ -211,6 +211,10 @@ def airspeed(self): def mount_status(self): return [ self.__module.mount_pitch, self.__module.mount_yaw, self.__module.mount_roll ] + @property + def ekf_ok(self): + return self.__module.ekf_ok + @property def channel_override(self): overrides = self.__rc.override From 618712f8716697d96e803f0a4471b3a6afbb4582 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 9 Oct 2015 09:17:20 -0400 Subject: [PATCH 010/475] Fixes raise error hiding stack trace. --- dronekit/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 107c4172c..9fcbc8bb4 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -448,7 +448,7 @@ def mavlink_thread(): if self.exiting: pass else: - raise e + raise t = Thread(target=mavlink_thread) From 460ffa46ea61fd39a46e31520ec011e5d7d3906f Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 9 Oct 2015 09:21:11 -0400 Subject: [PATCH 011/475] Corrects ekf_ok armed check. --- dronekit/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 9fcbc8bb4..c6654f183 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -255,7 +255,7 @@ def set(chnum, v): self.__on_change('rangefinder') elif typ == "EKF_STATUS_REPORT": # use same check that ArduCopter::system.pde::position_ok() is using - if self.vehicle.armed: + if self.status.armed: self.ekf_ok = ((m.flags&ardupilotmega.EKF_POS_HORIZ_ABS) > 0) and (m.flags&ardupilotmega.EKF_CONST_POS_MODE == 0) else: self.ekf_ok = ((m.flags&ardupilotmega.EKF_POS_HORIZ_ABS) > 0) or ((m.flags&ardupilotmega.EKF_PRED_POS_HORIZ_ABS) > 0) From b4767faee79f6894c851557b2b2bbdf3aeda3fff Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 13 Oct 2015 11:14:45 -0400 Subject: [PATCH 012/475] Adds loading block for dronekit.sitl. --- dronekit/__init__.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index c6654f183..664609751 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -9,9 +9,6 @@ from Queue import Empty from pymavlink.dialects.v10 import ardupilotmega -from pkgutil import extend_path -__path__ = extend_path(__path__, __name__) - if platform.system() == 'Windows': from errno import WSAECONNRESET as ECONNABORTED else: @@ -489,3 +486,9 @@ def connect(ip, await_params=False, status_printer=errprinter): state.status_printer = status_printer # api.init(state) return state.prepare(await_params=await_params).get_vehicles()[0] + +# import dronekit.sitl +try: + import dronekit_sitl as sitl +except: + pass From 9a91bf8d6633731facbacc2955c9442ea14a7129 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 13 Oct 2015 11:20:10 -0400 Subject: [PATCH 013/475] Cleans up EKF code. --- dronekit/__init__.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 664609751..8a72c4ff1 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -251,11 +251,21 @@ def set(chnum, v): self.rngfnd_voltage = m.voltage self.__on_change('rangefinder') elif typ == "EKF_STATUS_REPORT": + # legacy check for dronekit-python for solo # use same check that ArduCopter::system.pde::position_ok() is using + + # boolean: EKF's horizontal position (absolute) estimate is good + status_poshorizabs = (m.flags & ardupilotmega.EKF_POS_HORIZ_ABS) > 0 + # boolean: EKF is in constant position mode and does not know it's absolute or relative position + status_constposmode = m.flags & ardupilotmega.EKF_CONST_POS_MODE > 0 + # boolean: EKF's predicted horizontal position (absolute) estimate is good + status_predposhorizabs = (m.flags & ardupilotmega.EKF_PRED_POS_HORIZ_ABS) > 0 + if self.status.armed: - self.ekf_ok = ((m.flags&ardupilotmega.EKF_POS_HORIZ_ABS) > 0) and (m.flags&ardupilotmega.EKF_CONST_POS_MODE == 0) + self.ekf_ok = status_poshorizabs and not status_constposmode else: - self.ekf_ok = ((m.flags&ardupilotmega.EKF_POS_HORIZ_ABS) > 0) or ((m.flags&ardupilotmega.EKF_PRED_POS_HORIZ_ABS) > 0) + self.ekf_ok = status_poshorizabs or status_predposhorizabs + self.__on_change('ekf_ok') if self.api: From 1f4ec81ee4821a657376b4737a3105f6df559d0b Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 13 Oct 2015 11:20:18 -0400 Subject: [PATCH 014/475] Bumps beta version. --- dronekit/__init__.py | 6 ------ dronekit/tools/__init__.py | 2 +- requirements.txt | 2 +- setup.py | 2 +- 4 files changed, 3 insertions(+), 9 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 8a72c4ff1..e0763a2c9 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -496,9 +496,3 @@ def connect(ip, await_params=False, status_printer=errprinter): state.status_printer = status_printer # api.init(state) return state.prepare(await_params=await_params).get_vehicles()[0] - -# import dronekit.sitl -try: - import dronekit_sitl as sitl -except: - pass diff --git a/dronekit/tools/__init__.py b/dronekit/tools/__init__.py index cad05cc3e..b8088dc00 100644 --- a/dronekit/tools/__init__.py +++ b/dronekit/tools/__init__.py @@ -1,6 +1,6 @@ import os from nose.tools import assert_equals, with_setup -from dronekit.sitl import SITL +from dronekit_sitl import SITL sitl = SITL('copter', '3.3-rc5') sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] diff --git a/requirements.txt b/requirements.txt index a8eaab4f4..b59df0378 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,4 @@ nose>=1.3.7 psutil>=3.0.0 mock>=1.3.0 six>=1.9.0 -dronekit-sitl>=2.2.0 +dronekit-sitl>=2.3.0 diff --git a/setup.py b/setup.py index 7e7742895..a6add7a28 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.0.0b2' +version = '2.0.0b3' setup (name = 'dronekit', zip_safe=True, From 7d3410534a66a700f1fe3f931a9cee7b854f7423 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 13 Oct 2015 11:45:36 +1100 Subject: [PATCH 015/475] Update/add mavlink message example for DKPY2.x -untested --- docs/examples/create_attribute.rst | 212 ++++++++++++++++++ docs/examples/index.rst | 1 + docs/guide/index.rst | 1 + docs/guide/mavlink_messages.rst | 86 +++++++ examples/create_attribute/create_attribute.py | 126 +++++++++++ 5 files changed, 426 insertions(+) create mode 100644 docs/examples/create_attribute.rst create mode 100644 docs/guide/mavlink_messages.rst create mode 100644 examples/create_attribute/create_attribute.py diff --git a/docs/examples/create_attribute.rst b/docs/examples/create_attribute.rst new file mode 100644 index 000000000..283b20593 --- /dev/null +++ b/docs/examples/create_attribute.rst @@ -0,0 +1,212 @@ +.. _example_create_attribute: + +================================ +Example: Create Attribute in App +================================ + +This example shows how you can create attributes for MAVLink messages within your DroneKit-Python script and +use them in *in the same way* as the built-in :py:class:`Vehicle ` attributes. + +Additional information is provided in the guide topic :ref:`mavlink_messages`. + +.. tip:: + + This approach is useful when you urgently need to access messages that are not yet supported as + :py:class:`Vehicle ` attributes. + + Please :ref:`contribute your code to the API ` so that it is available to + (and can be tested by) the whole DroneKit-Python community. + + + +Running the example +=================== + +The vehicle and DroneKit should be set up as described in :ref:`get-started`. It can be run as described in +:doc:`running_examples`. + +In summary, after cloning the repository: + +#. Navigate to the example folder as shown: + + .. code-block:: bash + + cd dronekit-python\examples\create_attribute\ + + +#. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: + + .. code-block:: bash + + python create_attribute.py --connect 127.0.0.1:14550 + + .. note:: + + The examples uses the ``--connect`` parameter to pass the :ref:`connection string ` into the script. + The command above would be used to connect to :ref:`SITL ` running on the local machine via UDP port 14550. + + + +On the command prompt you should see (something like): + +.. code:: bash + + RAW_IMU: time_boot_us=41270000,xacc=0,yacc=0,zacc=-999,xgyro=1,ygyro=1,zgyro=1,xmag=153,ymag=52,zmag=-364 + RAW_IMU: time_boot_us=41510000,xacc=0,yacc=0,zacc=-1000,xgyro=1,ygyro=0,zgyro=1,xmag=153,ymag=52,zmag=-364 + RAW_IMU: time_boot_us=41750000,xacc=1,yacc=0,zacc=-1000,xgyro=1,ygyro=1,zgyro=0,xmag=153,ymag=52,zmag=-364 + RAW_IMU: time_boot_us=41990000,xacc=0,yacc=0,zacc=-999,xgyro=0,ygyro=0,zgyro=0,xmag=153,ymag=52,zmag=-364 + RAW_IMU: time_boot_us=42230000,xacc=0,yacc=0,zacc=-1000,xgyro=0,ygyro=0,zgyro=0,xmag=153,ymag=52,zmag=-364 + RAW_IMU: time_boot_us=42470000,xacc=0,yacc=0,zacc=-999,xgyro=1,ygyro=0,zgyro=0,xmag=153,ymag=52,zmag=-364 + RAW_IMU: time_boot_us=42710000,xacc=0,yacc=0,zacc=-999,xgyro=0,ygyro=0,zgyro=0,xmag=153,ymag=52,zmag=-364 + RAW_IMU: time_boot_us=42950000,xacc=0,yacc=0,zacc=-1000,xgyro=1,ygyro=1,zgyro=0,xmag=153,ymag=52,zmag=-364 + RAW_IMU: time_boot_us=43190000,xacc=0,yacc=0,zacc=-999,xgyro=1,ygyro=1,zgyro=1,xmag=153,ymag=52,zmag=-364 + RAW_IMU: time_boot_us=43430000,xacc=0,yacc=0,zacc=-999,xgyro=0,ygyro=0,zgyro=0,xmag=153,ymag=52,zmag=-364 + RAW_IMU: time_boot_us=43670000,xacc=0,yacc=0,zacc=-999,xgyro=1,ygyro=0,zgyro=1,xmag=153,ymag=52,zmag=-364 + RAW_IMU: time_boot_us=43910000,xacc=0,yacc=0,zacc=-999,xgyro=1,ygyro=0,zgyro=1,xmag=153,ymag=52,zmag=-364 + RAW_IMU: time_boot_us=44150000,xacc=0,yacc=0,zacc=-999,xgyro=1,ygyro=1,zgyro=0,xmag=153,ymag=52,zmag=-364 + RAW_IMU: time_boot_us=44390000,xacc=0,yacc=0,zacc=-999,xgyro=1,ygyro=1,zgyro=0,xmag=153,ymag=52,zmag=-364 + APIThread-0 exiting... + + + +How does it work? +================= + +The example first defines a class for the attribute. This has members for each of the values in the message +(in this case `RAW_IMU `_). It provides an initialiser and a string +representation for printing the object. + +.. code:: python + + class RawIMU(object): + """ + The RAW IMU readings for the usual 9DOF sensor setup. + This contains the true raw values without any scaling to allow data capture and system debugging. + + The message definition is here: http://mavlink.org/messages/common#RAW_IMU + + :param time_boot_us: Timestamp (microseconds since system boot). #Note, not milliseconds as per spec + :param xacc: X acceleration (mg) + :param yacc: Y acceleration (mg) + :param zacc: Z acceleration (mg) + :param xgyro: Angular speed around X axis (millirad /sec) + :param ygyro: Angular speed around Y axis (millirad /sec) + :param zgyro: Angular speed around Z axis (millirad /sec) + :param xmag: X Magnetic field (milli tesla) + :param ymag: Y Magnetic field (milli tesla) + :param zmag: Z Magnetic field (milli tesla) + """ + + def __init__(self, time_boot_us, xacc, yacc, zacc, xygro, ygyro, zgyro, xmag, ymag, zmag): + """ + RawIMU object constructor. + """ + self.time_boot_us = time_boot_us + self.xacc = xacc + self.yacc = yacc + self.zacc = zacc + self.xgyro = zgyro + self.ygyro = ygyro + self.zgyro = zgyro + self.xmag = xmag + self.ymag = ymag + self.zmag = zmag + + def __str__(self): + """ + String representation of the RawIMU object + """ + return "RAW_IMU: time_boot_us={},xacc={},yacc={},zacc={},xgyro={},ygyro={},zgyro={},xmag={},ymag={},zmag={}".format(self.time_boot_us, self.xacc, self.yacc,self.zacc,self.xgyro,self.ygyro,self.zgyro,self.xmag,self.ymag,self.zmag) + +The script should then create an instance of the class and add it as an attribute to the vehicle object retrieved from the local connection. +All values in the new attribute should be set to ``None`` so that it is obvious to users when no messages have been received. + +.. code:: python + + # Get an instance of the API endpoint + api = local_connect() + # Get the connected vehicle (currently only one vehicle can be returned). + vehicle = api.get_vehicles()[0] + + #Create an Vehicle.raw_imu object and set all values to None. + vehicle.raw_imu=RawIMU(None,None,None,None,None,None,None,None,None,None) + +We can set a callback to intercept MAVLink messages using :py:func:`Vehicle.set_mavlink_callback() ` +as shown below. + +.. code:: python + + def mavrx_debug_handler(message): + """ + Handler for MAVLink messages. + """ + #Handle raw_imu messages + mav_raw_imu_handler(message) + + # Set MAVLink callback handler (after getting Vehicle instance) + vehicle.set_mavlink_callback(mavrx_debug_handler) + +For clarity we have separated the handling code for the RAW_IMU message into ``mav_raw_imu_handler()``. The handler simply checks the message type and +(for the correct messages) writes the values into the attribute. It then calls ``vehicle.notify_observers('raw_imu')`` to notify all observers of this attribute type. + +.. code:: python + + def mav_raw_imu_handler(message): + """ + Writes received message to the (newly attached) vehicle.raw_imu object and notifies observers. + """ + messagetype=str(message).split('{')[0].strip() + if messagetype=='RAW_IMU': + vehicle.raw_imu.time_boot_us=message.time_usec + vehicle.raw_imu.xacc=message.xacc + vehicle.raw_imu.yacc=message.yacc + vehicle.raw_imu.zacc=message.zacc + vehicle.raw_imu.xgyro=message.xgyro + vehicle.raw_imu.ygyro=message.ygyro + vehicle.raw_imu.zgyro=message.zgyro + vehicle.raw_imu.xmag=message.xmag + vehicle.raw_imu.ymag=message.ymag + vehicle.raw_imu.zmag=message.zmag + + #Add Notify all observers of new message. + vehicle.notify_observers('raw_imu') + + +At this point the ``Vehicle.raw_imu`` attribute can be treated the same as any other attribute for the duration of the session. +You can query the attribute to get any of the values, and even add an observer as shown: + + +.. code:: python + + #Callback to print the raw_imu + def raw_imu_callback(rawimu): + print vehicle.raw_imu + + + #Add observer for the vehicle's current location + vehicle.add_attribute_observer('raw_imu', raw_imu_callback) + + +.. note:: + + It is not possible to reliably use this approach to create independent modules because: + + * Only one MAVLink callback can be set at a time in the running program (``set_mavlink_callback()``) + * There is no reliable way to import modules without adding them properly to the Python environment. + + + +Known issues +============ + +This code has no known issues. + + +Source code +=========== + +The full source code at documentation build-time is listed below (`current version on github `_): + +.. literalinclude:: ../../examples/create_attribute/create_attribute.py + :language: python + diff --git a/docs/examples/index.rst b/docs/examples/index.rst index 65b983659..55504b717 100644 --- a/docs/examples/index.rst +++ b/docs/examples/index.rst @@ -18,6 +18,7 @@ during missions and outside missions using custom commands. Guided Movement and Commands Basic Mission Mission Import/Export + Create Attribute in App Follow Me (Linux only) Drone Delivery Flight Replay diff --git a/docs/guide/index.rst b/docs/guide/index.rst index 612d296a7..d63671773 100644 --- a/docs/guide/index.rst +++ b/docs/guide/index.rst @@ -17,3 +17,4 @@ The guide contains how-to documentation for using the DroneKit-Python API. These copter/guided_mode Missions debugging + mavlink_messages \ No newline at end of file diff --git a/docs/guide/mavlink_messages.rst b/docs/guide/mavlink_messages.rst new file mode 100644 index 000000000..ea614d154 --- /dev/null +++ b/docs/guide/mavlink_messages.rst @@ -0,0 +1,86 @@ +.. _mavlink_messages: + +================ +MAVLink Messages +================ + +Some useful MAVLink messages sent by the autopilot are not (yet) directly available to DroneKit-Python scripts +through the :ref:`observable attributes ` in :py:class:`Vehicle `. + +This topic shows how you can intercept MAVLink messages using +:py:func:`Vehicle.set_mavlink_callback() `. + +.. tip:: + + :ref:`example_create_attribute` shows how you can extend this approach to create a new :py:class:`Vehicle ` + attribute in your client code. + + + +.. _mavlink_messages_set_mavlink_callback: + +Creating the message observer +============================= + +The :py:func:`Vehicle.set_mavlink_callback() ` method provides asynchronous +notification when any *MAVLink* packet is received from the connected vehicle. + +The code snippet below shows how to set a “demo” callback function as the callback handler: + +.. code:: python + + # Demo callback handler for raw MAVLink messages + def mavrx_debug_handler(message): + print type(message) + print message + + + # Set MAVLink callback handler (after getting Vehicle instance) + vehicle.set_mavlink_callback(mavrx_debug_handler) + +.. note:: + + DroneKit-Python only supports a single MAVLink message observer at a time. This can be removed or replaced + with a different observer. + +The messages are `classes `_ from the `pymavlink `_ library. +The output of the code above looks something like: + +.. code:: bash + + + RANGEFINDER {distance : 0.0899999961257, voltage : 0.00900000054389} + + TERRAIN_REPORT {lat : -353632610, lon : 1491652299, spacing : 100, terrain_height : 583.88470459, current_height : 0.0, pending : 0, loaded : 504} + + EKF_STATUS_REPORT {flags : 933, velocity_variance : 0.0, pos_horiz_variance : 0.0, pos_vert_variance : 0.000532002304681, compass_variance : 0.00632426189259, terrain_alt_variance : 0.0} + + VIBRATION {time_usec : 88430000, vibration_x : 0.0, vibration_y : 0.0, vibration_z : 0.0, clipping_0 : 0, clipping_1 : 0, clipping_2 : 0} + ... + +You can access the message fields directly. For example, to access the ``RANGEFINDER`` message your handler might look like this: + +.. code:: python + + # Handler for message: RANGEFINDER {distance : 0.0899999961257, voltage : 0.00900000054389} + def mavrx_debug_handler(message): + messagetype=str(message).split('{')[0].strip() + if messagetype=='RANGEFINDER': + print 'distance: %s' % message.distance + print 'voltage: %s' % message.voltage + + + + + + +Clearing the observer +===================== + +The observer is unset by calling :py:func:`Vehicle.unset_mavlink_callback `. + +The observer will also be removed when the thread exits. + + + + \ No newline at end of file diff --git a/examples/create_attribute/create_attribute.py b/examples/create_attribute/create_attribute.py new file mode 100644 index 000000000..360396ced --- /dev/null +++ b/examples/create_attribute/create_attribute.py @@ -0,0 +1,126 @@ +""" +create_attribute.py: + +Demonstrates how to create attributes for MAVLink messages within your DroneKit-Python script +and use them in the same way as the built-in Vehicle attributes. + +The code adds a new attribute to the Vehicle class, populating it with information from RAW_IMU messages +intercepted using set_mavlink_callback. + +Full documentation is provided at http://python.dronekit.io/examples/create_attribute.html +""" + +from dronekit import connect +from dronekit.lib import VehicleMode +from pymavlink import mavutil +import time + + +#Set up option parsing to get connection string +import argparse +parser = argparse.ArgumentParser(description='Print out vehicle state information. Connects to SITL on local PC by default.') +parser.add_argument('--connect', default='127.0.0.1:14550', + help="vehicle connection target. Default '127.0.0.1:14550'") +args = parser.parse_args() + + +# Connect to the Vehicle +print 'Connecting to vehicle on: %s' % args.connect +vehicle = connect(args.connect, await_params=True) + + + +class RawIMU(object): + """ + The RAW IMU readings for the usual 9DOF sensor setup. + This contains the true raw values without any scaling to allow data capture and system debugging. + + The message definition is here: https://pixhawk.ethz.ch/mavlink/#RAW_IMU + + :param time_boot_us: Timestamp (microseconds since system boot). #Note, not milliseconds as per spec + :param xacc: X acceleration (mg) + :param yacc: Y acceleration (mg) + :param zacc: Z acceleration (mg) + :param xgyro: Angular speed around X axis (millirad /sec) + :param ygyro: Angular speed around Y axis (millirad /sec) + :param zgyro: Angular speed around Z axis (millirad /sec) + :param xmag: X Magnetic field (milli tesla) + :param ymag: Y Magnetic field (milli tesla) + :param zmag: Z Magnetic field (milli tesla) + """ + def __init__(self, time_boot_us, xacc, yacc, zacc, xygro, ygyro, zgyro, xmag, ymag, zmag): + """ + RawIMU object constructor. + """ + self.time_boot_us = time_boot_us + self.xacc = xacc + self.yacc = yacc + self.zacc = zacc + self.xgyro = zgyro + self.ygyro = ygyro + self.zgyro = zgyro + self.xmag = xmag + self.ymag = ymag + self.zmag = zmag + + def __str__(self): + """ + String representation used to print the RawIMU object. + """ + return "RAW_IMU: time_boot_us={},xacc={},yacc={},zacc={},xgyro={},ygyro={},zgyro={},xmag={},ymag={},zmag={}".format(self.time_boot_us, self.xacc, self.yacc,self.zacc,self.xgyro,self.ygyro,self.zgyro,self.xmag,self.ymag,self.zmag) + + + +#Create an Vehicle.raw_imu object and set all values to None. +vehicle.raw_imu=RawIMU(None,None,None,None,None,None,None,None,None,None) + + +def mav_raw_imu_handler(message): + """ + Writes received message to the (newly attached) vehicle.raw_imu object and notifies observers. + """ + messagetype=str(message).split('{')[0].strip() + if messagetype=='RAW_IMU': + vehicle.raw_imu.time_boot_us=message.time_usec + vehicle.raw_imu.xacc=message.xacc + vehicle.raw_imu.yacc=message.yacc + vehicle.raw_imu.zacc=message.zacc + vehicle.raw_imu.xgyro=message.xgyro + vehicle.raw_imu.ygyro=message.ygyro + vehicle.raw_imu.zgyro=message.zgyro + vehicle.raw_imu.xmag=message.xmag + vehicle.raw_imu.ymag=message.ymag + vehicle.raw_imu.zmag=message.zmag + + #Add Notify all observers of new message. + vehicle.notify_observers('raw_imu') + + +def mavrx_debug_handler(message): + """ + Handler for MAVLink messages. + """ + #Handle raw_imu messages + mav_raw_imu_handler(message) + +# Set MAVLink callback handler (after getting Vehicle instance) +vehicle.set_mavlink_callback(mavrx_debug_handler) + +""" +From this point vehicle.raw_imu can be used just like any other attribute. +""" + +#Callback to print the raw_imu +def raw_imu_callback(rawimu): + print vehicle.raw_imu + + +#Add observer for the vehicle's current location +vehicle.add_attribute_observer('raw_imu', raw_imu_callback) + +print 'Display RAW_IMU messages for 5 seconds and then exit.' +time.sleep(5) + +#The observer can be unset using ``vehicle.unset_mavlink_callback()`` OR +# ``vehicle.set_mavlink_callback(None)``. +#It is automatically removed when the thread exits. From 8d41915a7e6643a68e4d700d3bb225196c017ae9 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 13 Oct 2015 16:52:31 -0400 Subject: [PATCH 016/475] Abstracts MAVLink listeners in the constructor. --- dronekit/__init__.py | 275 +++++++++++++++++++++++++++---------------- 1 file changed, 172 insertions(+), 103 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index e0763a2c9..ed38456b1 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -8,6 +8,7 @@ from pymavlink import mavutil, mavwp from Queue import Empty from pymavlink.dialects.v10 import ardupilotmega +import types if platform.system() == 'Windows': from errno import WSAECONNRESET as ECONNABORTED @@ -74,16 +75,89 @@ def __init__(self, master, status_printer=None): self.target_system = 0 self.target_component = 0 + self.status = type('MPStatus',(object,),{ + 'flightmode': 'AUTO', + 'armed': False, + })() + + self.mav_param = {} + + # Weird + self.mpstate = self + self.functions = self + self.mpstate.settings = self + + # waypoints + self.wploader = mavwp.MAVWPLoader() + self.wp_loaded = True + + # Attaches message listeners. + self.message_listeners = dict() + + def message_default(name): + """ + Decorator for default message handlers. + """ + def decorator(fn): + if isinstance(name, list): + for n in name: + self.on_message(n, fn) + else: + self.on_message(name, fn) + return decorator + + self.status_printer = status_printer + + @message_default('STATUSTEXT') + def listener(self, name, m): + self.status_printer(re.sub(r'(^|\n)', '>>> \1', m.text.rstrip())) + self.lat = None self.lon = None self.alt = None - self.vx = None self.vy = None self.vz = None + + @message_default('GLOBAL_POSITION_INT') + def listener(self, name, m): + (self.lat, self.lon) = (m.lat / 1.0e7, m.lon / 1.0e7) + (self.vx, self.vy, self.vz) = (m.vx / 100.0, m.vy / 100.0, m.vz / 100.0) + self._MPFakeState__on_change('location', 'velocity') + + @message_default('GPS_RAW') + def listener(self, name, m): + # (self.lat, self.lon) = (m.lat, m.lon) + # self.__on_change('location') + # better to just use global position int + pass + + self.eph = None + self.epv = None + self.satellites_visible = None + self.fix_type = None # FIXME support multiple GPSs per vehicle - possibly by using componentId + + @message_default('GPS_RAW_INT') + def listener(self, name, m): + # (self.lat, self.lon) = (m.lat / 1.0e7, m.lon / 1.0e7) + self.eph = m.eph + self.epv = m.epv + self.satellites_visible = m.satellites_visible + self.fix_type = m.fix_type + self._MPFakeState__on_change('gps_0') + self.heading = None + # self.alt = None self.airspeed = None self.groundspeed = None + + @message_default('VFR_HUD') + def listener(self, name, m): + self.heading = m.heading + self.alt = m.alt + self.airspeed = m.airspeed + self.groundspeed = m.groundspeed + self._MPFakeState__on_change('location', 'airspeed', 'groundspeed') self.pitch = None self.yaw = None @@ -91,45 +165,96 @@ def __init__(self, master, status_printer=None): self.pitchspeed = None self.yawspeed = None self.rollspeed = None - - self.mount_pitch = None - self.mount_yaw = None - self.mount_roll = None + + @message_default('ATTITUDE') + def listener(self, name, m): + self.pitch = m.pitch + self.yaw = m.yaw + self.roll = m.roll + self.pitchspeed = m.pitchspeed + self.yawspeed = m.yawspeed + self.rollspeed = m.rollspeed + self._MPFakeState__on_change('attitude') self.voltage = -1 self.current = -1 self.level = -1 + + @message_default('SYS_STATUS') + def listener(self, name, m): + self.voltage = m.voltage_battery + self.current = m.current_battery + self.level = m.battery_remaining + self._MPFakeState__on_change('battery') - self.rc_readback = {} + @message_default('HEARTBEAT') + def listener(self, name, m): + self._MPFakeState__on_change('mode', 'armed') self.last_waypoint = 0 - self.eph = None - self.epv = None - self.satellites_visible = None - self.fix_type = None # FIXME support multiple GPSs per vehicle - possibly by using componentId - self.ekf_ok = False + @message_default(['WAYPOINT_CURRENT', 'MISSION_CURRENT']) + def listener(self, name, m): + self.last_waypoint = m.seq + + self.rc_readback = {} + + @message_default('RC_CHANNELS_RAW') + def listener(self, name, m): + def set(chnum, v): + '''Private utility for handling rc channel messages''' + # use port to allow ch nums greater than 8 + self.rc_readback[str(m.port * 8 + chnum)] = v + + set(1, m.chan1_raw) + set(2, m.chan2_raw) + set(3, m.chan3_raw) + set(4, m.chan4_raw) + set(5, m.chan5_raw) + set(6, m.chan6_raw) + set(7, m.chan7_raw) + set(8, m.chan8_raw) + + self.mount_pitch = None + self.mount_yaw = None + self.mount_roll = None + + @message_default('MOUNT_STATUS') + def listener(self, name, m): + self.mount_pitch = m.pointing_a / 100 + self.mount_roll = m.pointing_b / 100 + self.mount_yaw = m.pointing_c / 100 + self._MPFakeState__on_change('mount') self.rngfnd_distance = None self.rngfnd_voltage = None - self.status = type('MPStatus',(object,),{ - 'flightmode': 'AUTO', - 'armed': False, - })() + @message_default('RANGEFINDER') + def listener(self, name, m): + self.rngfnd_distance = m.distance + self.rngfnd_voltage = m.voltage + self._MPFakeState__on_change('rangefinder') - self.mav_param = {} + self.ekf_ok = False - # Weird - self.mpstate = self - self.functions = self - self.mpstate.settings = self + @message_default('EKF_STATUS_REPORT') + def listener(self, name, m): + # legacy check for dronekit-python for solo + # use same check that ArduCopter::system.pde::position_ok() is using - self.status_printer = status_printer + # boolean: EKF's horizontal position (absolute) estimate is good + status_poshorizabs = (m.flags & ardupilotmega.EKF_POS_HORIZ_ABS) > 0 + # boolean: EKF is in constant position mode and does not know it's absolute or relative position + status_constposmode = m.flags & ardupilotmega.EKF_CONST_POS_MODE > 0 + # boolean: EKF's predicted horizontal position (absolute) estimate is good + status_predposhorizabs = (m.flags & ardupilotmega.EKF_PRED_POS_HORIZ_ABS) > 0 - # waypoints - self.wploader = mavwp.MAVWPLoader() - self.wp_loaded = True + if self.status.armed: + self.ekf_ok = status_poshorizabs and not status_constposmode + else: + self.ekf_ok = status_poshorizabs or status_predposhorizabs + + self._MPFakeState__on_change('ekf_ok') def fetch(self): """ @@ -185,88 +310,32 @@ def __on_change(self, *args): for v in self.api.get_vehicles(): v.notify_observers(a) - def mavlink_packet(self, m): - typ = m.get_type() - if typ == 'STATUSTEXT': - print(re.sub(r'(^|\n)', '>>> \1', m.text.rstrip())) - elif typ == 'GLOBAL_POSITION_INT': - (self.lat, self.lon) = (m.lat / 1.0e7, m.lon / 1.0e7) - (self.vx, self.vy, self.vz) = (m.vx / 100.0, m.vy / 100.0, m.vz / 100.0) - self.__on_change('location', 'velocity') - elif typ == 'GPS_RAW': - pass # better to just use global position int - # (self.lat, self.lon) = (m.lat, m.lon) - # self.__on_change('location') - elif typ == 'GPS_RAW_INT': - # (self.lat, self.lon) = (m.lat / 1.0e7, m.lon / 1.0e7) - self.eph = m.eph - self.epv = m.epv - self.satellites_visible = m.satellites_visible - self.fix_type = m.fix_type - self.__on_change('gps_0') - elif typ == "VFR_HUD": - self.heading = m.heading - self.alt = m.alt - self.airspeed = m.airspeed - self.groundspeed = m.groundspeed - self.__on_change('location', 'airspeed', 'groundspeed') - elif typ == "ATTITUDE": - self.pitch = m.pitch - self.yaw = m.yaw - self.roll = m.roll - self.pitchspeed = m.pitchspeed - self.yawspeed = m.yawspeed - self.rollspeed = m.rollspeed - self.__on_change('attitude') - elif typ == "SYS_STATUS": - self.voltage = m.voltage_battery - self.current = m.current_battery - self.level = m.battery_remaining - self.__on_change('battery') - elif typ == "HEARTBEAT": - self.__on_change('mode', 'armed') - elif typ in ["WAYPOINT_CURRENT", "MISSION_CURRENT"]: - self.last_waypoint = m.seq - elif typ == "RC_CHANNELS_RAW": - def set(chnum, v): - '''Private utility for handling rc channel messages''' - # use port to allow ch nums greater than 8 - self.rc_readback[str(m.port * 8 + chnum)] = v - - set(1, m.chan1_raw) - set(2, m.chan2_raw) - set(3, m.chan3_raw) - set(4, m.chan4_raw) - set(5, m.chan5_raw) - set(6, m.chan6_raw) - set(7, m.chan7_raw) - set(8, m.chan8_raw) - elif typ == "MOUNT_STATUS": - self.mount_pitch = m.pointing_a / 100 - self.mount_roll = m.pointing_b / 100 - self.mount_yaw = m.pointing_c / 100 - self.__on_change('mount') - elif typ == "RANGEFINDER": - self.rngfnd_distance = m.distance - self.rngfnd_voltage = m.voltage - self.__on_change('rangefinder') - elif typ == "EKF_STATUS_REPORT": - # legacy check for dronekit-python for solo - # use same check that ArduCopter::system.pde::position_ok() is using + def on_message(self, name, fn): + """ + Adds a message listener. + """ + name = str(name) + if name not in self.message_listeners: + self.message_listeners[name] = [] + if fn not in self.message_listeners[name]: + self.message_listeners[name].append(fn) - # boolean: EKF's horizontal position (absolute) estimate is good - status_poshorizabs = (m.flags & ardupilotmega.EKF_POS_HORIZ_ABS) > 0 - # boolean: EKF is in constant position mode and does not know it's absolute or relative position - status_constposmode = m.flags & ardupilotmega.EKF_CONST_POS_MODE > 0 - # boolean: EKF's predicted horizontal position (absolute) estimate is good - status_predposhorizabs = (m.flags & ardupilotmega.EKF_PRED_POS_HORIZ_ABS) > 0 + def remove_message_listener(self, name, fn): + """ + Removes a message listener. + """ + name = str(name) + if name in self.message_listeners: + self.message_listeners[name].remove(fn) + if len(self.message_listeners[name]) == 0: + del self.message_listeners[name] - if self.status.armed: - self.ekf_ok = status_poshorizabs and not status_constposmode - else: - self.ekf_ok = status_poshorizabs or status_predposhorizabs + def mavlink_packet(self, m): + typ = m.get_type() - self.__on_change('ekf_ok') + # Call message listeners. + for fn in self.message_listeners.get(typ, []): + fn(self, typ, m) if self.api: for v in self.api.get_vehicles(): From 98ccc97f5a94695416de1605cf282a010ad65409 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 13 Oct 2015 16:58:54 -0400 Subject: [PATCH 017/475] Corrects status_printer. --- dronekit/__init__.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index ed38456b1..7d7b8942c 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -56,7 +56,7 @@ def request_data_stream_send(master, rate=1): from threading import Thread class MPFakeState: - def __init__(self, master, status_printer=None): + def __init__(self, master): self.master = master out_queue = Queue() # self.mav_thread = mav_thread(master, self) @@ -106,11 +106,12 @@ def decorator(fn): self.on_message(name, fn) return decorator - self.status_printer = status_printer + self.status_printer = None @message_default('STATUSTEXT') def listener(self, name, m): - self.status_printer(re.sub(r'(^|\n)', '>>> \1', m.text.rstrip())) + if self.status_printer: + self.status_printer(re.sub(r'(^|\n)', '>>> \1', m.text.rstrip())) self.lat = None self.lon = None From ac2ec9e5fe9d6b13ee395b59b591a6f22dbd99cf Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 13 Oct 2015 17:25:59 -0400 Subject: [PATCH 018/475] Adds ability to abstract Vehicle class. --- dronekit/__init__.py | 34 +++++++++++++++++++++------------- dronekit/module/api.py | 4 ++++ 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 7d7b8942c..448f57c4c 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -19,12 +19,15 @@ import dronekit.module.api as api +# Public exports +Vehicle = api.MPVehicle + def errprinter(*args): print(*args, file=sys.stderr) class FakeAPI: def __init__(self, module): - self.__vehicle = api.MPVehicle(module) + self.__vehicle = module.vehicle_class(module) self.exit = False def get_vehicles(self, query=None): @@ -56,7 +59,9 @@ def request_data_stream_send(master, rate=1): from threading import Thread class MPFakeState: - def __init__(self, master): + def __init__(self, master, vehicle_class=Vehicle): + self.vehicle_class = vehicle_class + self.master = master out_queue = Queue() # self.mav_thread = mav_thread(master, self) @@ -124,7 +129,7 @@ def listener(self, name, m): def listener(self, name, m): (self.lat, self.lon) = (m.lat / 1.0e7, m.lon / 1.0e7) (self.vx, self.vy, self.vz) = (m.vx / 100.0, m.vy / 100.0, m.vz / 100.0) - self._MPFakeState__on_change('location', 'velocity') + self._notify_attribute_listeners('location', 'velocity') @message_default('GPS_RAW') def listener(self, name, m): @@ -145,7 +150,7 @@ def listener(self, name, m): self.epv = m.epv self.satellites_visible = m.satellites_visible self.fix_type = m.fix_type - self._MPFakeState__on_change('gps_0') + self._notify_attribute_listeners('gps_0') self.heading = None # self.alt = None @@ -158,7 +163,7 @@ def listener(self, name, m): self.alt = m.alt self.airspeed = m.airspeed self.groundspeed = m.groundspeed - self._MPFakeState__on_change('location', 'airspeed', 'groundspeed') + self._notify_attribute_listeners('location', 'airspeed', 'groundspeed') self.pitch = None self.yaw = None @@ -175,7 +180,7 @@ def listener(self, name, m): self.pitchspeed = m.pitchspeed self.yawspeed = m.yawspeed self.rollspeed = m.rollspeed - self._MPFakeState__on_change('attitude') + self._notify_attribute_listeners('attitude') self.voltage = -1 self.current = -1 @@ -186,11 +191,11 @@ def listener(self, name, m): self.voltage = m.voltage_battery self.current = m.current_battery self.level = m.battery_remaining - self._MPFakeState__on_change('battery') + self._notify_attribute_listeners('battery') @message_default('HEARTBEAT') def listener(self, name, m): - self._MPFakeState__on_change('mode', 'armed') + self._notify_attribute_listeners('mode', 'armed') self.last_waypoint = 0 @@ -225,7 +230,7 @@ def listener(self, name, m): self.mount_pitch = m.pointing_a / 100 self.mount_roll = m.pointing_b / 100 self.mount_yaw = m.pointing_c / 100 - self._MPFakeState__on_change('mount') + self._notify_attribute_listeners('mount') self.rngfnd_distance = None self.rngfnd_voltage = None @@ -234,7 +239,7 @@ def listener(self, name, m): def listener(self, name, m): self.rngfnd_distance = m.distance self.rngfnd_voltage = m.voltage - self._MPFakeState__on_change('rangefinder') + self._notify_attribute_listeners('rangefinder') self.ekf_ok = False @@ -255,7 +260,7 @@ def listener(self, name, m): else: self.ekf_ok = status_poshorizabs or status_predposhorizabs - self._MPFakeState__on_change('ekf_ok') + self._notify_attribute_listeners('ekf_ok') def fetch(self): """ @@ -311,6 +316,9 @@ def __on_change(self, *args): for v in self.api.get_vehicles(): v.notify_observers(a) + def _notify_attribute_listeners(self, *args): + return self.__on_change(*args) + def on_message(self, name, fn): """ Adds a message listener. @@ -560,9 +568,9 @@ def mavlink_thread(): return self.api -def connect(ip, await_params=False, status_printer=errprinter): +def connect(ip, await_params=False, status_printer=errprinter, vehicle_class=Vehicle): import dronekit.module.api as api - state = MPFakeState(mavutil.mavlink_connection(ip)) + state = MPFakeState(mavutil.mavlink_connection(ip), vehicle_class=Vehicle) state.status_printer = status_printer # api.init(state) return state.prepare(await_params=await_params).get_vehicles()[0] diff --git a/dronekit/module/api.py b/dronekit/module/api.py index 976dfd3c2..bc859bfa3 100644 --- a/dronekit/module/api.py +++ b/dronekit/module/api.py @@ -279,6 +279,10 @@ def wait_init(self): time.sleep(pollinterval) raise APIException("Vehicle did not complete initialization") + def on_message(self, name, fn): + def handler(state, name, m): + return fn(elf, name, m) + return self.__module.on_message(name, handler) class MPAPIConnection(APIConnection): """ From 0cd3ed76cd7e050a22c991fd0740d4d090a8d7f7 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 13 Oct 2015 17:35:22 -0400 Subject: [PATCH 019/475] Adds Vehicle inheritance test. --- dronekit/__init__.py | 4 +++- dronekit/module/api.py | 2 +- tests/sitl/test_vehicleclass.py | 20 ++++++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 tests/sitl/test_vehicleclass.py diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 448f57c4c..fea5cd4d2 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -345,6 +345,8 @@ def mavlink_packet(self, m): # Call message listeners. for fn in self.message_listeners.get(typ, []): fn(self, typ, m) + for fn in self.message_listeners.get('*', []): + fn(self, typ, m) if self.api: for v in self.api.get_vehicles(): @@ -570,7 +572,7 @@ def mavlink_thread(): def connect(ip, await_params=False, status_printer=errprinter, vehicle_class=Vehicle): import dronekit.module.api as api - state = MPFakeState(mavutil.mavlink_connection(ip), vehicle_class=Vehicle) + state = MPFakeState(mavutil.mavlink_connection(ip), vehicle_class=vehicle_class) state.status_printer = status_printer # api.init(state) return state.prepare(await_params=await_params).get_vehicles()[0] diff --git a/dronekit/module/api.py b/dronekit/module/api.py index bc859bfa3..e23c43bd3 100644 --- a/dronekit/module/api.py +++ b/dronekit/module/api.py @@ -281,7 +281,7 @@ def wait_init(self): def on_message(self, name, fn): def handler(state, name, m): - return fn(elf, name, m) + return fn(self, name, m) return self.__module.on_message(name, handler) class MPAPIConnection(APIConnection): diff --git a/tests/sitl/test_vehicleclass.py b/tests/sitl/test_vehicleclass.py new file mode 100644 index 000000000..0d87d1527 --- /dev/null +++ b/tests/sitl/test_vehicleclass.py @@ -0,0 +1,20 @@ +from dronekit import connect, Vehicle +from dronekit.tools import with_sitl +import time +from nose.tools import assert_equals + +class DummyVehicle(Vehicle): + def __init__(self, *args): + super(DummyVehicle, self).__init__(*args) + + self.success = False + def success_fn(self, name, m): + self.success = True + self.on_message('HEARTBEAT', success_fn) + +@with_sitl +def test_timeout(connpath): + v = connect(connpath, vehicle_class=DummyVehicle) + + while not v.success: + time.sleep(0.1) From 1fb01fbf28fda8ccbfa76f3ff76c3f711f207ade Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 14 Oct 2015 08:23:39 -0400 Subject: [PATCH 020/475] Removes protobuf dependency. Closes #339 --- requirements.txt | 2 -- scripts/compile-protobufs.sh | 7 ----- setup.py | 48 ++++++++++++++++++---------------- windows/droneapiWinBuild.bat | 24 ----------------- windows/droneapi_installer.iss | 1 - 5 files changed, 26 insertions(+), 56 deletions(-) delete mode 100755 scripts/compile-protobufs.sh diff --git a/requirements.txt b/requirements.txt index b59df0378..ce1b2e86f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,3 @@ -poster==0.8.1 -protobuf==2.6.1 requests==2.5.1 pymavlink>=1.1.62 sphinx-3dr-theme>=0.0.6 diff --git a/scripts/compile-protobufs.sh b/scripts/compile-protobufs.sh deleted file mode 100755 index 588c00285..000000000 --- a/scripts/compile-protobufs.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -cd $(dirname $0) -cd .. - -DESTDIR=dronekit/lib -protoc --python_out=$DESTDIR --proto_path=../dronekit-protobuf/src ../dronekit-protobuf/src/webapi.proto diff --git a/setup.py b/setup.py index a6add7a28..2c26cd440 100644 --- a/setup.py +++ b/setup.py @@ -3,25 +3,29 @@ version = '2.0.0b3' -setup (name = 'dronekit', - zip_safe=True, - version = version, - description = 'Python language bindings for the DroneApi', - long_description = 'Python language bindings for the DroneApi', - url = 'https://github.com/dronekit/dronekit-python', - author = '3D Robotics', - install_requires = ['pymavlink >= 1.1.62', - 'protobuf >= 2.5.0', - 'requests == 2.5.1' ], - author_email = 'tim@3drobotics.com, kevinh@geeksville.com', - classifiers=['Development Status :: 4 - Beta', - 'Environment :: Console', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: Apache Software License', - 'Operating System :: OS Independent', - 'Programming Language :: Python :: 2.7', - 'Topic :: Scientific/Engineering' - ], - license='apache', - packages = ['dronekit', 'dronekit.module', 'dronekit.lib' ], - ext_modules = []) +setup(name='dronekit', + zip_safe=True, + version=version, + description='Python language bindings for the DroneApi', + long_description='Python language bindings for the DroneApi', + url='https://github.com/dronekit/dronekit-python', + author='3D Robotics', + install_requires=[ + 'pymavlink >= 1.1.62', + 'requests == 2.5.1', + ], + author_email='tim@3drobotics.com, kevinh@geeksville.com', + classifiers=[ + 'Development Status :: 4 - Beta', + 'Environment :: Console', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: Apache Software License', + 'Operating System :: OS Independent', + 'Programming Language :: Python :: 2.7', + 'Topic :: Scientific/Engineering', + ], + license='apache', + packages=[ + 'dronekit', 'dronekit.module', 'dronekit.lib' + ], + ext_modules=[]) diff --git a/windows/droneapiWinBuild.bat b/windows/droneapiWinBuild.bat index dba643871..1344267f3 100644 --- a/windows/droneapiWinBuild.bat +++ b/windows/droneapiWinBuild.bat @@ -9,29 +9,5 @@ for /f "tokens=*" %%a in ( set VERSION=%%a ) -rem -----Get protobuf and unzip----- -C:\python27\scripts\pip.exe install --download .\ protobuf -rem get the protobuf fullname -for /f "tokens=*" %%a in ( - 'dir /B protobuf-*' - ) do ( - set PROTOBUFFULL=%%a - ) - -rem Use 7zip to unzip files. Works for both 32 and 64 bit versions -"C:\Program Files\7-zip\7z.exe" x -y %PROTOBUFFULL% -"C:\Program Files\7-zip\7z.exe" x -y .\dist\protobuf* -"C:\Program Files (x86)\7-zip\7z.exe" x -y %PROTOBUFFULL% -"C:\Program Files (x86)\7-zip\7z.exe" x -y .\dist\protobuf* - -rem get the protobuf fullname -for /f "tokens=*" %%a in ( - 'dir /A:D /B protobuf-*' - ) do ( - set PROTOBUFDIR=%%a - ) -xcopy /E /Y %PROTOBUFDIR%\google .\google\ - - rem -----Build the Installer----- "C:\Program Files (x86)\Inno Setup 5\ISCC.exe" /dMyAppVersion=%VERSION% dronekit_installer.iss diff --git a/windows/droneapi_installer.iss b/windows/droneapi_installer.iss index b9e3f5e76..707baa6ef 100644 --- a/windows/droneapi_installer.iss +++ b/windows/droneapi_installer.iss @@ -32,7 +32,6 @@ Name: "english"; MessagesFile: "compiler:Default.isl" [Files] Source: "..\dronekit\*"; DestDir: "{code:GetMAVProxyPath}\dronekit"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "..\examples\*"; DestDir: "{code:GetMAVProxyPath}\examples"; Flags: ignoreversion recursesubdirs createallsubdirs -Source: "google\*"; DestDir: "{code:GetMAVProxyPath}\google"; Flags: ignoreversion recursesubdirs createallsubdirs ; NOTE: Don't use "Flags: ignoreversion" on any shared system files From 10d3a9cc50b421915f1e6badd0dab5a6d7498fdc Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 14 Oct 2015 08:53:45 -0400 Subject: [PATCH 021/475] Adds Solo-specific system_status impl. --- dronekit/__init__.py | 3 +++ dronekit/module/api.py | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index fea5cd4d2..c938e1cb0 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -193,8 +193,11 @@ def listener(self, name, m): self.level = m.battery_remaining self._notify_attribute_listeners('battery') + self.system_status = None + @message_default('HEARTBEAT') def listener(self, name, m): + self.system_status = m.system_status self._notify_attribute_listeners('mode', 'armed') self.last_waypoint = 0 diff --git a/dronekit/module/api.py b/dronekit/module/api.py index e23c43bd3..c66c6effc 100644 --- a/dronekit/module/api.py +++ b/dronekit/module/api.py @@ -199,6 +199,10 @@ def armed(self, value): else: self.__master.arducopter_disarm() + @property + def system_status(self): + return self.__module.system_status + @property def groundspeed(self): return self.__module.groundspeed From 7564d6b6463eb8af862bb1b44783c1a24c3d0bd2 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 14 Oct 2015 16:15:00 -0400 Subject: [PATCH 022/475] Adds undocumented interface for parameters setting. --- dronekit/__init__.py | 12 ++++++++---- dronekit/module/api.py | 5 +++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index c938e1cb0..25390ab59 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -302,16 +302,20 @@ def param_set(self, name, value, retries=3): name = name.upper() value = float(value) success = False - while retries > 0: - retries -= 1 + remaining = retries + while True: self.master.param_set_send(name.upper(), value) tstart = time.time() + if remaining == 0: + break + remaining -= 1 while time.time() - tstart < 1: - if self.mav_param[name] == value: + if name in self.mav_param and self.mav_param[name] == value: return True time.sleep(0.1) - errprinter("timeout setting parameter %s to %f" % (name, value)) + if retries > 0: + errprinter("timeout setting parameter %s to %f" % (name, value)) return False def __on_change(self, *args): diff --git a/dronekit/module/api.py b/dronekit/module/api.py index c66c6effc..616367010 100644 --- a/dronekit/module/api.py +++ b/dronekit/module/api.py @@ -32,6 +32,11 @@ def __setitem__(self, name, value): self.wait_valid() self.__module.mpstate.functions.param_set(name, value) + def set(self, name, value, retries=3, await_valid=False): + if await_valid: + self.wait_valid() + return self.__module.mpstate.param_set(name, value, retries=retries) + def wait_valid(self): '''Block the calling thread until parameters have been downloaded''' # FIXME this is a super crufty spin-wait, also we should give the user the option of specifying a timeout From 83cd7756c5fc773496256828c62bc95e8cabe469 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 14 Oct 2015 16:20:44 -0400 Subject: [PATCH 023/475] Adds a close method. --- dronekit/__init__.py | 8 ++++++++ dronekit/module/api.py | 3 +++ setup.py | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 25390ab59..86d579cc1 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -548,6 +548,7 @@ def mavlink_thread(): t = Thread(target=mavlink_thread) t.daemon = True t.start() + self.mavlink_thread = t # Wait for first heartbeat. while True: @@ -577,6 +578,13 @@ def mavlink_thread(): return self.api + def close(self): + # TODO this can block forever if parameters continue to be added + self.exiting = True + while not self.out_queue.empty(): + time.sleep(0.1) + self.master.close() + def connect(ip, await_params=False, status_printer=errprinter, vehicle_class=Vehicle): import dronekit.module.api as api state = MPFakeState(mavutil.mavlink_connection(ip), vehicle_class=vehicle_class) diff --git a/dronekit/module/api.py b/dronekit/module/api.py index 616367010..ad4abf7eb 100644 --- a/dronekit/module/api.py +++ b/dronekit/module/api.py @@ -133,6 +133,9 @@ def __init__(self, module): self._waypoints = None self.wpts_dirty = False + def close(self): + return self.__module.close() + def flush(self): if self.wpts_dirty: self.__module.send_all_waypoints() diff --git a/setup.py b/setup.py index 2c26cd440..f6c1dfb1d 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.0.0b3' +version = '2.0.0b4' setup(name='dronekit', zip_safe=True, From 807abb41353bf3ae1627f618735f81754f6ed413 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 14 Oct 2015 16:31:20 -0400 Subject: [PATCH 024/475] 2.0.0b5 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index f6c1dfb1d..cf2301d5f 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.0.0b4' +version = '2.0.0b5' setup(name='dronekit', zip_safe=True, From 185c1adbf699bf688eda10d040811b2c760d46b0 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 15 Oct 2015 11:48:22 -0400 Subject: [PATCH 025/475] Adds request rate parameter. --- dronekit/__init__.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 86d579cc1..d8c0564f0 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -360,7 +360,7 @@ def mavlink_packet(self, m): if v.mavrx_callback: v.mavrx_callback(m) - def prepare(self, await_params=False): + def prepare(self, await_params=False, rate=None): # errprinter('Await heartbeat.') # TODO this should be more rigious. How to avoid # invalid MAVLink prefix '73' @@ -560,7 +560,8 @@ def mavlink_thread(): heartbeat_started = True # Request a list of all parameters. - request_data_stream_send(self.master) + if rate != None: + request_data_stream_send(self.master, rate=rate) while True: # This fn actually rate limits itself to every 2s. # Just retry with persistence to get our first param stream. @@ -585,9 +586,9 @@ def close(self): time.sleep(0.1) self.master.close() -def connect(ip, await_params=False, status_printer=errprinter, vehicle_class=Vehicle): +def connect(ip, await_params=False, status_printer=errprinter, vehicle_class=Vehicle, rate=None): import dronekit.module.api as api state = MPFakeState(mavutil.mavlink_connection(ip), vehicle_class=vehicle_class) state.status_printer = status_printer # api.init(state) - return state.prepare(await_params=await_params).get_vehicles()[0] + return state.prepare(await_params=await_params, rate=rate).get_vehicles()[0] From 2aa214a4594a33a6985324c344ba5e5a3aefe82b Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 15 Oct 2015 12:01:09 -0400 Subject: [PATCH 026/475] Adds default rate of 4 (like MAVProxy) --- dronekit/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index d8c0564f0..117a12b19 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -586,7 +586,7 @@ def close(self): time.sleep(0.1) self.master.close() -def connect(ip, await_params=False, status_printer=errprinter, vehicle_class=Vehicle, rate=None): +def connect(ip, await_params=False, status_printer=errprinter, vehicle_class=Vehicle, rate=4): import dronekit.module.api as api state = MPFakeState(mavutil.mavlink_connection(ip), vehicle_class=vehicle_class) state.status_printer = status_printer From 247b91d97b07585d10de8a8e158679f03b8209d6 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 15 Oct 2015 12:05:14 -0400 Subject: [PATCH 027/475] 2.0.0b6 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index cf2301d5f..c17c8eea9 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.0.0b5' +version = '2.0.0b6' setup(name='dronekit', zip_safe=True, From 6447c7f95aa13d2a1bcfb81d3ec10b083088038f Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 14 Oct 2015 09:56:26 -0400 Subject: [PATCH 028/475] Tests that parameter setting is less than 1s. Closes #12 --- tests/sitl/test_12.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/sitl/test_12.py b/tests/sitl/test_12.py index 245e67928..2380f2fba 100644 --- a/tests/sitl/test_12.py +++ b/tests/sitl/test_12.py @@ -25,5 +25,6 @@ def test_timeout(connpath): assert_equals(type(newvalue), float) assert_equals(newvalue, value + 10) - # TODO once this issue is fixed - # assert end - start < 1000, 'time to set parameter was %s, over 1s' % (end - start,) + # Checks that time to set parameter was <1s + # see https://github.com/dronekit/dronekit-python/issues/12 + assert end - start < 1000, 'time to set parameter was %s, over 1s' % (end - start,) From 04654bea3d5be9b178e3715089cc67b1d0a9dfed Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 21 Oct 2015 17:27:50 +1100 Subject: [PATCH 029/475] Add vehicle.close and local_path information to migration guide --- docs/guide/migrating.rst | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/docs/guide/migrating.rst b/docs/guide/migrating.rst index 2af1ec245..5a8d93aac 100644 --- a/docs/guide/migrating.rst +++ b/docs/guide/migrating.rst @@ -85,11 +85,12 @@ The vehicle can then be used in exactly the same way as in DKPY 1.x. .. todo:: Above link to the connect method in API ref - make sure connect() is documented. -Exit status checks ------------------- +Connection status checks +------------------------ -Remove code that checks the ``api.exit`` status (note that the ``api.exit`` call below is commented out). DroneKit no -longer runs in *MAVProxy* so scripts don't need to monitor and act on external thread shutdown commands. +DroneKit no longer runs in *MAVProxy* so scripts don't need to monitor and act on external thread shutdown commands. + +Remove code that checks the ``api.exit`` status (note that the ``api.exit`` call below is commented out). .. code:: python @@ -105,7 +106,18 @@ longer runs in *MAVProxy* so scripts don't need to monitor and act on external t .. todo:: Find out how to check the connection status is still valid. That would go in separate section. - +Script completion checks +------------------------ + +Examples that might possibly have outstanding messages should call :py:func:`Vehicle.close() ` +before exiting to ensure that all messages have flushed before the script completes: + +.. code:: python + + #About to exit script + vehicle.close() + + Command line arguments ---------------------- @@ -135,3 +147,17 @@ use whatever method you like. .. todo:: This addition closes https://github.com/dronekit/dronekit-python/issues/13 +Current script directory +------------------------ + +DroneKit-Python v1.x passed a global property ``load_path`` to any executed file containing the +directory in which the script was running. This is no longer needed in version 2 and has been removed. + +Instead, use normal Python methods for getting file system information: + +.. code:: python + + import os.path + full_directory_path_of_current_script = os.path.dirname(os.path.abspath(__file__)) + + From 48d7ddab004549d17a2408700ef73ac62b7bb658 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 16 Oct 2015 14:10:30 +1100 Subject: [PATCH 030/475] Test and fix up simple_goto.py and example docs for DKPY2 (b6) --- docs/examples/simple_goto.rst | 102 +++++++++++++++++----------- examples/simple_goto/simple_goto.py | 8 ++- 2 files changed, 68 insertions(+), 42 deletions(-) diff --git a/docs/examples/simple_goto.rst b/docs/examples/simple_goto.rst index 0f1387460..a65474bb2 100644 --- a/docs/examples/simple_goto.rst +++ b/docs/examples/simple_goto.rst @@ -4,12 +4,12 @@ Example: Simple Go To (Copter) ============================== -This example demonstrates how to arm and launch a Copter in GUIDED mode, travel to a number of waypoints, and then return +This example demonstrates how to arm and launch a Copter in GUIDED mode, travel towards a number of target points, and then return to the home location. It uses :py:func:`Vehicle.commands.takeoff() `, :py:func:`Vehicle.commands.goto() ` and :py:attr:`Vehicle.mode `. -The locations used are centred around the home location when the :ref:`Simulated Vehicle ` is booted; you can edit the latitude and longitude -to use more appropriate positions for your own vehicle. +The target locations are centred around the home location when the :ref:`Simulated Vehicle ` is booted; +you can edit the latitude and longitude to use more appropriate positions for your own vehicle. .. note:: @@ -19,65 +19,83 @@ to use more appropriate positions for your own vehicle. * *Rover* will ignore the ``takeoff`` command and will then stick at the altitude check. +.. figure:: simple_goto_example_copter_path.png + :width: 50 % + :alt: Setting destination using position and changing speed and ROI + + Simple Goto Example: Flight path + + Running the example =================== -The vehicle and DroneKit should be set up as described in :ref:`get-started`. +The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle +and DroneKit have been set up as described in :ref:`get-started`). If you're using a simulated vehicle, remember to :ref:`disable arming checks ` so that the example can run. -Once MAVProxy is running and the API is loaded, you can start the example by typing: ``api start simple_goto.py``. +In summary, after cloning the repository: -.. note:: +#. Navigate to the example folder as shown: + + .. code-block:: bash + + cd dronekit-python\examples\simple_goto\ - The command above assumes you started the *MAVProxy* prompt in a directory containing the example script. If not, - you will have to specify the full path to the script (something like): - ``api start /home/user/git/dronekit-python/examples/simple_goto/simple_goto.py``. -.. tip:: +#. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: + + .. code-block:: bash + + python simple_goto.py --connect 127.0.0.1:14550 + + .. note:: + + The examples uses the ``--connect`` parameter to pass the :ref:`connection string ` into the script. + The command above would be used to connect to :ref:`SITL ` running on the local machine via UDP port 14550. + + +.. tip:: It is more interesting to watch the example above on a map than the console. The topic :ref:`viewing_uav_on_map` explains how to set up *Mission Planner* to view a vehicle running on the simulator (SITL). -On the *MAVProxy* console you should see (something like): +On the command prompt you should see (something like): -.. code-block:: python +.. code-block:: bash - MAV> api start simple_goto.py - STABILIZE> Basic pre-arm checks + \dronekit-python\examples\simple_goto>simple_goto.py + Connecting to vehicle on: 127.0.0.1:14550 + >>> ☺APM:Copter V3.4-dev (e0810c2e) + >>> ☺Frame: QUAD + Basic pre-arm checks + Waiting for GPS...: None + ... + Waiting for GPS...: None Arming motors Waiting for arming... - Waiting for arming... - APM: ARMING MOTORS - APM: GROUND START - Waiting for arming... - Waiting for arming... - GUIDED> Mode GUIDED - APM: Initialising APM... - Got MAVLink msg: COMMAND_ACK {command : 400, result : 0} - Waiting for arming... - ARMED + >>> ☺ARMING MOTORS + >>> ☺Initialising APM... Taking off! Altitude: 0.0 - Got MAVLink msg: COMMAND_ACK {command : 22, result : 0} - Altitude: 0.10000000149 - Altitude: 0.620000004768 - ... - Altitude: 19.25 + Altitude: 0.00999999977648 + Altitude: 0.25 + Altitude: 0.5 + ... + Altitude: 18.7299995422 + Altitude: 19.2700004578 Reached target altitude Going to first point... - Got MAVLink msg: MISSION_ACK {target_system : 255, target_component : 0, type : 0} Going to second point... - Got MAVLink msg: MISSION_ACK {target_system : 255, target_component : 0, type : 0} Returning to Launch - APIThread-0 exiting... - -.. tip:: + Close vehicle object + +.. tip:: If you get stuck in ``Waiting for arming...`` it is very likely that the vehicle did not pass all pre-arm checks. - On a real device you can view the controller LEDs to determine likely issues. On the Simulator console you + On a real device you can view the controller LEDs to determine possible causes. On the Simulator console you can disable the checks if needed: .. code-block:: bash @@ -89,7 +107,7 @@ On the *MAVProxy* console you should see (something like): How does it work? ================= -The code has three distinct sections: arming and takeoff, flight to a specified location, and return-to-home. +The code has three distinct sections: arming and takeoff, flight to two locations, and return-to-home. Takeoff ------- @@ -98,7 +116,7 @@ To launch *Copter* you need to set the mode to ``GUIDED``, arm the vehicle, and :py:func:`Vehicle.commands.takeoff() `. The takeoff code in this example is explained in the guide topic :ref:`taking-off`. - + Flying to a point - Goto ------------------------ @@ -106,7 +124,7 @@ The vehicle is already in ``GUIDED`` mode, so to send it to a certain point we j call :py:func:`Vehicle.commands.goto() ` with the target location, and then :py:func:`flush() ` the command: -.. code-block:: python +.. code-block:: python point1 = Location(-35.361354, 149.165218, 20, is_relative=True) vehicle.commands.goto(point1) @@ -116,7 +134,11 @@ and then :py:func:`flush() ` the command: time.sleep(30) Without some sort of "wait" the next command would be executed immediately. In this example we just -sleep for 30 seconds - a good opportunity to observe the vehicle's movement on a map. +sleep for 30 seconds, set a new destination and then sleep another 30 seconds (the vehicle doesn't reach +its target destination in either 30 second wait). The script doesn't report anything during these sleep periods, +but you can observe the vehicle's movement on a ground station map. + + RTL - Return to launch @@ -124,7 +146,7 @@ RTL - Return to launch To return to the home position and land, we set the mode to ``RTL``: -.. code-block:: python +.. code-block:: python vehicle.mode = VehicleMode("RTL") vehicle.flush() diff --git a/examples/simple_goto/simple_goto.py b/examples/simple_goto/simple_goto.py index 555935e7e..f958ad1de 100644 --- a/examples/simple_goto/simple_goto.py +++ b/examples/simple_goto/simple_goto.py @@ -39,7 +39,7 @@ def arm_and_takeoff(aTargetAltitude): while vehicle.gps_0.fix_type < 2: print "Waiting for GPS...:", vehicle.gps_0.fix_type time.sleep(1) - + print "Arming motors" # Copter should arm in GUIDED mode vehicle.mode = VehicleMode("GUIDED") @@ -80,8 +80,12 @@ def arm_and_takeoff(aTargetAltitude): vehicle.flush() # sleep so we can see the change in map -time.sleep(20) +time.sleep(30) print "Returning to Launch" vehicle.mode = VehicleMode("RTL") vehicle.flush() + +#Close vehicle object before exiting script +print "Close vehicle object" +vehicle.close() From 0affdc30e7a8ab91eb1ef7e74f74edb6607acd2d Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 16 Oct 2015 14:11:15 +1100 Subject: [PATCH 031/475] Update taking off guide for DKPY2 (b6) --- docs/guide/taking_off.rst | 43 ++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/docs/guide/taking_off.rst b/docs/guide/taking_off.rst index 0ab398ab6..d18b0db5f 100644 --- a/docs/guide/taking_off.rst +++ b/docs/guide/taking_off.rst @@ -4,8 +4,9 @@ Taking Off ========== -This article explains how to get your *Copter* to take off. At high level, the steps are: set the mode to ``GUIDED``, -arm the vehicle, and then call :py:func:`Vehicle.commands.takeoff() `. +This article explains how to get your *Copter* to take off. At high level, the steps are: check that the vehicle +is able to arm (can pass pre-arm checks), set the mode to ``GUIDED``, arm the vehicle, +and then call :py:func:`Vehicle.commands.takeoff() `. .. todo:: @@ -23,8 +24,8 @@ The code below shows a function to arm a Copter, take off, and fly to a specifie .. code-block:: python - api = local_connect() - vehicle = api.get_vehicles()[0] + # Connect to the Vehicle (in this case a simulator running the same computer) + vehicle = connect('127.0.0.1:14550', await_params=True) def arm_and_takeoff(aTargetAltitude): """ @@ -39,14 +40,14 @@ The code below shows a function to arm a Copter, take off, and fly to a specifie while vehicle.gps_0.fix_type < 2: print "Waiting for GPS...:", vehicle.gps_0.fix_type time.sleep(1) - + print "Arming motors" # Copter should arm in GUIDED mode vehicle.mode = VehicleMode("GUIDED") vehicle.armed = True vehicle.flush() - while not vehicle.armed and not api.exit: + while not vehicle.armed: print " Waiting for arming..." time.sleep(1) @@ -56,15 +57,15 @@ The code below shows a function to arm a Copter, take off, and fly to a specifie # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.commands.takeoff will execute immediately). - while not api.exit: + while True: print " Altitude: ", vehicle.location.alt if vehicle.location.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. print "Reached target altitude" break; time.sleep(1) - arm_and_takeoff(3) - + arm_and_takeoff(20) + The function first performs some pre-arm checks. @@ -90,14 +91,14 @@ to guarantee that the commands have been sent, and then wait until arming is con :py:func:`takeoff ` command. .. code-block:: python - + print "Arming motors" # Copter should arm in GUIDED mode vehicle.mode = VehicleMode("GUIDED") vehicle.armed = True vehicle.flush() - while not vehicle.armed and not api.exit: + while not vehicle.armed: print " Waiting for arming..." time.sleep(1) @@ -111,15 +112,15 @@ horizontally before it reaches a safe height. In addition, there is no message s to inform the client code that the target altitude has been reached. To address these issues, the function waits until the vehicle reaches a specified height before returning. If you're not -so concerned about reaching a particular height, a simpler implementation might just "wait" for a few seconds. - -.. code-block:: python - - while not api.exit: - print " Altitude: ", vehicle.location.alt - if vehicle.location.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. - print "Reached target altitude" - break; - time.sleep(1) +concerned about reaching a particular height, a simpler implementation might just "wait" for a few seconds. + +.. code-block:: python + + while True: + print " Altitude: ", vehicle.location.alt + if vehicle.location.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. + print "Reached target altitude" + break; + time.sleep(1) When the function returns the app can continue in ``GUIDED`` mode or switch to ``AUTO`` mode to start a mission. \ No newline at end of file From b57c5b5509b2abf3b86efb9bc26dd69f89a8f366 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 16 Oct 2015 15:05:32 +1100 Subject: [PATCH 032/475] Updates to the create_attribute example and associated guide for dkpy2. Code still has issues due to #352 --- docs/examples/create_attribute.rst | 21 +++++++------------ docs/guide/mavlink_messages.rst | 6 +++--- examples/create_attribute/create_attribute.py | 5 +++++ 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/examples/create_attribute.rst b/docs/examples/create_attribute.rst index 283b20593..3beb44a89 100644 --- a/docs/examples/create_attribute.rst +++ b/docs/examples/create_attribute.rst @@ -22,8 +22,8 @@ Additional information is provided in the guide topic :ref:`mavlink_messages`. Running the example =================== -The vehicle and DroneKit should be set up as described in :ref:`get-started`. It can be run as described in -:doc:`running_examples`. +The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle +and DroneKit have been set up as described in :ref:`get-started`). In summary, after cloning the repository: @@ -118,20 +118,18 @@ representation for printing the object. """ return "RAW_IMU: time_boot_us={},xacc={},yacc={},zacc={},xgyro={},ygyro={},zgyro={},xmag={},ymag={},zmag={}".format(self.time_boot_us, self.xacc, self.yacc,self.zacc,self.xgyro,self.ygyro,self.zgyro,self.xmag,self.ymag,self.zmag) -The script should then create an instance of the class and add it as an attribute to the vehicle object retrieved from the local connection. +The script should then create an instance of the class and add it as an attribute to the vehicle object retrieved from the connection. All values in the new attribute should be set to ``None`` so that it is obvious to users when no messages have been received. .. code:: python - # Get an instance of the API endpoint - api = local_connect() - # Get the connected vehicle (currently only one vehicle can be returned). - vehicle = api.get_vehicles()[0] + # Connect to the Vehicle passed in as args.connect + vehicle = connect(args.connect, await_params=True) #Create an Vehicle.raw_imu object and set all values to None. vehicle.raw_imu=RawIMU(None,None,None,None,None,None,None,None,None,None) -We can set a callback to intercept MAVLink messages using :py:func:`Vehicle.set_mavlink_callback() ` +We set a callback to intercept all MAVLink messages using :py:func:`Vehicle.set_mavlink_callback() ` as shown below. .. code:: python @@ -189,11 +187,8 @@ You can query the attribute to get any of the values, and even add an observer a .. note:: - It is not possible to reliably use this approach to create independent modules because: - - * Only one MAVLink callback can be set at a time in the running program (``set_mavlink_callback()``) - * There is no reliable way to import modules without adding them properly to the Python environment. - + It is not possible to reliably use this approach to create independent modules because only one + MAVLink callback can be set at a time in the running program (``set_mavlink_callback()``) Known issues diff --git a/docs/guide/mavlink_messages.rst b/docs/guide/mavlink_messages.rst index ea614d154..ec0af1e4b 100644 --- a/docs/guide/mavlink_messages.rst +++ b/docs/guide/mavlink_messages.rst @@ -7,7 +7,7 @@ MAVLink Messages Some useful MAVLink messages sent by the autopilot are not (yet) directly available to DroneKit-Python scripts through the :ref:`observable attributes ` in :py:class:`Vehicle `. -This topic shows how you can intercept MAVLink messages using +This topic shows how you can intercept all MAVLink messages using :py:func:`Vehicle.set_mavlink_callback() `. .. tip:: @@ -19,8 +19,8 @@ This topic shows how you can intercept MAVLink messages using .. _mavlink_messages_set_mavlink_callback: -Creating the message observer -============================= +Creating a message observer +=========================== The :py:func:`Vehicle.set_mavlink_callback() ` method provides asynchronous notification when any *MAVLink* packet is received from the connected vehicle. diff --git a/examples/create_attribute/create_attribute.py b/examples/create_attribute/create_attribute.py index 360396ced..0bcdd10a2 100644 --- a/examples/create_attribute/create_attribute.py +++ b/examples/create_attribute/create_attribute.py @@ -124,3 +124,8 @@ def raw_imu_callback(rawimu): #The observer can be unset using ``vehicle.unset_mavlink_callback()`` OR # ``vehicle.set_mavlink_callback(None)``. #It is automatically removed when the thread exits. + + +#Close vehicle object before exiting script +print "Close vehicle object" +vehicle.close() \ No newline at end of file From ebbf4a8a400d6aa14ccf380e8ee67c0bacee3cf5 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 16 Oct 2015 15:06:00 +1100 Subject: [PATCH 033/475] Image used by goto example docs --- .../simple_goto_example_copter_path.png | Bin 0 -> 193312 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/examples/simple_goto_example_copter_path.png diff --git a/docs/examples/simple_goto_example_copter_path.png b/docs/examples/simple_goto_example_copter_path.png new file mode 100644 index 0000000000000000000000000000000000000000..d5d3b28ded3a318ed4194c09fe48b29cdcf9025d GIT binary patch literal 193312 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℘s+ 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

H~5)+pWF3 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

Ng+VN=|?Yjuc6Qr++=JFLCy2J3U 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

yQsw&Hy7PNuD`(c- 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 Xbl-o7byG)x3p||cPTStI#$W$GZjT2R literal 0 HcmV?d00001 From 881f661b4a46d12ca0b76ba06503414415080d82 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 16 Oct 2015 15:59:48 +1100 Subject: [PATCH 034/475] Update guided-set-speed-yaw-demo with new connect and vehicle.close. Test. --- docs/examples/guided-set-speed-yaw-demo.rst | 49 ++++++++---- .../guided_set_speed_yaw.py | 78 ++++++++++--------- 2 files changed, 76 insertions(+), 51 deletions(-) diff --git a/docs/examples/guided-set-speed-yaw-demo.rst b/docs/examples/guided-set-speed-yaw-demo.rst index 7c272927d..c24cd9bc0 100644 --- a/docs/examples/guided-set-speed-yaw-demo.rst +++ b/docs/examples/guided-set-speed-yaw-demo.rst @@ -27,28 +27,48 @@ The example is :ref:`documented in the source code ` Running the example =================== -The vehicle and DroneKit should be set up as described in :ref:`get-started`. +The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle +and DroneKit have been set up as described in :ref:`get-started`). + If you're using a simulated vehicle, remember to :ref:`disable arming checks ` so that the example can run. -Once *MAVProxy* is running and the API is loaded, you can start the example by typing: ``api start guided_set_speed_yaw.py``. +In summary, after cloning the repository: -.. note:: +#. Navigate to the example folder as shown: + + .. code-block:: bash + + cd dronekit-python\examples\guided_set_speed_yaw\ - The command above assumes you started the *MAVProxy* prompt in a directory containing the example script. If not, - you will have to specify the full path to the script (e.g. on Linux): - ``api start /home/user/git/dronekit-python/examples/guided_set_speed_yaw/guided_set_speed_yaw.py``. -On the *MAVProxy* console you should see (something like): +#. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: -:: + .. code-block:: bash + + python guided_set_speed_yaw.py --connect 127.0.0.1:14550 + + .. note:: + + The examples uses the ``--connect`` parameter to pass the :ref:`connection string ` into the script. + The command above would be used to connect to :ref:`SITL ` running on the local machine via UDP port 14550. - MAV> api start /home/user/git/dronekit-python/examples/guided_set_speed_yaw/guided_set_speed_yaw.py - STABILIZE> Basic pre-arm checks + +.. tip:: + + It is more interesting to watch the example above on a map than the console. The topic :ref:`viewing_uav_on_map` + explains how to set up *Mission Planner* to view a vehicle running on the simulator (SITL). + +On the command prompt you should see (something like): + + +.. code-block:: bash + + \dronekit-python\examples\guided_set_speed_yaw>guided_set_speed_yaw.py + Basic pre-arm checks Arming motors Waiting for arming... Waiting for arming... - GUIDED> Waiting for arming... Taking off! Altitude: 0.00999999977648 Altitude: 0.159999996424 @@ -141,9 +161,8 @@ On the *MAVProxy* console you should see (something like): Yaw 90 relative (to previous yaw heading) Setting LAND mode... + Close vehicle object Completed - APIThread-0 exiting... - LAND> @@ -188,8 +207,8 @@ This takes a function argument of either :ref:`Vehicle.commands.goto() Date: Mon, 19 Oct 2015 12:12:01 +1100 Subject: [PATCH 035/475] Updates mission examples/docs/guide to DKPY2. Further testing/update required when #355 fixed --- docs/examples/mission_basic.rst | 64 ++++++++++++++----- docs/examples/mission_import_export.rst | 60 +++++++++++++---- docs/guide/auto_mode.rst | 48 ++++++-------- examples/mission_basic/mission_basic.py | 28 ++++++-- .../mission_import_export.py | 28 ++++++-- examples/mission_import_export/mpmission.txt | 9 +++ 6 files changed, 170 insertions(+), 67 deletions(-) create mode 100644 examples/mission_import_export/mpmission.txt diff --git a/docs/examples/mission_basic.rst b/docs/examples/mission_basic.rst index 9e41a0faf..60ac4e954 100644 --- a/docs/examples/mission_basic.rst +++ b/docs/examples/mission_basic.rst @@ -16,27 +16,49 @@ should be used. Running the example =================== -The vehicle and DroneKit should be set up as described in :ref:`get-started`. +The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle +and DroneKit have been set up as described in :ref:`get-started`). -If you're using a simulated vehicle remember to :ref:`disable arming checks ` so -that the example can run. +If you're using a simulated vehicle, remember to :ref:`disable arming checks ` so +that the example can run. -Once MAVProxy is running and the API is loaded, you can start the example by typing: ``api start mission_basic.py``. +In summary, after cloning the repository: -.. note:: +#. Navigate to the example folder as shown: - The command above assumes you started the *MAVProxy* prompt in a directory containing the example script. If not, - you will have to specify the full path to the script (something like): - ``api start /home/user/git/dronekit-python/examples/mission_basic/mission_basic.py``. + .. code-block:: bash + cd dronekit-python\examples\mission_basic\ + + +#. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: + + .. code-block:: bash + + python mission_basic.py --connect 127.0.0.1:14550 + + .. note:: + + The examples uses the ``--connect`` parameter to pass the :ref:`connection string ` into the script. + The command above would be used to connect to :ref:`SITL ` running on the local machine via UDP port 14550. + + +.. tip:: + + It is more interesting to watch the example above on a map than the console. The topic :ref:`viewing_uav_on_map` + explains how to set up *Mission Planner* to view a vehicle running on the simulator (SITL). + +On the command prompt you should see (something like): -On the *MAVProxy* console you should see (something like): .. code:: bash - MAV> api start mission_basic.py - STABILIZE> Clear the current mission - Got MAVLink msg: MISSION_ACK {target_system : 255, target_component : 0, type : 0} + \dronekit-python\examples\mission_basic>mission_basic.py + Connecting to vehicle on: 127.0.0.1:14550 + >>> ☺APM:Copter V3.4-dev (e0810c2e) + >>> ☺Frame: QUAD + Clear the current mission + Requesting 0 waypoints t=Wed Jul 29 21:27:58 2015 now=Wed Jul 29 21:27:58 2015 Create a new mission Got MAVLink msg: MISSION_ACK {target_system : 255, target_component : 0, type : 0} @@ -151,8 +173,18 @@ When the vehicle starts the 5th command the loop breaks and the mode is set to R Known issues ============ -This example works around the :ref:`known issues in the API `. -Provided that the vehicle is connected and able to arm, it should run through to completion. +This example fails in DroneKit 2.0.0b6 (see `#355 DKPY2 Can't clear waypoints `_). + + +.. todo:: + + This is blocked by https://github.com/dronekit/dronekit-python/issues/355 (vehicle.commands.clear not working). + The code output in "running the example needs to be updated once this runs cleanly. + The above text for the error needs to be replaced with original text + > "This example works around the :ref:`known issues in the API `. + > Provided that the vehicle is connected and able to arm, it should run through to completion." + Need to check all that clearing is still strictly necessary in DKPY2 which handles race conditions more gracefully. + Add image of waypoints /flight for top of page. @@ -162,7 +194,7 @@ Source code =========== The full source code at documentation build-time is listed below (`current version on github `_): - + .. literalinclude:: ../../examples/mission_basic/mission_basic.py :language: python - + diff --git a/docs/examples/mission_import_export.rst b/docs/examples/mission_import_export.rst index ce7371ec9..3c0ec47dc 100644 --- a/docs/examples/mission_import_export.rst +++ b/docs/examples/mission_import_export.rst @@ -21,23 +21,46 @@ missions and AUTO mode. Running the example =================== -The vehicle and DroneKit should be set up as described in :ref:`get-started`. +The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle +and DroneKit have been set up as described in :ref:`get-started`). -Once MAVProxy is running and the API is loaded, you can start the example by typing: ``api start mission_import_export.py``. +If you're using a simulated vehicle, remember to :ref:`disable arming checks ` so +that the example can run. -.. note:: +In summary, after cloning the repository: - The command above assumes you started the *MAVProxy* prompt in a directory containing the example script. If not, - you will have to specify the absolute path to the script. For example: - ``api start /home/user/git/dronekit-python/examples/mission_import_export/mission_import_export.py``. +#. Navigate to the example folder as shown: + .. code-block:: bash + + cd dronekit-python\examples\mission_import_export\ + + +#. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: + + .. code-block:: bash + + python mission_import_export.py --connect 127.0.0.1:14550 + + .. note:: + + The examples uses the ``--connect`` parameter to pass the :ref:`connection string ` into the script. + The command above would be used to connect to :ref:`SITL ` running on the local machine via UDP port 14550. + + + +On the command prompt you should see (something like): -On the *MAVProxy* console you should see (something like): .. code:: bash - STABILIZE> api start mission_import_export.py - STABILIZE> + \dronekit-python\examples\mission_import_export>mission_import_export.py + + Connecting to vehicle on: 127.0.0.1:14550 + >>> ☺APM:Copter V3.4-dev (e0810c2e) + >>> ☺Frame: QUAD + Link timeout, no heartbeat in last 5 seconds + Upload mission from a file: mpmission.txt Reading mission from file: mpmission.txt @@ -95,14 +118,27 @@ More information about the functions can be found in the guide at Known issues ============ -This example works around known issues in the API: + +* This example fails in DroneKit 2.0.0b6 (see `#355 DKPY2 Can't clear waypoints `_). * A ``time.sleep(1)`` has been placed between uploading the mission to the vehicle (from the file) and downloading the mission. This is to avoid the race condition where the mission being downloaded has not yet successfully uploaded to the vehicle. This race condition (probably) shouldn't exist because the mission is flushed to the Vehicle - see `Race condition when updating and fetching commands `_ + +.. todo:: + + This is blocked by https://github.com/dronekit/dronekit-python/issues/355 (vehicle.commands.clear not working). + The code output in "running the example"" needs to be updated once this runs cleanly. + The above text for the error needs to be replaced with original text + > "This example works around known issues in the API:." + Need to check all that clearing is still strictly necessary in DKPY2 which handles race conditions more gracefully. + + + + .. _example_mission_import_export_source_code: @@ -110,7 +146,7 @@ Source code =========== The full source code at documentation build-time is listed below (`current version on github `_): - + .. literalinclude:: ../../examples/mission_import_export/mission_import_export.py :language: python - + diff --git a/docs/guide/auto_mode.rst b/docs/guide/auto_mode.rst index 65decadd9..1dceb29b1 100644 --- a/docs/guide/auto_mode.rst +++ b/docs/guide/auto_mode.rst @@ -70,9 +70,8 @@ use :py:func:`wait_valid() ` to block y .. code:: python - # Connect to API provider and get vehicle - api = local_connect() - vehicle = api.get_vehicles()[0] + # Connect to the Vehicle (in this case a simulated vehicle at 127.0.0.1:14550) + vehicle = connect('127.0.0.1:14550', await_params=True) # Download the vehicle waypoints (commands). Wait until download is complete. cmds = vehicle.commands @@ -100,9 +99,10 @@ To clear a mission you call :py:func:`clear() ` objects. @@ -367,7 +361,7 @@ Save a mission to a file It uses ``download_mission()`` (below) to get them mission, and then writes the list line-by-line to the file. .. code:: python - + def save_mission(aFileName): """ Save a mission in the Waypoint file format (http://qgroundcontrol.org/mavlink/waypoint_protocol#waypoint_file_format). diff --git a/examples/mission_basic/mission_basic.py b/examples/mission_basic/mission_basic.py index e31700c1c..65aa105a7 100644 --- a/examples/mission_basic/mission_basic.py +++ b/examples/mission_basic/mission_basic.py @@ -4,14 +4,24 @@ Full documentation is provided at http://python.dronekit.io/examples/mission_basic.html """ +from dronekit import connect import time import math from dronekit.lib import VehicleMode, Location, Command from pymavlink import mavutil -# Connect to API provider and get vehicle -api = local_connect() -vehicle = api.get_vehicles()[0] + +#Set up option parsing to get connection string +import argparse +parser = argparse.ArgumentParser(description='Print out vehicle state information. Connects to SITL on local PC by default.') +parser.add_argument('--connect', default='127.0.0.1:14550', + help="vehicle connection target. Default '127.0.0.1:14550'") +args = parser.parse_args() + + +# Connect to the Vehicle +print 'Connecting to vehicle on: %s' % args.connect +vehicle = connect(args.connect, await_params=True) def get_location_metres(original_location, dNorth, dEast): @@ -130,6 +140,9 @@ def arm_and_takeoff(aTargetAltitude): if vehicle.mode.name == "INITIALISING": print "Waiting for vehicle to initialise" time.sleep(1) + else: + print "MODE: %s" % vehicle.mode.name + while vehicle.gps_0.fix_type < 2: print "Waiting for GPS...:", vehicle.gps_0.fix_type time.sleep(1) @@ -140,7 +153,7 @@ def arm_and_takeoff(aTargetAltitude): vehicle.armed = True vehicle.flush() - while not vehicle.armed and not api.exit: + while not vehicle.armed: print " Waiting for arming..." time.sleep(1) @@ -150,7 +163,7 @@ def arm_and_takeoff(aTargetAltitude): # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.commands.takeoff will execute immediately). - while not api.exit: + while True: print " Altitude: ", vehicle.location.alt if vehicle.location.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. print "Reached target altitude" @@ -158,6 +171,7 @@ def arm_and_takeoff(aTargetAltitude): time.sleep(1) + print 'Clear the current mission' clear_mission() @@ -195,4 +209,8 @@ def arm_and_takeoff(aTargetAltitude): vehicle.mode = VehicleMode("RTL") vehicle.flush() # Flush to ensure changes are sent to autopilot +#Close vehicle object before exiting script +print "Close vehicle object" +vehicle.close() + diff --git a/examples/mission_import_export/mission_import_export.py b/examples/mission_import_export/mission_import_export.py index 35d8b8519..331b210a5 100644 --- a/examples/mission_import_export/mission_import_export.py +++ b/examples/mission_import_export/mission_import_export.py @@ -8,14 +8,25 @@ Documentation is provided at http://python.dronekit.io/examples/mission_import_export.html """ + +from dronekit import connect import time import math from dronekit.lib import Command from pymavlink import mavutil -# Connect to API provider and get vehicle -api = local_connect() -vehicle = api.get_vehicles()[0] + +#Set up option parsing to get connection string +import argparse +parser = argparse.ArgumentParser(description='Print out vehicle state information. Connects to SITL on local PC by default.') +parser.add_argument('--connect', default='127.0.0.1:14550', + help="vehicle connection target. Default '127.0.0.1:14550'") +args = parser.parse_args() + + +# Connect to the Vehicle +print 'Connecting to vehicle on: %s' % args.connect +vehicle = connect(args.connect, await_params=True) def readmission(aFileName): @@ -46,8 +57,8 @@ def readmission(aFileName): ln_param4=float(linearray[7]) ln_param5=float(linearray[8]) ln_param6=float(linearray[9]) - ln_param7=float(linearray[10]) - ln_autocontinue=int(linearray[11].strip()) + ln_param7=float(linearray[10]) + ln_autocontinue=int(linearray[11].strip()) cmd = Command( 0, 0, 0, ln_frame, ln_command, ln_currentwp, ln_autocontinue, ln_param1, ln_param2, ln_param3, ln_param4, ln_param5, ln_param6, ln_param7) missionlist.append(cmd) return missionlist @@ -71,7 +82,7 @@ def upload_mission(aFileName): cmds.wait_valid() for command in missionlist: cmds.add(command) - vehicle.flush() + vehicle.flush() def download_mission(): @@ -103,7 +114,7 @@ def save_mission(aFileName): import_mission_filename = 'mpmission.txt' export_mission_filename = 'exportedmission.txt' -print "\nUpload mission from a file: %s" % import_mission_filename +print "\nUpload mission from a file: %s" % import_mission_filename upload_mission(import_mission_filename) time.sleep(1) @@ -111,3 +122,6 @@ def save_mission(aFileName): print "\nSave mission from Vehicle to file: %s" % export_mission_filename save_mission(export_mission_filename) +#Close vehicle object before exiting script +print "Close vehicle object" +vehicle.close() \ No newline at end of file diff --git a/examples/mission_import_export/mpmission.txt b/examples/mission_import_export/mpmission.txt new file mode 100644 index 000000000..bd331abdd --- /dev/null +++ b/examples/mission_import_export/mpmission.txt @@ -0,0 +1,9 @@ +QGC WPL 110 +0 1 0 16 0 0 0 0 -35.360500 149.172363 747.000000 1 +1 0 3 22 0.000000 0.000000 0.000000 0.000000 -35.359831 149.166334 100.000000 1 +2 0 3 16 0.000000 0.000000 0.000000 0.000000 -35.363489 149.167213 100.000000 1 +3 0 3 16 0.000000 0.000000 0.000000 0.000000 -35.355491 149.169595 100.000000 1 +4 0 3 16 0.000000 0.000000 0.000000 0.000000 -35.355071 149.175839 100.000000 1 +5 0 3 113 0.000000 0.000000 0.000000 0.000000 -35.362666 149.178715 22222.000000 1 +6 0 3 115 2.000000 22.000000 1.000000 3.000000 0.000000 0.000000 0.000000 1 +7 0 3 16 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1 From 89062ffe03f84d8faf47d6c4dab00c7421b2a1b3 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 21 Oct 2015 12:28:50 +1100 Subject: [PATCH 036/475] Fix help description for examples --- examples/mission_basic/mission_basic.py | 2 +- examples/mission_import_export/mission_import_export.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/mission_basic/mission_basic.py b/examples/mission_basic/mission_basic.py index 65aa105a7..c644ef555 100644 --- a/examples/mission_basic/mission_basic.py +++ b/examples/mission_basic/mission_basic.py @@ -13,7 +13,7 @@ #Set up option parsing to get connection string import argparse -parser = argparse.ArgumentParser(description='Print out vehicle state information. Connects to SITL on local PC by default.') +parser = argparse.ArgumentParser(description='Example which runs basic mission operations. Connects to SITL on local PC by default.') parser.add_argument('--connect', default='127.0.0.1:14550', help="vehicle connection target. Default '127.0.0.1:14550'") args = parser.parse_args() diff --git a/examples/mission_import_export/mission_import_export.py b/examples/mission_import_export/mission_import_export.py index 331b210a5..dd22fe2cc 100644 --- a/examples/mission_import_export/mission_import_export.py +++ b/examples/mission_import_export/mission_import_export.py @@ -18,7 +18,7 @@ #Set up option parsing to get connection string import argparse -parser = argparse.ArgumentParser(description='Print out vehicle state information. Connects to SITL on local PC by default.') +parser = argparse.ArgumentParser(description='Example that demonstrates mission import/export from a file. Connects to SITL on local PC by default.') parser.add_argument('--connect', default='127.0.0.1:14550', help="vehicle connection target. Default '127.0.0.1:14550'") args = parser.parse_args() From b030927c4c9818f4b83f16dd6bdb5892e5895753 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 21 Oct 2015 16:08:27 +1100 Subject: [PATCH 037/475] Improvements to wording around connection defaults. Add warnings to mission examples because bugs not yet fixed --- docs/examples/create_attribute.rst | 4 +-- docs/examples/guided-set-speed-yaw-demo.rst | 28 ++++++++++----------- docs/examples/mission_basic.rst | 16 +++++++++--- docs/examples/mission_import_export.rst | 13 ++++++++-- docs/examples/simple_goto.rst | 4 +-- 5 files changed, 41 insertions(+), 24 deletions(-) diff --git a/docs/examples/create_attribute.rst b/docs/examples/create_attribute.rst index 3beb44a89..91657a2b0 100644 --- a/docs/examples/create_attribute.rst +++ b/docs/examples/create_attribute.rst @@ -42,8 +42,8 @@ In summary, after cloning the repository: .. note:: - The examples uses the ``--connect`` parameter to pass the :ref:`connection string ` into the script. - The command above would be used to connect to :ref:`SITL ` running on the local machine via UDP port 14550. + The command parameter above is the default, and may be omitted. This + connects to SITL on udp port 127.0.0.1:14550. diff --git a/docs/examples/guided-set-speed-yaw-demo.rst b/docs/examples/guided-set-speed-yaw-demo.rst index c24cd9bc0..9ef950cdb 100644 --- a/docs/examples/guided-set-speed-yaw-demo.rst +++ b/docs/examples/guided-set-speed-yaw-demo.rst @@ -50,8 +50,8 @@ In summary, after cloning the repository: .. note:: - The examples uses the ``--connect`` parameter to pass the :ref:`connection string ` into the script. - The command above would be used to connect to :ref:`SITL ` running on the local machine via UDP port 14550. + The command parameter above is the default, and may be omitted. This + connects to SITL on udp port 127.0.0.1:14550. .. tip:: @@ -252,10 +252,10 @@ which is used to directly specify the speed components of the vehicle. The funct 0, # lat_int - X Position in WGS84 frame in 1e7 * meters 0, # lon_int - Y Position in WGS84 frame in 1e7 * meters 0, # alt - Altitude in meters in AMSL altitude(not WGS84 if absolute or relative) - # altitude above terrain if GLOBAL_TERRAIN_ALT_INT + # altitude above terrain if GLOBAL_TERRAIN_ALT_INT velocity_x, # X velocity in NED frame in m/s - velocity_y, # Y velocity in NED frame in m/s - velocity_z, # Z velocity in NED frame in m/s + velocity_y, # Y velocity in NED frame in m/s + velocity_z, # Z velocity in NED frame in m/s 0, 0, 0, # afx, afy, afz acceleration (not supported yet, ignored in GCS_Mavlink) 0, 0) # yaw, yaw_rate (not supported yet, ignored in GCS_Mavlink) # send command to vehicle @@ -263,7 +263,7 @@ which is used to directly specify the speed components of the vehicle. The funct vehicle.flush() - + .. _example_guided_mode_goto_position_target_global_int: goto_position_target_global_int() @@ -271,13 +271,13 @@ goto_position_target_global_int() The function ``goto_position_target_global_int()`` generates a `SET_POSITION_TARGET_GLOBAL_INT `_ MAVLink message which is used to directly specify the target location of the vehicle. When used with ``MAV_FRAME_GLOBAL_RELATIVE_ALT_INT`` as shown below, this method is effectively the same as :ref:`Vehicle.commands.goto `. - + .. code-block:: python def goto_position_target_global_int(aLocation): """ Send SET_POSITION_TARGET_GLOBAL_INT command to request the vehicle fly to a specified location. - """ + """ msg = vehicle.message_factory.set_position_target_global_int_encode( 0, # time_boot_ms (not used) 0, 0, # target system, target component @@ -287,8 +287,8 @@ which is used to directly specify the target location of the vehicle. When used aLocation.lon*1e7, # lon_int - Y Position in WGS84 frame in 1e7 * meters aLocation.alt, # alt - Altitude in meters in AMSL altitude, not WGS84 if absolute or relative, above terrain if GLOBAL_TERRAIN_ALT_INT 0, # X velocity in NED frame in m/s - 0, # Y velocity in NED frame in m/s - 0, # Z velocity in NED frame in m/s + 0, # Y velocity in NED frame in m/s + 0, # Z velocity in NED frame in m/s 0, 0, 0, # afx, afy, afz acceleration (not supported yet, ignored in GCS_Mavlink) 0, 0) # yaw, yaw_rate (not supported yet, ignored in GCS_Mavlink) # send command to vehicle @@ -317,13 +317,13 @@ which is used to directly specify the target location in the North, East, Down f The `documentation `_ lists a number of possible frames of reference. At time of writing experimentation indicates that the actual frame use is always relative to the home location (not the vehicle, as indicated by MAV_FRAME_BODY_NED). -.. code-block:: python +.. code-block:: python def goto_position_target_local_ned(north, east, down): - """ + """ Send SET_POSITION_TARGET_LOCAL_NED command to request the vehicle fly to a specified location in the North, East, Down frame. - """ + """ msg = vehicle.message_factory.set_position_target_local_ned_encode( 0, # time_boot_ms (not used) 0, 0, # target system, target component @@ -336,7 +336,7 @@ which is used to directly specify the target location in the North, East, Down f # send command to vehicle vehicle.send_mavlink(msg) vehicle.flush() - + At time of writing, acceleration and yaw bits are ignored. diff --git a/docs/examples/mission_basic.rst b/docs/examples/mission_basic.rst index 60ac4e954..b396715f4 100644 --- a/docs/examples/mission_basic.rst +++ b/docs/examples/mission_basic.rst @@ -12,13 +12,21 @@ command. The guide topic :ref:`auto_mode_vehicle_control` provides more detailed explanation of how the API should be used. +.. warning:: + + At time of writing this example fails with an exception in DKYP2: `#355 DKPY2 Can't clear waypoints `_. + +.. todo:: + + Check if `#355 DKPY2 Can't clear waypoints `_ is fixed and re-review example. + Running the example =================== The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle and DroneKit have been set up as described in :ref:`get-started`). - + If you're using a simulated vehicle, remember to :ref:`disable arming checks ` so that the example can run. @@ -39,8 +47,8 @@ In summary, after cloning the repository: .. note:: - The examples uses the ``--connect`` parameter to pass the :ref:`connection string ` into the script. - The command above would be used to connect to :ref:`SITL ` running on the local machine via UDP port 14550. + The command parameter above is the default, and may be omitted. This + connects to SITL on udp port 127.0.0.1:14550. .. tip:: @@ -48,8 +56,8 @@ In summary, after cloning the repository: It is more interesting to watch the example above on a map than the console. The topic :ref:`viewing_uav_on_map` explains how to set up *Mission Planner* to view a vehicle running on the simulator (SITL). -On the command prompt you should see (something like): +On the command prompt you should see (something like): .. code:: bash diff --git a/docs/examples/mission_import_export.rst b/docs/examples/mission_import_export.rst index 3c0ec47dc..f52828508 100644 --- a/docs/examples/mission_import_export.rst +++ b/docs/examples/mission_import_export.rst @@ -7,6 +7,14 @@ Example: Mission Import/Export This example shows how to import and export files in the `Waypoint file format `_. +.. warning:: + + At time of writing this example fails with an exception in DKYP2: `#355 DKPY2 Can't clear waypoints `_. + +.. todo:: + + Check if `#355 DKPY2 Can't clear waypoints `_ is fixed and re-review example. + The commands are first imported from a file into a list and then uploaded to the vehicle. Then the current mission is downloaded from the vehicle and put into a list, and finally saved into (another file). @@ -42,10 +50,11 @@ In summary, after cloning the repository: python mission_import_export.py --connect 127.0.0.1:14550 + .. note:: - The examples uses the ``--connect`` parameter to pass the :ref:`connection string ` into the script. - The command above would be used to connect to :ref:`SITL ` running on the local machine via UDP port 14550. + The command parameter above is the default, and may be omitted. This + connects to SITL on udp port 127.0.0.1:14550. diff --git a/docs/examples/simple_goto.rst b/docs/examples/simple_goto.rst index a65474bb2..1b21b33b9 100644 --- a/docs/examples/simple_goto.rst +++ b/docs/examples/simple_goto.rst @@ -53,8 +53,8 @@ In summary, after cloning the repository: .. note:: - The examples uses the ``--connect`` parameter to pass the :ref:`connection string ` into the script. - The command above would be used to connect to :ref:`SITL ` running on the local machine via UDP port 14550. + The command parameter above is the default, and may be omitted. This + connects to SITL on udp port 127.0.0.1:14550. .. tip:: From 7372c1fc1c5c46689b15043309cee97887c19d3d Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 22 Oct 2015 16:27:13 +1100 Subject: [PATCH 038/475] Fixes in response to @tcr3dr comments --- docs/examples/guided-set-speed-yaw-demo.rst | 3 +-- docs/examples/mission_basic.rst | 9 ++++----- docs/examples/mission_import_export.rst | 13 +++++-------- docs/examples/simple_goto.rst | 11 +++++------ docs/guide/taking_off.rst | 4 ++-- examples/simple_goto/simple_goto.py | 2 +- 6 files changed, 18 insertions(+), 24 deletions(-) diff --git a/docs/examples/guided-set-speed-yaw-demo.rst b/docs/examples/guided-set-speed-yaw-demo.rst index 9ef950cdb..044cd69cc 100644 --- a/docs/examples/guided-set-speed-yaw-demo.rst +++ b/docs/examples/guided-set-speed-yaw-demo.rst @@ -39,7 +39,7 @@ In summary, after cloning the repository: .. code-block:: bash - cd dronekit-python\examples\guided_set_speed_yaw\ + cd dronekit-python/examples/guided_set_speed_yaw/ #. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: @@ -64,7 +64,6 @@ On the command prompt you should see (something like): .. code-block:: bash - \dronekit-python\examples\guided_set_speed_yaw>guided_set_speed_yaw.py Basic pre-arm checks Arming motors Waiting for arming... diff --git a/docs/examples/mission_basic.rst b/docs/examples/mission_basic.rst index b396715f4..81293d69e 100644 --- a/docs/examples/mission_basic.rst +++ b/docs/examples/mission_basic.rst @@ -36,7 +36,7 @@ In summary, after cloning the repository: .. code-block:: bash - cd dronekit-python\examples\mission_basic\ + cd dronekit-python/examples/mission_basic/ #. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: @@ -61,10 +61,9 @@ On the command prompt you should see (something like): .. code:: bash - \dronekit-python\examples\mission_basic>mission_basic.py Connecting to vehicle on: 127.0.0.1:14550 - >>> ☺APM:Copter V3.4-dev (e0810c2e) - >>> ☺Frame: QUAD + >>> APM:Copter V3.4-dev (e0810c2e) + >>> Frame: QUAD Clear the current mission Requesting 0 waypoints t=Wed Jul 29 21:27:58 2015 now=Wed Jul 29 21:27:58 2015 @@ -181,7 +180,7 @@ When the vehicle starts the 5th command the loop breaks and the mode is set to R Known issues ============ -This example fails in DroneKit 2.0.0b6 (see `#355 DKPY2 Can't clear waypoints `_). +This example fails in DroneKit 2.0.0b6 and earlier releases (see `#355 DKPY2 Can't clear waypoints `_ to see if it has been fixed in the current release). .. todo:: diff --git a/docs/examples/mission_import_export.rst b/docs/examples/mission_import_export.rst index f52828508..f8252d4a6 100644 --- a/docs/examples/mission_import_export.rst +++ b/docs/examples/mission_import_export.rst @@ -41,7 +41,7 @@ In summary, after cloning the repository: .. code-block:: bash - cd dronekit-python\examples\mission_import_export\ + cd dronekit-python/examples/mission_import_export/ #. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: @@ -63,11 +63,9 @@ On the command prompt you should see (something like): .. code:: bash - \dronekit-python\examples\mission_import_export>mission_import_export.py - Connecting to vehicle on: 127.0.0.1:14550 - >>> ☺APM:Copter V3.4-dev (e0810c2e) - >>> ☺Frame: QUAD + >>> APM:Copter V3.4-dev (e0810c2e) + >>> Frame: QUAD Link timeout, no heartbeat in last 5 seconds Upload mission from a file: mpmission.txt @@ -127,9 +125,8 @@ More information about the functions can be found in the guide at Known issues ============ - - -* This example fails in DroneKit 2.0.0b6 (see `#355 DKPY2 Can't clear waypoints `_). +* This example fails in DroneKit 2.0.0b6 and earlier + (see `#355 DKPY2 Can't clear waypoints `_ to see if it has been fixed). * A ``time.sleep(1)`` has been placed between uploading the mission to the vehicle (from the file) and downloading the mission. This is to avoid the race condition where the mission being downloaded has not yet successfully uploaded to the vehicle. This race condition (probably) shouldn't exist because the mission is flushed to the Vehicle - diff --git a/docs/examples/simple_goto.rst b/docs/examples/simple_goto.rst index 1b21b33b9..c300bd7bf 100644 --- a/docs/examples/simple_goto.rst +++ b/docs/examples/simple_goto.rst @@ -42,7 +42,7 @@ In summary, after cloning the repository: .. code-block:: bash - cd dronekit-python\examples\simple_goto\ + cd dronekit-python/examples/simple_goto/ #. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: @@ -66,18 +66,17 @@ On the command prompt you should see (something like): .. code-block:: bash - \dronekit-python\examples\simple_goto>simple_goto.py Connecting to vehicle on: 127.0.0.1:14550 - >>> ☺APM:Copter V3.4-dev (e0810c2e) - >>> ☺Frame: QUAD + >>> APM:Copter V3.4-dev (e0810c2e) + >>> Frame: QUAD Basic pre-arm checks Waiting for GPS...: None ... Waiting for GPS...: None Arming motors Waiting for arming... - >>> ☺ARMING MOTORS - >>> ☺Initialising APM... + >>> ARMING MOTORS + >>> Initialising APM... Taking off! Altitude: 0.0 Altitude: 0.00999999977648 diff --git a/docs/guide/taking_off.rst b/docs/guide/taking_off.rst index d18b0db5f..fda18b3b7 100644 --- a/docs/guide/taking_off.rst +++ b/docs/guide/taking_off.rst @@ -61,7 +61,7 @@ The code below shows a function to arm a Copter, take off, and fly to a specifie print " Altitude: ", vehicle.location.alt if vehicle.location.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. print "Reached target altitude" - break; + break time.sleep(1) arm_and_takeoff(20) @@ -120,7 +120,7 @@ concerned about reaching a particular height, a simpler implementation might jus print " Altitude: ", vehicle.location.alt if vehicle.location.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. print "Reached target altitude" - break; + break time.sleep(1) When the function returns the app can continue in ``GUIDED`` mode or switch to ``AUTO`` mode to start a mission. \ No newline at end of file diff --git a/examples/simple_goto/simple_goto.py b/examples/simple_goto/simple_goto.py index f958ad1de..53f9d0d0e 100644 --- a/examples/simple_goto/simple_goto.py +++ b/examples/simple_goto/simple_goto.py @@ -60,7 +60,7 @@ def arm_and_takeoff(aTargetAltitude): print " Altitude: ", vehicle.location.alt if vehicle.location.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. print "Reached target altitude" - break; + break time.sleep(1) arm_and_takeoff(20) From d2a0d22328bf7a843098eb29d9d4d92242c4cc3d Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 20 Oct 2015 12:21:25 +1100 Subject: [PATCH 039/475] follow me example updates for dkpy2 --- docs/examples/follow_me.rst | 156 ++++++++++++++++++++++++++++---- examples/follow_me/follow_me.py | 156 ++++++++++++++++++++------------ 2 files changed, 236 insertions(+), 76 deletions(-) diff --git a/docs/examples/follow_me.rst b/docs/examples/follow_me.rst index e9691a279..ab7ed6ccc 100644 --- a/docs/examples/follow_me.rst +++ b/docs/examples/follow_me.rst @@ -4,39 +4,155 @@ Example: Follow Me ================== -This is a significantly more complex example – showing closed-loop control of the vehicle. It will use a USB GPS attached to your laptop to have the vehicle follow you as you walk around a field. +The *Follow Me* example moves a vehicle to track your position, using location information from a USB GPS attached to your (Linux) laptop. -Run this example with caution - be ready to exit follow-me mode by switching the flight mode switch on your RC radio. +The source code is a good *starting point* for your own applications. It can be extended to use other +python language features and libraries (OpenCV, classes, lots of packages etc...) -In practice, you don't really want to use this follow-me implementation, rather you can use this example as a starting point to build your own custom application. -Before running this demo you'll need to make sure your computer has the gpsd service installed. +.. note:: This example can only run on a Linux computer, because it depends on the Linux-only *gpsd* service. + +.. warning:: Run this example with caution - be ready to exit follow-me mode by switching the flight mode switch on your RC radio. -*Ubuntu install* -.. code-block:: bash +Running the example +=================== - apt-get install gpsd gpsd-clients +DroneKit (for Linux) and the vehicle should be set up as described in :ref:`get-started`. -You can then plug in a USB GPS and run the "xgps" client to confirm that it is working. If you do not have a USB GPS you can use simulated data by running *dronekit-python/examples/run-fake-gps.sh*. +Once you've done that: -Once your GPS is plugged in you can start follow-me by running the following command inside of MAVProxy: +#. Install the *gpsd* service (as shown for Ubuntu Linux below): -.. code-block:: bash + .. code-block:: bash + + sudo apt-get install gpsd gpsd-clients + + You can then plug in a USB GPS and run the "xgps" client to confirm that it is working. + + .. note:: + + If you do not have a USB GPS you can use simulated data by running *dronekit-python/examples/follow_me/run-fake-gps.sh* + (in a separate terminal from where you're running DroneKit-Python). This approach simulates a single location, and so + is really only useful for verifying that the script is working correctly. + + +#. Get the DroneKit-Python example source code onto your local machine. The easiest way to do this + is to clone the **dronekit-python** repository from Github. On the command prompt enter: + + .. code-block:: bash + + git clone http://github.com/dronekit/dronekit-python.git + +#. Navigate to the example folder as shown: + + .. code-block:: bash - RTL> api start follow_me.py - RTL> Going to: Location:lat=50.616468333,lon=7.131903333,alt=30,is_relative=True - Got MAVLink msg: MISSION_ACK {target_system : 255, target_component : 0, type : 0} - GUIDED> Mode GUIDED - Going to: Location:lat=50.616468333,lon=7.131903333,alt=30,is_relative=True - Got MAVLink msg: MISSION_ACK {target_system : 255, target_component : 0, type : 0} - ... + cd dronekit-python\examples\follow_me\ -These debugging messages will appear every two seconds - when a new target position is sent to the vehicle, to stop follow-me either change the vehicle mode switch on your RC transmitter or type "api stop". -The source code for this example is a good starting point for your own application, from here you can use all python language features and libraries (OpenCV, classes, lots of packages etc...) +#. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: + + .. code-block:: bash + + python follow_me.py --connect 127.0.0.1:14550 + + + .. note:: + + The examples uses the ``--connect`` parameter to pass the :ref:`connection string ` into the script. + The command above is used to connect to :ref:`SITL ` running on the local Linux machine via UDP port 14550. + + +On the terminal you should see (something like): + + +.. code-block:: bash + + dronekit-python/examples/follow_me$ python follow_me.py --connect 127.0.0.1:14550 + + Connecting to vehicle on: 127.0.0.1:14550 + >>> APM:Copter V3.4-dev (e0810c2e) + >>> Frame: QUAD + Link timeout, no heartbeat in last 5 seconds + Basic pre-arm checks + Waiting for GPS...: None + ... + Waiting for GPS...: None + Taking off! + Altitude: 0.019999999553 + ... + Altitude: 4.76000022888 + Reached target altitude + Going to: Location:lat=50.616468333,lon=7.131903333,alt=30,is_relative=True + ... + Going to: Location:lat=50.616468333,lon=7.131903333,alt=30,is_relative=True + Going to: Location:lat=50.616468333,lon=7.131903333,alt=30,is_relative=True + User has changed flight modes - aborting follow-me + Close vehicle object + Completed + + +To stop follow-me you can change the vehicle mode (on a real flight you can just change the mode switch on your RC transmitter). + +.. note:: + + The terminal output above was created using simulated GPS data + (which is why the same target location is returned every time). It was exited by changing + the mode from GUIDED to STABILIZE using MAVProxy. + + + +How does it work? +================= + +Most of the example should be fairly familiar as it uses the same code as other examples for connecting to the vehicle, +:ref:`taking off `, and closing the vehicle object. + +The example-specific code is shown below. All this does is attempt to get a gps socket and read the location in a two second loop. If it is successful it +reports the value and uses :py:func:`Vehicle.commands.goto ` to move to the new position. The loop exits when +the mode is changed. + +.. code-block:: python + + import gps + import socket + + ... + + try: + # Use the python gps package to access the laptop GPS + gpsd = gps.gps(mode=gps.WATCH_ENABLE) + + #Arm and take of to altitude of 5 meters + arm_and_takeoff(5) + + while True: + + if vehicle.mode.name != "GUIDED": + print "User has changed flight modes - aborting follow-me" + break + + # Read the GPS state from the laptop + gpsd.next() + + # Once we have a valid location (see gpsd documentation) we can start moving our vehicle around + if (gpsd.valid & gps.LATLON_SET) != 0: + altitude = 30 # in meters + dest = Location(gpsd.fix.latitude, gpsd.fix.longitude, altitude, is_relative=True) + print "Going to: %s" % dest + + # A better implementation would only send new waypoints if the position had changed significantly + vehicle.commands.goto(dest) + vehicle.flush() + + # Send a new target every two seconds + # For a complete implementation of follow me you'd want adjust this delay + time.sleep(2) + + except socket.error: + print "Error: gpsd service does not seem to be running, plug in USB GPS or run run-fake-gps.sh" -Next, take a look at the full :ref:`api_reference` for more information. Source code diff --git a/examples/follow_me/follow_me.py b/examples/follow_me/follow_me.py index 8dd2b51be..4807db102 100644 --- a/examples/follow_me/follow_me.py +++ b/examples/follow_me/follow_me.py @@ -1,65 +1,109 @@ +""" +followme - Tracks GPS position of your computer (Linux only). + +This example uses the python gps package to read positions from a GPS attached to your +laptop and sends a new vehicle.commands.goto command every two seconds to move the +vehicle to the current point. + +When you want to stop follow-me, either change vehicle modes or type Ctrl+C to exit the script. + +Example documentation: http://python.dronekit.io/examples/follow_me.html +""" + +from dronekit import connect import gps import socket import time from dronekit.lib import VehicleMode, Location -def followme(): - """ - followme - A DroneAPI example +#Set up option parsing to get connection string +import argparse +parser = argparse.ArgumentParser(description='Print out vehicle state information. Connects to SITL on local PC by default.') +parser.add_argument('--connect', default='127.0.0.1:14550', + help="vehicle connection target. Default '127.0.0.1:14550'") +args = parser.parse_args() + - This is a somewhat more 'meaty' example on how to use the DroneAPI. It uses the - python gps package to read positions from the GPS attached to your laptop an - every two seconds it sends a new goto command to the vehicle. +# Connect to the Vehicle +print 'Connecting to vehicle on: %s' % args.connect +vehicle = connect(args.connect, await_params=True) - To use this example: - * Run mavproxy.py with the correct options to connect to your vehicle - * module load api - * api start - When you want to stop follow-me, either change vehicle modes from your RC - transmitter or type "api stop". + +def arm_and_takeoff(aTargetAltitude): + """ + Arm vehicle and fly to aTargetAltitude. """ - try: - # First get an instance of the API endpoint (the connect via web case will be similar) - api = local_connect() - - # Now get our vehicle (we assume the user is trying to control the first vehicle attached to the GCS) - v = api.get_vehicles()[0] - - # Don't let the user try to fly while the board is still booting - if v.mode.name == "INITIALISING": - print "Vehicle still booting, try again later" - return - - cmds = v.commands - is_guided = False # Have we sent at least one destination point? - - # Use the python gps package to access the laptop GPS - gpsd = gps.gps(mode=gps.WATCH_ENABLE) - - while not api.exit: - # This is necessary to read the GPS state from the laptop - gpsd.next() - - if is_guided and v.mode.name != "GUIDED": - print "User has changed flight modes - aborting follow-me" - break - - # Once we have a valid location (see gpsd documentation) we can start moving our vehicle around - if (gpsd.valid & gps.LATLON_SET) != 0: - altitude = 30 # in meters - dest = Location(gpsd.fix.latitude, gpsd.fix.longitude, altitude, is_relative=True) - print "Going to: %s" % dest - - # A better implementation would only send new waypoints if the position had changed significantly - cmds.goto(dest) - is_guided = True - v.flush() - - # Send a new target every two seconds - # For a complete implementation of follow me you'd want adjust this delay - time.sleep(2) - except socket.error: - print "Error: gpsd service does not seem to be running, plug in USB GPS or run run-fake-gps.sh" - -followme() + print "Basic pre-arm checks" + # Don't let the user try to fly while autopilot is booting + if vehicle.mode.name == "INITIALISING": + print "Waiting for vehicle to initialise" + time.sleep(1) + while vehicle.gps_0.fix_type < 2: + print "Waiting for GPS...:", vehicle.gps_0.fix_type + time.sleep(1) + + print "Arming motors" + # Copter should arm in GUIDED mode + vehicle.mode = VehicleMode("GUIDED") + vehicle.armed = True + vehicle.flush() + + while not vehicle.armed: + print " Waiting for arming..." + time.sleep(1) + + print "Taking off!" + vehicle.commands.takeoff(aTargetAltitude) # Take off to target altitude + vehicle.flush() + + # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command + # after Vehicle.commands.takeoff will execute immediately). + while True: + print " Altitude: ", vehicle.location.alt + if vehicle.location.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. + print "Reached target altitude" + break; + time.sleep(1) + + + +try: + # Use the python gps package to access the laptop GPS + gpsd = gps.gps(mode=gps.WATCH_ENABLE) + + #Arm and take of to altitude of 5 meters + arm_and_takeoff(5) + + while True: + + if vehicle.mode.name != "GUIDED": + print "User has changed flight modes - aborting follow-me" + break + + # Read the GPS state from the laptop + gpsd.next() + + # Once we have a valid location (see gpsd documentation) we can start moving our vehicle around + if (gpsd.valid & gps.LATLON_SET) != 0: + altitude = 30 # in meters + dest = Location(gpsd.fix.latitude, gpsd.fix.longitude, altitude, is_relative=True) + print "Going to: %s" % dest + + # A better implementation would only send new waypoints if the position had changed significantly + vehicle.commands.goto(dest) + vehicle.flush() + + # Send a new target every two seconds + # For a complete implementation of follow me you'd want adjust this delay + time.sleep(2) + +except socket.error: + print "Error: gpsd service does not seem to be running, plug in USB GPS or run run-fake-gps.sh" + + +#Close vehicle object before exiting script +print "Close vehicle object" +vehicle.close() + +print("Completed") From 7e036b650727fa442d2f2944a7464d26da67d16f Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 21 Oct 2015 12:10:57 +1100 Subject: [PATCH 040/475] Fix example's help description --- examples/follow_me/follow_me.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/follow_me/follow_me.py b/examples/follow_me/follow_me.py index 4807db102..a43057ecb 100644 --- a/examples/follow_me/follow_me.py +++ b/examples/follow_me/follow_me.py @@ -18,7 +18,7 @@ #Set up option parsing to get connection string import argparse -parser = argparse.ArgumentParser(description='Print out vehicle state information. Connects to SITL on local PC by default.') +parser = argparse.ArgumentParser(description='Tracks GPS position of your computer (Linux only). Connects to SITL on local PC by default.') parser.add_argument('--connect', default='127.0.0.1:14550', help="vehicle connection target. Default '127.0.0.1:14550'") args = parser.parse_args() From be30346c116f716323432beb8829795588ccad8c Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 22 Oct 2015 17:04:56 +1100 Subject: [PATCH 041/475] Docs tidy up in response to feedback --- docs/examples/follow_me.rst | 3 ++- examples/follow_me/follow_me.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/examples/follow_me.rst b/docs/examples/follow_me.rst index ab7ed6ccc..72ade7aa3 100644 --- a/docs/examples/follow_me.rst +++ b/docs/examples/follow_me.rst @@ -124,7 +124,7 @@ the mode is changed. # Use the python gps package to access the laptop GPS gpsd = gps.gps(mode=gps.WATCH_ENABLE) - #Arm and take of to altitude of 5 meters + #Arm and take off to an altitude of 5 meters arm_and_takeoff(5) while True: @@ -152,6 +152,7 @@ the mode is changed. except socket.error: print "Error: gpsd service does not seem to be running, plug in USB GPS or run run-fake-gps.sh" + sys.exit(1) diff --git a/examples/follow_me/follow_me.py b/examples/follow_me/follow_me.py index a43057ecb..253f9ca44 100644 --- a/examples/follow_me/follow_me.py +++ b/examples/follow_me/follow_me.py @@ -72,7 +72,7 @@ def arm_and_takeoff(aTargetAltitude): # Use the python gps package to access the laptop GPS gpsd = gps.gps(mode=gps.WATCH_ENABLE) - #Arm and take of to altitude of 5 meters + #Arm and take off to altitude of 5 meters arm_and_takeoff(5) while True: @@ -100,7 +100,7 @@ def arm_and_takeoff(aTargetAltitude): except socket.error: print "Error: gpsd service does not seem to be running, plug in USB GPS or run run-fake-gps.sh" - + sys.exit(1) #Close vehicle object before exiting script print "Close vehicle object" From 49674ff950f2c6ffb9ea87df2ac2965765fdc6d4 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 22 Oct 2015 17:08:31 +1100 Subject: [PATCH 042/475] Fix up directory path directions to forward slash in documentation --- docs/examples/follow_me.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/examples/follow_me.rst b/docs/examples/follow_me.rst index 72ade7aa3..bbc7155a2 100644 --- a/docs/examples/follow_me.rst +++ b/docs/examples/follow_me.rst @@ -48,7 +48,7 @@ Once you've done that: .. code-block:: bash - cd dronekit-python\examples\follow_me\ + cd dronekit-python/examples/follow_me/ #. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: @@ -68,8 +68,6 @@ On the terminal you should see (something like): .. code-block:: bash - - dronekit-python/examples/follow_me$ python follow_me.py --connect 127.0.0.1:14550 Connecting to vehicle on: 127.0.0.1:14550 >>> APM:Copter V3.4-dev (e0810c2e) From 79e08cd553e69125604a9dc3df8ba10229ed5ef3 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 21 Oct 2015 15:11:07 +1100 Subject: [PATCH 043/475] Fix up flight_replay.py doc/example to DKPY2. Note, still has bug #355 --- docs/examples/flight_replay.rst | 122 +++++++++++++++++------- examples/flight_replay/flight_replay.py | 77 +++++++++------ 2 files changed, 132 insertions(+), 67 deletions(-) diff --git a/docs/examples/flight_replay.rst b/docs/examples/flight_replay.rst index 4f8fac2be..f2be54507 100644 --- a/docs/examples/flight_replay.rst +++ b/docs/examples/flight_replay.rst @@ -2,57 +2,95 @@ Example: Flight Replay ========================= -This is an interesting demo that uses our web API to query raw flight data from a particular flight. +This example requests a past flight from Droneshare, and then "replays" the mission +by sending waypoints to a vehicle. For safety reasons, the vehicle is replayed at a height of 30 meters. +.. warning:: -Starting the demo -================= + At time of writing this example fails with an exception in DKYP2: `#355 DKPY2 Can't clear waypoints `_. -In this case, we pick some public flight from `Droneshare `_: +.. todo:: Check if `#355 DKPY2 Can't clear waypoints `_ is fixed and re-review example. -.. image:: flight_replay_example.png +You can specify which mission to replay using a parameter when starting the script (for example, to replay your own local flights). +By default the code gets (and replays) the public `Droneshare mission with ID 101 `_. -You'll notice that the mission number for this flight is 101. +.. figure:: flight_replay_example.png -Now we'll launch **flight_replay.py** (/examples/flight_replay/flight_replay.py) and ask it to try and 'replay' mission 101. It will ask the web server for representative points from the flight, parse the JSON response and use that data to generate 100 waypoints we would like our vehicle to hit. For safety rather than using the altitude from the original flight we instead ask our vehicle to fly at a height of 30 meters. + Droneshare Mission #101 -One possible use of some variant of this tool to replay your old flights at your regular test field. -:: - STABILIZE> api start flight_replay.py 101 - STABILIZE> JSON downloaded... - Genrating 95 waypoints from replay... - APIThread-1 exiting... - Got MAVLink msg: MISSION_ACK {target_system : 255, target_component : 0, type : 0} - Sent waypoint 0 : MISSION_ITEM {target_system : 1, target_component : 1, seq : 0, frame : 3, command : 16, current : 0, autocontinue : 0, param1 : 0, param2 : 0, param3 : 0, param4 : 0, x : 45.7379052, y : 126.6273574, z : 30.0} - Sent waypoint 1 : MISSION_ITEM {target_system : 1, target_component : 1, seq : 1, frame : 3, command : 16, current : 0, autocontinue : 0, param1 : 0, param2 : 0, param3 : 0, param4 : 0, x : 45.7378905, y : 126.6273609, z : 30.0} - Sent waypoint 2 : MISSION_ITEM {target_system : 1, target_component : 1, seq : 2, frame : 3, command : 16, current : 0, autocontinue : 0, param1 : 0, param2 : 0, param3 : 0, - ... - Sent waypoint 92 : MISSION_ITEM {target_system : 1, target_component : 1, seq : 92, frame : 3, command : 16, current : 0, autocontinue : 0, param1 : 0, param2 : 0, param3 : 0, param4 : 0, x : 45.737971, y : 126.6274908, z : 30.0} - Sent waypoint 93 : MISSION_ITEM {target_system : 1, target_component : 1, seq : 93, frame : 3, command : 16, current : 0, autocontinue : 0, param1 : 0, param2 : 0, param3 : 0, param4 : 0, x : 45.738018, y : 126.6275664, z : 30.0} - Sent waypoint 94 : MISSION_ITEM {target_system : 1, target_component : 1, seq : 94, frame : 3, command : 16, current : 0, autocontinue : 0, param1 : 0, param2 : 0, param3 : 0, param4 : 0, x : 45.7380429, y : 126.6275067, z : 30.0} - Sent all 95 waypoints - Got MAVLink msg: MISSION_ACK {target_system : 255, target_component : 0, type : 0} - APM: flight plan received +Running the example +=================== + +The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle +and DroneKit have been set up as described in :ref:`get-started`). + +If you're using a simulated vehicle, remember to :ref:`disable arming checks ` so +that the example can run. + +In summary, after cloning the repository: + +#. Navigate to the example folder as shown: + + .. code-block:: bash + + cd dronekit-python\examples\flight_replay\ + + +#. Start the example, passing the :ref:`connection string ` + you wish to use in the ``--connect`` parameter and specifying the mission to replay. + + .. code-block:: bash + + python flight_replay.py --connect 127.0.0.1:14550 --mission_id 101 + + .. note:: + + The command parameters above are the defaults, and may be omitted. These + connect to SITL on udp port 127.0.0.1:14550 and replay the mission with id 101. + + +.. tip:: + + It is more interesting to watch the example above on a map than the console. The topic :ref:`viewing_uav_on_map` + explains how to set up *Mission Planner* to view a vehicle running on the simulator (SITL). + +On the command prompt you should see (something like): + +.. code-block:: bash + + + \dronekit-python\examples\flight_replay>flight_replay.py + Connecting to vehicle on: 127.0.0.1:14550 + >>> ☺APM:Copter V3.4-dev (e0810c2e) + >>> ☺Frame: QUAD + JSON downloaded... + Generating 95 waypoints from replay... + ... How it works ============ +The example requests the web server for representative points from the flight, parses the JSON response +and uses that data to generate 100 waypoints. These are then sent to the vehicle. + + + Getting the points ------------------ The following simple function asks for the droneshare flight data: -:: +.. code:: python - def download_messages(mission_id, max_freq = 1.0): - """Download a public mission from droneshare (as JSON)""" - f = urllib.urlopen("%s/api/v1/mission/%s/messages.json?max_freq=%s&api_key=%s" % (api_server, mission_id, max_freq, api_key)) - j = json.load(f, object_hook=_decode_dict) - f.close() - return j + def download_messages(mission_id, max_freq = 1.0): + """Download a public mission from droneshare (as JSON)""" + f = urllib.urlopen("%s/api/v1/mission/%s/messages.json?max_freq=%s&api_key=%s" % (api_server, mission_id, max_freq, api_key)) + j = json.load(f, object_hook=_decode_dict) + f.close() + return j Some comments: @@ -61,11 +99,14 @@ Some comments: Setting the new waypoints -========================= +------------------------- + +If necessary, the example then reduces the number of messages retrieved into a set that can fit on the vehicle (in this case 100 waypoints). -We generate up to 100 waypoints for the vehicle with the following code: +The following code shows how the vehicle writes the received messages as commands (this part of the code is very similar to that +shown in :ref:`example_mission_basic`): -:: +.. code:: python print "Generating %s waypoints from replay..." % len(messages) cmds = v.commands @@ -89,8 +130,18 @@ We generate up to 100 waypoints for the vehicle with the following code: v.flush() -Next we'll work with existing Linux services (gpsd) to add a new drone based feature called :ref:`Follow Me `. +Known issues +============ + +At time of writing this example fails with an exception. See `#355 DKPY2 Can't clear waypoints `_ for more information. + +.. todo:: + + When example is fixed replace above text with + "This example works around the :ref:`known issues in the API `. + Provided that the vehicle is connected and able to arm, it should run through to completion." + Source code =========== @@ -100,4 +151,3 @@ The full source code at documentation build-time is listed below (`current versi .. literalinclude:: ../../examples/flight_replay/flight_replay.py :language: python - \ No newline at end of file diff --git a/examples/flight_replay/flight_replay.py b/examples/flight_replay/flight_replay.py index f496ddb71..d5948f9f8 100644 --- a/examples/flight_replay/flight_replay.py +++ b/examples/flight_replay/flight_replay.py @@ -1,28 +1,35 @@ """ flight_replay.py: -An example of talking to Droneshare to receive a past flight, and then 'replaying' -that flight by sending waypoints to a vehicle. - -Start this example as shown below, specifying the -missionid (a numeric mission number from a public droneshare flight): - - api start flight_replay.py +This example requests a past flight from Droneshare, and then 'replays' +the flight by sending waypoints to a vehicle. Full documentation is provided at http://python.dronekit.io/examples/flight_replay.html """ +from dronekit import connect from dronekit.lib import Command from pymavlink import mavutil import json, urllib, math -api_server = "https://api.3drobotics.com" -api_key = "a8948c11.9e44351f6c0aa7e3e2ff6d00b14a71c5" +#Set up option parsing to get connection string +import argparse +parser = argparse.ArgumentParser(description='Get a flight from droneshare and send as waypoints to a vehicle. Connects to SITL on local PC by default.') +parser.add_argument('--connect', default='127.0.0.1:14550', + help="vehicle connection target. Default '127.0.0.1:14550'") +parser.add_argument('--mission_id', default='101', + help="DroneShare Mission ID to replay. Default is '101'") +parser.add_argument('--api_server', default='https://api.3drobotics.com', + help="API Server. Default is Droneshare API (https://api.3drobotics.com)") +parser.add_argument('--api_key', default='89b511b1.d884d1cb57306e63925fcc07d032f2af', + help="API Server Key (default should be fine!)") +args = parser.parse_args() + + +# Connect to the Vehicle +print 'Connecting to vehicle on: %s' % args.connect +vehicle = connect(args.connect, await_params=True) -# First get an instance of the API endpoint -api = local_connect() -# Get our vehicle - when running with MAVProxy it only knows about one vehicle (for now) -v = api.get_vehicles()[0] def _decode_list(data): @@ -55,7 +62,8 @@ def _decode_dict(data): def download_messages(mission_id, max_freq = 1.0): """Download a public mission from droneshare (as JSON)""" - f = urllib.urlopen("%s/api/v1/mission/%s/messages.json?max_freq=%s&api_key=%s" % (api_server, mission_id, max_freq, api_key)) + message_url="%s/api/v1/mission/%s/messages.json?max_freq=%s&api_key=%s" % (args.api_server, mission_id, max_freq, args.api_key) + f = urllib.urlopen(message_url) j = json.load(f, object_hook=_decode_dict) f.close() return j @@ -63,7 +71,11 @@ def download_messages(mission_id, max_freq = 1.0): def replay_mission(payload): """Given mission JSON, set a series of wpts approximating the previous flight""" # Pull out just the global position msgs - messages = payload['messages'] + try: + messages = payload['messages'] + except: + print "Exception: payload from site is: %s" % payload + exit() messages = filter(lambda obj: obj['typ'] == 'MAVLINK_MSG_ID_GLOBAL_POSITION_INT', messages) messages = map(lambda obj: obj['fld'], messages) @@ -76,9 +88,9 @@ def replay_mission(payload): messages = shorter print "Generating %s waypoints from replay..." % len(messages) - cmds = v.commands + cmds = vehicle.commands cmds.clear() - v.flush() + vehicle.flush() for i in xrange(0, len(messages)): pt = messages[i] lat = pt['lat'] @@ -94,17 +106,20 @@ def replay_mission(payload): 0, 0, 0, 0, 0, 0, lat, lon, altitude) cmds.add(cmd) - v.flush() - -if len(local_arguments) != 1: - print 'Error: usage "api start flight_replay.py "' -else: - # Now download the vehicle waypoints - cmds = v.commands - cmds.wait_valid() - - mission_id = int(local_arguments[0]) - max_freq = 0.1 - json = download_messages(mission_id, max_freq) - print "JSON downloaded..." - replay_mission(json) + vehicle.flush() + + +# Now download the vehicle waypoints +cmds = vehicle.commands +cmds.wait_valid() +mission_id = int(args.mission_id) +max_freq = 0.1 +json = download_messages(mission_id, max_freq) +print "JSON downloaded..." +replay_mission(json) + + +#Close vehicle object before exiting script +print "Close vehicle object" +vehicle.close() +print("Completed") From e6e6ed296a9bf16640ea2786a490d709df76beea Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 22 Oct 2015 17:14:06 +1100 Subject: [PATCH 044/475] Update in line with Tims comments --- docs/examples/flight_replay.rst | 6 +++--- examples/flight_replay/flight_replay.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/examples/flight_replay.rst b/docs/examples/flight_replay.rst index f2be54507..e5f1747a1 100644 --- a/docs/examples/flight_replay.rst +++ b/docs/examples/flight_replay.rst @@ -35,7 +35,7 @@ In summary, after cloning the repository: .. code-block:: bash - cd dronekit-python\examples\flight_replay\ + cd dronekit-python/examples/flight_replay/ #. Start the example, passing the :ref:`connection string ` @@ -63,8 +63,8 @@ On the command prompt you should see (something like): \dronekit-python\examples\flight_replay>flight_replay.py Connecting to vehicle on: 127.0.0.1:14550 - >>> ☺APM:Copter V3.4-dev (e0810c2e) - >>> ☺Frame: QUAD + >>> APM:Copter V3.4-dev (e0810c2e) + >>> Frame: QUAD JSON downloaded... Generating 95 waypoints from replay... ... diff --git a/examples/flight_replay/flight_replay.py b/examples/flight_replay/flight_replay.py index d5948f9f8..c48c73607 100644 --- a/examples/flight_replay/flight_replay.py +++ b/examples/flight_replay/flight_replay.py @@ -75,7 +75,7 @@ def replay_mission(payload): messages = payload['messages'] except: print "Exception: payload from site is: %s" % payload - exit() + sys.exit() messages = filter(lambda obj: obj['typ'] == 'MAVLINK_MSG_ID_GLOBAL_POSITION_INT', messages) messages = map(lambda obj: obj['fld'], messages) @@ -122,4 +122,4 @@ def replay_mission(payload): #Close vehicle object before exiting script print "Close vehicle object" vehicle.close() -print("Completed") +print("Completed...") From 79ca024597cfd35a2577e1aa301e2f0095c07353 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 21 Oct 2015 17:02:10 +1100 Subject: [PATCH 045/475] Minimal changes to drone_delivery for dkpy2. This is broken by #357, and that is documented too --- docs/examples/drone_delivery.rst | 110 ++++++++++++++++------ examples/drone_delivery/drone_delivery.py | 41 ++++++-- 2 files changed, 116 insertions(+), 35 deletions(-) diff --git a/docs/examples/drone_delivery.rst b/docs/examples/drone_delivery.rst index e7f1ae520..b73904ce8 100644 --- a/docs/examples/drone_delivery.rst +++ b/docs/examples/drone_delivery.rst @@ -2,7 +2,14 @@ Example: Drone Delivery =========================== -This demonstration is a bit more extensive. It is a `CherryPy `_ based web application that displays a mapbox map to let you view the current vehicle position and send the vehicle commands to fly to a particular latitude and longitude. +This example shows how to create a `CherryPy `_ based web application that +displays a mapbox map to let you view the current vehicle position and send the vehicle commands +to fly to a particular latitude and longitude. + +.. warning:: + + At time of writing, this example does not work properly (the vehicle does not take off). + For more information see `#357 Mode not changed when message sent inside drone delivery example `_ New functionality demonstrated by this example includes: @@ -10,34 +17,80 @@ New functionality demonstrated by this example includes: * Starting *CherryPy* from a DroneKit application. -Starting the demo -================= +Running the example +=================== + +The example can be run much as described in :doc:`running_examples` (which in turn assumes that the vehicle +and DroneKit have been set up as described in :ref:`get-started`). The main exception is that you need to +install the CherryPy dependencies and view the behaviour in a web browser. + +If you're using a simulated vehicle remember to :ref:`disable arming checks ` so +that the example can run. You can also `add a virtual rangefinder `_ +(otherwise the :py:attr:`Vehicle.rangefinder ` attribute may return values of ``None`` for the distance +and voltage). + +In summary, after cloning the repository: + +#. Navigate to the example folder as shown: + + .. code-block:: bash + + cd dronekit-python\examples\drone_delivery\ + + +#. Install *CherryPy* and any other dependencies from **requirements.pip** in that directory: -The demonstration is started similar to the previous tutorials. You should see output that looks like the following: + .. code-block:: bash -:: + pip install -r requirements.pip + + +#. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: - GUIDED> api start drone_delivery.py - GUIDED> [DEBUG]: DroneDelivery Start - [DEBUG]: Waiting for GPS Lock - [DEBUG]: DroneDelivery Armed Callback - [DEBUG]: GPS: GPSInfo:fix=3,num_sat=10 - [DEBUG]: Running initial boot sequence - [DEBUG]: Arming - [DEBUG]: Taking off - [DEBUG]: Mode: GUIDED - INFO:cherrypy.error:[03/Mar/2015:14:29:01] ENGINE Bus STARTING - INFO:cherrypy.error:[03/Mar/2015:14:29:01] ENGINE Started monitor thread '_TimeoutMonitor'. - INFO:cherrypy.error:[03/Mar/2015:14:29:01] ENGINE Started monitor thread 'Autoreloader'. - INFO:cherrypy.error:[03/Mar/2015:14:29:01] ENGINE Serving on http://0.0.0.0:8080 - INFO:cherrypy.error:[03/Mar/2015:14:29:01] ENGINE Bus STARTED - ARMED - GPS lock at 0 meters + .. code-block:: bash + + python drone_delivery.py --connect 127.0.0.1:14550 + + .. note:: + + The command parameter above is the default, and may be omitted. This + connects to SITL on udp port 127.0.0.1:14550. + +#. After a short while you should be able to reach your new webserver at http://localhost:8080. + + +On the command prompt you should see (something like): + +.. code-block:: bash + + \dronekit-python\examples\drone_delivery>drone_delivery.py + local path: E:\deleteme\dronekit-python\examples\drone_delivery + Connecting to vehicle on: 127.0.0.1:14550 + >>> ☺APM:Copter V3.4-dev (e0810c2e) + >>> ☺Frame: QUAD + connected ... + [DEBUG]: DroneDelivery Start + [DEBUG]: Waiting for GPS Lock + [DEBUG]: DroneDelivery Armed Callback + [DEBUG]: GPS: GPSInfo:fix=3,num_sat=10 + [DEBUG]: Running initial boot sequence + [DEBUG]: Arming + [DEBUG]: Taking off + [DEBUG]: Mode: GUIDED + INFO:cherrypy.error:[21/Oct/2015:16:33:15] ENGINE Bus STARTING + INFO:cherrypy.error:[21/Oct/2015:16:33:15] ENGINE Started monitor thread 'Autoreloader'. + INFO:cherrypy.error:[21/Oct/2015:16:33:15] ENGINE Started monitor thread '_TimeoutMonitor'. + INFO:cherrypy.error:[21/Oct/2015:16:33:15] ENGINE Serving on http://0.0.0.0:8080 + INFO:cherrypy.error:[21/Oct/2015:16:33:15] ENGINE Bus STARTED + >>> ☺ARMING MOTORS + >>> ☺Initialising APM... + ... + Screenshots =========== -You should be able to reach your new webserver at http://localhost:8080. It will look like the following: +The webserver (http://localhost:8080) will look like the following: .. image:: drone-delivery-splash.png @@ -46,19 +99,19 @@ You should be able to reach your new webserver at http://localhost:8080. It will .. image:: drone-delivery-command.png -Looking at the code -=================== +How it works +============ Using attribute observers ------------------------- All attributes in DroneKit can have observers - this is the primary mechanism you should use to be notified of changes in vehicle state. For instance, `drone_delivery.py `_ calls: -:: +.. code-block:: python - self.vehicle.add_attribute_observer('location', self.location_callback) + self.vehicle.add_attribute_observer('location', self.location_callback) - ... + ... def location_callback(self, location): location = self.vehicle.location @@ -71,6 +124,8 @@ All attributes in DroneKit can have observers - this is the primary mechanism yo This results in DroneKit calling our ``location_callback`` method any time the location attribute gets changed. + + Starting CherryPy from a DroneKit application --------------------------------------------- @@ -78,7 +133,6 @@ We start running a web server by calling ``cherrypy.engine.start()``. *CherryPy* is a very small and simple webserver. It is probably best to refer to their eight line `tutorial `_ for more information. -Next we'll look at the basics of using the webservice and the local vehicle API to 'replay' a flight which has been uploaded to `Droneshare `_. Source code diff --git a/examples/drone_delivery/drone_delivery.py b/examples/drone_delivery/drone_delivery.py index da141aa57..496f0a00f 100644 --- a/examples/drone_delivery/drone_delivery.py +++ b/examples/drone_delivery/drone_delivery.py @@ -1,14 +1,37 @@ +""" +drone_delivery.py: + +A CherryPy based web application that displays a mapbox map to let you view the current vehicle position and send the vehicle commands to fly to a particular latitude and longitude. + +Full documentation is provided at http://python.dronekit.io/examples/drone_delivery.html +""" import os, os.path import simplejson from pymavlink import mavutil import dronekit.lib +from dronekit import connect from dronekit.lib import VehicleMode, Location import cherrypy from cherrypy.process import wspbus, plugins from jinja2 import Environment, FileSystemLoader + +#Set up option parsing to get connection string +import argparse +parser = argparse.ArgumentParser(description='Print out vehicle state information. Connects to SITL on local PC by default.') +parser.add_argument('--connect', default='127.0.0.1:14550', + help="vehicle connection target. Default '127.0.0.1:14550'") +args = parser.parse_args() + + + +local_path=os.path.dirname(os.path.abspath(__file__)) +print "local path: %s" % local_path + + + cherrypy_conf = { '/': { 'tools.sessions.on': True, @@ -22,10 +45,12 @@ class Drone(object): def __init__(self, home_coords, server_enabled=True): - self.api = local_connect() + # Connect to the Vehicle + print 'Connecting to vehicle on: %s' % args.connect + self.vehicle = connect(args.connect, await_params=True) + print "connected ..." self.gps_lock = False self.altitude = 30.0 - self.vehicle = self.api.get_vehicles()[0] self.commands = self.vehicle.commands self.current_coords = [] self.home_coords = home_coords @@ -45,11 +70,8 @@ def takeoff(self): self.commands.takeoff(30.0) self.vehicle.flush() - def arm(self, toggle=True): - if toggle: - self._log("Arming") - else: - self._log("Disarming") + def arm(self): + self._log("Arming") self.vehicle.armed = True self.vehicle.flush() @@ -195,3 +217,8 @@ def track(self, lat=None, lon=None): Drone([32.5738, -117.0068]) cherrypy.engine.block() + +#Close vehicle object before exiting script +print "Close vehicle object" +vehicle.close() +print("Completed") From c8e62f7589cf8e977bf2d32326b574f4bfbc1111 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 21 Oct 2015 18:12:46 -0700 Subject: [PATCH 046/475] Removes stray forward slash replace in STATUSTEXT. --- dronekit/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 117a12b19..071f0dde6 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -116,7 +116,7 @@ def decorator(fn): @message_default('STATUSTEXT') def listener(self, name, m): if self.status_printer: - self.status_printer(re.sub(r'(^|\n)', '>>> \1', m.text.rstrip())) + self.status_printer(re.sub(r'(^|\n)', '>>> ', m.text.rstrip())) self.lat = None self.lon = None From 7084758a63c99ef91655d43e4c4c1aafc0bb0879 Mon Sep 17 00:00:00 2001 From: squilter Date: Tue, 13 Oct 2015 17:39:00 -0400 Subject: [PATCH 047/475] add local position support --- dronekit/__init__.py | 12 ++++++++++++ dronekit/lib/__init__.py | 33 ++++++++++++++++++++++++++++----- dronekit/module/api.py | 14 +++++++++----- 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 071f0dde6..efcadab05 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -121,6 +121,7 @@ def listener(self, name, m): self.lat = None self.lon = None self.alt = None + self.vx = None self.vy = None self.vz = None @@ -131,6 +132,17 @@ def listener(self, name, m): (self.vx, self.vy, self.vz) = (m.vx / 100.0, m.vy / 100.0, m.vz / 100.0) self._notify_attribute_listeners('location', 'velocity') + self.north = None + self.east = None + self.down = None + + @message_default('LOCAL_POSITION_NED') + def listener(self, name, m): + self.north = m.x + self.east = m.y + self.down = m.z + self._MPFakeState__on_change('local_position') + @message_default('GPS_RAW') def listener(self, name, m): # (self.lat, self.lon) = (m.lat, m.lon) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 61fbf7f81..3df494b89 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -117,9 +117,9 @@ def __init__(self, pitch, yaw, roll): def __str__(self): return "Attitude:pitch=%s,yaw=%s,roll=%s" % (self.pitch, self.yaw, self.roll) -class Location(object): +class LocationGlobal(object): """ - A location object. + A global location object. The latitude and longitude are relative to the `WGS84 coordinate system `_. The altitude is relative to either the *home position* or "mean sea-level", depending on the value of the ``is_relative``. @@ -144,7 +144,25 @@ def __init__(self, lat, lon, alt=None, is_relative=True): self.is_relative = is_relative def __str__(self): - return "Location:lat=%s,lon=%s,alt=%s,is_relative=%s" % (self.lat, self.lon, self.alt, self.is_relative) + return "LocationGlobal:lat=%s,lon=%s,alt=%s,is_relative=%s" % (self.lat, self.lon, self.alt, self.is_relative) + +class LocationLocal(object): + """ + A local location object. + + The north, east and down are relative to the EKF origin. This is most likely the location where the vehicle was turned on. + + :param north: Position north of the EKF origin in meters. + :param east: Position east of the EKF origin in meters. + :param down: Position down from the EKF origin in meters. (i.e. negative altitude in meters) + """ + def __init__(self, north, east, down): + self.north = north + self.east = east + self.down = down + + def __str__(self): + return "LocationLocal:north=%s,east=%s,down=%s" % (self.north, self.east, self.down) class GPSInfo(object): """ @@ -427,9 +445,14 @@ class Vehicle(HasObservers): **Standard attributes & types:** - .. py:attribute:: location + .. py:attribute:: location_global + + Current :py:class:`LocationGlobal`. + + + .. py:attribute::local_local - Current :py:class:`Location`. + Current :py:class:`LocationLocal`. .. py:attribute:: attitude diff --git a/dronekit/module/api.py b/dronekit/module/api.py index ad4abf7eb..6cb0b00ad 100644 --- a/dronekit/module/api.py +++ b/dronekit/module/api.py @@ -5,9 +5,9 @@ import logging import math from pymavlink import mavutil -from dronekit.lib import APIConnection, Vehicle, VehicleMode, Location, \ - Attitude, GPSInfo, Parameters, CommandSequence, APIException, Battery, \ - Rangefinder +from dronekit.lib import APIConnection, Vehicle, VehicleMode, LocationLocal, \ + LocationGlobal, Attitude, GPSInfo, Parameters, CommandSequence, \ + APIException, Battery, Rangefinder # Enable logging here (until this code can be moved into mavproxy) logging.basicConfig(level=logging.DEBUG) @@ -173,8 +173,12 @@ def mode(self, v): self.__master.set_mode(self.__mode_mapping[v.name]) @property - def location(self): - return Location(self.__module.lat, self.__module.lon, self.__module.alt, is_relative=False) + def location_global(self): + return LocationGlobal(self.__module.lat, self.__module.lon, self.__module.alt, is_relative=False) + + @property + def location_local(self): + return LocationLocal(self.__module.north, self.__module.east, self.__module.down) @property def battery(self): From 03480792d68ebfb5f8f973980b6b03dc9b074b0d Mon Sep 17 00:00:00 2001 From: squilter Date: Tue, 13 Oct 2015 17:39:16 -0400 Subject: [PATCH 048/475] update examples for local position --- dronekit/__main__.py | 3 ++- examples/vehicle_state/vehicle_state.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/dronekit/__main__.py b/dronekit/__main__.py index 73154941f..5ddc3ffbc 100644 --- a/dronekit/__main__.py +++ b/dronekit/__main__.py @@ -20,7 +20,8 @@ def demo(local_connect): # Get all vehicle attributes (state) print "\nGet all vehicle attribute values:" - print " Location: %s" % v.location + print " Global Location: %s" % v.location_global + print " Local Location: %s" % v.location_local print " Attitude: %s" % v.attitude print " Velocity: %s" % v.velocity print " GPS: %s" % v.gps_0 diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 128f422b8..4283776fd 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -25,7 +25,8 @@ # Get all vehicle attributes (state) print "\nGet all vehicle attribute values:" -print " Location: %s" % vehicle.location +print " Global Location: %s" % v.location_global +print " Local Location: %s" % v.location_local print " Attitude: %s" % vehicle.attitude print " Velocity: %s" % vehicle.velocity print " GPS: %s" % vehicle.gps_0 From 7d9eb8b367506f11a52d34af86f83e273382ad41 Mon Sep 17 00:00:00 2001 From: squilter Date: Tue, 13 Oct 2015 19:13:07 -0400 Subject: [PATCH 049/475] add sitl test for local position and update old sitl test --- dronekit/__init__.py | 3 +-- tests/sitl/test_goto.py | 8 ++++---- tests/sitl/test_localposition.py | 30 ++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 tests/sitl/test_localposition.py diff --git a/dronekit/__init__.py b/dronekit/__init__.py index efcadab05..bb8c81aa7 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -121,7 +121,6 @@ def listener(self, name, m): self.lat = None self.lon = None self.alt = None - self.vx = None self.vy = None self.vz = None @@ -141,7 +140,7 @@ def listener(self, name, m): self.north = m.x self.east = m.y self.down = m.z - self._MPFakeState__on_change('local_position') + self._notify_attribute_listeners('local_position') @message_default('GPS_RAW') def listener(self, name, m): diff --git a/tests/sitl/test_goto.py b/tests/sitl/test_goto.py index 1d6273299..2767a8520 100644 --- a/tests/sitl/test_goto.py +++ b/tests/sitl/test_goto.py @@ -9,7 +9,7 @@ import time from dronekit import connect -from dronekit.lib import VehicleMode, Location +from dronekit.lib import VehicleMode, LocationGlobal from dronekit.tools import with_sitl from pymavlink import mavutil from nose.tools import assert_equals @@ -74,7 +74,7 @@ def arm_and_takeoff(aTargetAltitude): while True: # print " Altitude: ", vehicle.location.alt # Test for altitude just below target, in case of undershoot. - if vehicle.location.alt >= aTargetAltitude * 0.95: + if vehicle.location_global.alt >= aTargetAltitude * 0.95: # print "Reached target altitude" break @@ -84,7 +84,7 @@ def arm_and_takeoff(aTargetAltitude): arm_and_takeoff(10) # print "Going to first point..." - point1 = Location(-35.361354, 149.165218, 20, is_relative=True) + point1 = LocationGlobal(-35.361354, 149.165218, 20, is_relative=True) vehicle.commands.goto(point1) vehicle.flush() @@ -92,7 +92,7 @@ def arm_and_takeoff(aTargetAltitude): time.sleep(3) # print "Going to second point..." - point2 = Location(-35.363244, 149.168801, 20, is_relative=True) + point2 = LocationGlobal(-35.363244, 149.168801, 20, is_relative=True) vehicle.commands.goto(point2) vehicle.flush() diff --git a/tests/sitl/test_localposition.py b/tests/sitl/test_localposition.py new file mode 100644 index 000000000..d05ac6570 --- /dev/null +++ b/tests/sitl/test_localposition.py @@ -0,0 +1,30 @@ +from dronekit import connect +from dronekit.tools import with_sitl +import time +from nose.tools import assert_not_equals + +@with_sitl +def test_timeout(connpath): + v = connect(connpath, await_params=True) + + # print "Basic pre-arm checks" + # Don't let the user try to fly autopilot is booting + if v.mode.name == "INITIALISING": + # print "Waiting for vehicle to initialise" + time.sleep(1) + while v.gps_0.fix_type < 2: + # print "Waiting for GPS...:", vehicle.gps_0.fix_type + time.sleep(1) + + v.armed = True + v.flush() + + while not v.armed: + time.sleep(1) + + time.sleep(1) + + #north, east, and down are initialized to None. Any other value suggests that a LOCAL_POSITION_NED was received and parsed. + assert_not_equals(v.location_local.north, None) + assert_not_equals(v.location_local.east, None) + assert_not_equals(v.location_local.down, None) From 96dac34198c3994c729e544b12c950394e7bf359 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 15 Oct 2015 15:49:09 -0400 Subject: [PATCH 050/475] Updates API, adds backward compatibility to local/global loc. --- dronekit/__main__.py | 4 ++-- dronekit/lib/__init__.py | 8 ++++++-- dronekit/module/api.py | 12 ++++++------ examples/vehicle_state/vehicle_state.py | 4 ++-- tests/sitl/test_goto.py | 2 +- tests/sitl/test_localposition.py | 6 +++--- 6 files changed, 20 insertions(+), 16 deletions(-) diff --git a/dronekit/__main__.py b/dronekit/__main__.py index 5ddc3ffbc..c149f0a14 100644 --- a/dronekit/__main__.py +++ b/dronekit/__main__.py @@ -20,8 +20,8 @@ def demo(local_connect): # Get all vehicle attributes (state) print "\nGet all vehicle attribute values:" - print " Global Location: %s" % v.location_global - print " Local Location: %s" % v.location_local + print " Global Location: %s" % v.location.global_frame + print " Local Location: %s" % v.location.local_frame print " Attitude: %s" % v.attitude print " Velocity: %s" % v.velocity print " GPS: %s" % v.gps_0 diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 3df494b89..7aae3f5f5 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -142,6 +142,10 @@ def __init__(self, lat, lon, alt=None, is_relative=True): self.lon = lon self.alt = alt self.is_relative = is_relative + + # This is for backward compatibility. + self.local_frame = None + self.global_fame = None def __str__(self): return "LocationGlobal:lat=%s,lon=%s,alt=%s,is_relative=%s" % (self.lat, self.lon, self.alt, self.is_relative) @@ -445,12 +449,12 @@ class Vehicle(HasObservers): **Standard attributes & types:** - .. py:attribute:: location_global + .. py:attribute:: location.global_frame Current :py:class:`LocationGlobal`. - .. py:attribute::local_local + .. py:attribute:: location.local_frame Current :py:class:`LocationLocal`. diff --git a/dronekit/module/api.py b/dronekit/module/api.py index 6cb0b00ad..c410cc22d 100644 --- a/dronekit/module/api.py +++ b/dronekit/module/api.py @@ -173,12 +173,12 @@ def mode(self, v): self.__master.set_mode(self.__mode_mapping[v.name]) @property - def location_global(self): - return LocationGlobal(self.__module.lat, self.__module.lon, self.__module.alt, is_relative=False) - - @property - def location_local(self): - return LocationLocal(self.__module.north, self.__module.east, self.__module.down) + def location(self): + # For backward compatibility, this is (itself) a LocationLocal object. + ret = LocationGlobal(self.__module.lat, self.__module.lon, self.__module.alt, is_relative=False) + ret.local_frame = LocationLocal(self.__module.north, self.__module.east, self.__module.down) + ret.global_frame = LocationGlobal(self.__module.lat, self.__module.lon, self.__module.alt, is_relative=False) + return ret @property def battery(self): diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 4283776fd..5f9e55ed8 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -25,8 +25,8 @@ # Get all vehicle attributes (state) print "\nGet all vehicle attribute values:" -print " Global Location: %s" % v.location_global -print " Local Location: %s" % v.location_local +print " Global Location: %s" % v.location.global_frame +print " Local Location: %s" % v.location.local_frame print " Attitude: %s" % vehicle.attitude print " Velocity: %s" % vehicle.velocity print " GPS: %s" % vehicle.gps_0 diff --git a/tests/sitl/test_goto.py b/tests/sitl/test_goto.py index 2767a8520..3327ab7f8 100644 --- a/tests/sitl/test_goto.py +++ b/tests/sitl/test_goto.py @@ -74,7 +74,7 @@ def arm_and_takeoff(aTargetAltitude): while True: # print " Altitude: ", vehicle.location.alt # Test for altitude just below target, in case of undershoot. - if vehicle.location_global.alt >= aTargetAltitude * 0.95: + if vehicle.location.global_frame.alt >= aTargetAltitude * 0.95: # print "Reached target altitude" break diff --git a/tests/sitl/test_localposition.py b/tests/sitl/test_localposition.py index d05ac6570..d10cd177e 100644 --- a/tests/sitl/test_localposition.py +++ b/tests/sitl/test_localposition.py @@ -25,6 +25,6 @@ def test_timeout(connpath): time.sleep(1) #north, east, and down are initialized to None. Any other value suggests that a LOCAL_POSITION_NED was received and parsed. - assert_not_equals(v.location_local.north, None) - assert_not_equals(v.location_local.east, None) - assert_not_equals(v.location_local.down, None) + assert_not_equals(v.location.local_frame.north, None) + assert_not_equals(v.location.local_frame.east, None) + assert_not_equals(v.location.local_frame.down, None) From bdd0b06152201257b09d2c1c73af0c472dee5719 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 22 Oct 2015 10:15:34 -0700 Subject: [PATCH 051/475] Adds backcompat for earlier clients. --- dronekit/lib/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 7aae3f5f5..6804f50ae 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -150,6 +150,9 @@ def __init__(self, lat, lon, alt=None, is_relative=True): def __str__(self): return "LocationGlobal:lat=%s,lon=%s,alt=%s,is_relative=%s" % (self.lat, self.lon, self.alt, self.is_relative) +# Back-compatibility for earlier clients. +Location = LocationGlobal + class LocationLocal(object): """ A local location object. From f352d4f4a83b72e91357d0ab974c4c994f9f4540 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 22 Oct 2015 14:55:44 -0700 Subject: [PATCH 052/475] Updates test to pass locally. --- dronekit/__init__.py | 4 ++++ tests/sitl/test_localposition.py | 36 ++++++++++++++++---------------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index bb8c81aa7..3ee31f8a2 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -588,6 +588,10 @@ def mavlink_thread(): while not params.loaded: time.sleep(0.1) + # Await GPS lock + while self.fix_type == None or self.fix_type < 2: + time.sleep(0.1) + return self.api def close(self): diff --git a/tests/sitl/test_localposition.py b/tests/sitl/test_localposition.py index d10cd177e..42063edc1 100644 --- a/tests/sitl/test_localposition.py +++ b/tests/sitl/test_localposition.py @@ -1,30 +1,30 @@ from dronekit import connect from dronekit.tools import with_sitl +from dronekit.lib import VehicleMode, LocationGlobal import time from nose.tools import assert_not_equals @with_sitl def test_timeout(connpath): - v = connect(connpath, await_params=True) + vehicle = connect(connpath, await_params=True) - # print "Basic pre-arm checks" - # Don't let the user try to fly autopilot is booting - if v.mode.name == "INITIALISING": - # print "Waiting for vehicle to initialise" - time.sleep(1) - while v.gps_0.fix_type < 2: - # print "Waiting for GPS...:", vehicle.gps_0.fix_type - time.sleep(1) + # NOTE these are *very inappropriate settings* + # to make on a real vehicle. They are leveraged + # exclusively for simulation. Take heed!!! + vehicle.parameters['ARMING_CHECK'] = 0 - v.armed = True - v.flush() - - while not v.armed: + # ARM + vehicle.armed = True + i = 60 + while not vehicle.armed and i > 0: time.sleep(1) + i = i - 1 - time.sleep(1) + # Await attributes + time.sleep(3) - #north, east, and down are initialized to None. Any other value suggests that a LOCAL_POSITION_NED was received and parsed. - assert_not_equals(v.location.local_frame.north, None) - assert_not_equals(v.location.local_frame.east, None) - assert_not_equals(v.location.local_frame.down, None) + # .north, .east, and .down are initialized to None. + # Any other value suggests that a LOCAL_POSITION_NED was received and parsed. + assert_not_equals(vehicle.location.local_frame.north, None) + assert_not_equals(vehicle.location.local_frame.east, None) + assert_not_equals(vehicle.location.local_frame.down, None) From 7975c1b108342776619f4f269da18ecf3b6f4616 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 22 Oct 2015 15:39:03 -0700 Subject: [PATCH 053/475] Corrects fix_type check. --- dronekit/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 3ee31f8a2..8072024c3 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -589,7 +589,7 @@ def mavlink_thread(): time.sleep(0.1) # Await GPS lock - while self.fix_type == None or self.fix_type < 2: + while self.fix_type == None: time.sleep(0.1) return self.api From d183f26fd335da86b83742062174974434cec5fb Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 22 Oct 2015 15:49:44 -0700 Subject: [PATCH 054/475] 2.0.0b7 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index c17c8eea9..1899def33 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.0.0b6' +version = '2.0.0b7' setup(name='dronekit', zip_safe=True, From 22c809a14ecccb98fdb3ac27c5ee3f5136859b1c Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 13 Oct 2015 14:56:32 +1100 Subject: [PATCH 055/475] Addresses #329 by creating a stand-alone channel overrides example and removing this information from elsewhere --- docs/examples/channel_overrides.rst | 90 +++++++++++++++++++ docs/examples/index.rst | 2 + docs/examples/vehicle_state.rst | 43 +++++---- docs/guide/vehicle_state_and_parameters.rst | 61 ++----------- .../channel_overrides/channel_overrides.py | 48 ++++++++++ 5 files changed, 174 insertions(+), 70 deletions(-) create mode 100644 docs/examples/channel_overrides.rst create mode 100644 examples/channel_overrides/channel_overrides.py diff --git a/docs/examples/channel_overrides.rst b/docs/examples/channel_overrides.rst new file mode 100644 index 000000000..4a45b47b3 --- /dev/null +++ b/docs/examples/channel_overrides.rst @@ -0,0 +1,90 @@ +.. _example_channel_overrides: +.. _vehicle_state_channel_override: + +========================== +Example: Channel Overrides +========================== + +This example shows how to get channel information and to get/set channel-override information. + +.. warning:: + + Channel overrides (a.k.a "RC overrides") are highly discommended (they are primarily implemented + for simulating user input and when implementing certain types of joystick control). + + Instead use the appropriate MAVLink commands like DO_SET_SERVO/DO_SET_RELAY, or more generally set + the desired position or direction/speed. + + If you have no choice but to use a channel-override please explain why in a + `github issue `_ and we will attempt to find a + better alternative. + + +Running the example +=================== + +The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle +and DroneKit have been set up as described in :ref:`get-started`). + +In summary, after cloning the repository: + +#. Navigate to the example folder as shown: + + .. code-block:: bash + + cd dronekit-python\examples\channel_overrides\ + + +#. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: + + .. code-block:: bash + + python channel_overrides.py --connect 127.0.0.1:14550 + + .. note:: + + The examples uses the ``--connect`` parameter to pass the :ref:`connection string ` into the script. + The command above would be used to connect to :ref:`SITL ` running on the local machine via UDP port 14550. + + + +On the command prompt you should see (something like): + +.. code:: bash + + Overriding RC channels for roll and yaw + Current overrides are: {'1': 900, '4': 1000} + Channel default values: {'1': 1500, '3': 1000, '2': 1500, '5': 1800, '4': 1500, '7': 1000, '6': 1000, '8': 1800} + Cancelling override + + + +How does it work? +================= + +Get the default values of the channels using the :py:attr:`channel_readback ` attribute. + +You can over-ride these values using the :py:attr:`channel_override ` attribute. This takes a dictionary argument defining the RC *output* channels to be overridden (specified by channel number), and their new values. Channels that are not specified in the dictionary are not overridden. All multi-channel updates are atomic. To cancel an override call ``channel_override`` again, setting zero for the overridden channels. + +The values of the first four channels map to the main flight controls: 1=Roll, 2=Pitch, 3=Throttle, 4=Yaw (the mapping is defined in ``RCMAP_`` parameters in +`Plane `_, +`Copter `_ , +`Rover `_). + +The remaining channel values are configurable, and their purpose can be determined using the +`RCn_FUNCTION parameters `_. +In general a value of 0 set for a specific ``RCn_FUNCTION`` indicates that the channel can be +`mission controlled `_ (i.e. it will not directly be +controlled by normal autopilot code). + + + + +Source code +=========== + +The full source code at documentation build-time is listed below (`current version on github `_): + +.. literalinclude:: ../../examples/channel_overrides/channel_overrides.py + :language: python + diff --git a/docs/examples/index.rst b/docs/examples/index.rst index 55504b717..d8ead16da 100644 --- a/docs/examples/index.rst +++ b/docs/examples/index.rst @@ -22,6 +22,8 @@ during missions and outside missions using custom commands. Follow Me (Linux only) Drone Delivery Flight Replay + Channel Overrides + diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index f07feff9c..8e6885bf8 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -4,7 +4,7 @@ Example: Vehicle State ====================== -This example shows how to get/set vehicle attribute, parameter and channel-override information, +This example shows how to get/set vehicle attribute and parameter information, how to observe vehicle attribute changes, and how to get the home position. The guide topic :ref:`vehicle-information` provides a more detailed explanation of how the API @@ -14,23 +14,38 @@ should be used. Running the example =================== -The vehicle and DroneKit should be set up as described in :ref:`get-started`. +The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle +and DroneKit have been set up as described in :ref:`get-started`). If you're using a simulated vehicle remember to :ref:`disable arming checks ` so -that the example can run. You can also `add a virtual rangefinder `_ +that the example can run. You can also +`add a virtual rangefinder `_ (otherwise the :py:attr:`Vehicle.rangefinder ` attribute may return values of ``None`` for the distance and voltage). -Once MAVProxy is running and the API is loaded, you can start the example by typing: ``api start vehicle_state.py``. +In summary, after cloning the repository: -.. note:: +#. Navigate to the example folder as shown: - The command above assumes you started the *MAVProxy* prompt in a directory containing the example script. If not, - you will have to specify the full path to the script (something like): - ``api start /home/user/git/dronekit-python/examples/vehicle_state/vehicle_state.py``. + .. code-block:: bash + cd dronekit-python\examples\vehicle_state\ -On the *MAVProxy* console you should see (something like): + +#. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: + + .. code-block:: bash + + python vehicle_state.py --connect 127.0.0.1:14550 + + .. note:: + + The examples uses the ``--connect`` parameter to pass the :ref:`connection string ` into the script. + The command above would be used to connect to :ref:`SITL ` running on the local machine via UDP port 14550. + + + +On the command prompt you should see (something like): .. code:: bash @@ -83,12 +98,6 @@ On the *MAVProxy* console you should see (something like): ... Raw MAVLink message: SCALED_PRESSURE {time_boot_ms : 895340, press_abs : 945.038024902, press_diff : 0.0, temperature : 2600} Remove the MAVLink callback handler (stop getting messages) - - - Overriding RC channels for roll and yaw - Current overrides are: {'1': 900, '4': 1000} - Channel default values: {'1': 1500, '3': 1000, '2': 1500, '5': 1800, '4': 1500, '7': 1000, '6': 1000, '8': 1800} - Cancelling override Reset vehicle attributes/parameters and exit Got MAVLink msg: COMMAND_ACK {command : 11, result : 0} @@ -133,7 +142,7 @@ Source code =========== The full source code at documentation build-time is listed below (`current version on github `_): - + .. literalinclude:: ../../examples/vehicle_state/vehicle_state.py :language: python - + diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index 0054ffbd3..ca9ca9a87 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -79,13 +79,13 @@ Attributes will also return ``None`` if the associated hardware is not present and `optical flow sensors `_. - + .. todo:: we need to be able to verify mount_status works/setup. .. _vehicle_state_set_attributes: - + Setting attributes ------------------ @@ -106,7 +106,7 @@ then forces DroneKit to send outstanding messages. After ``flush()`` returns the message is guaranteed to have been sent to the autopilot, but it is **not guaranteed to succeed**. For example, vehicle arming can fail if the vehicle doesn't pass pre-arming checks. - + While the autopilot does send information about the success (or failure) of the request, this is `not currently handled by DroneKit `_. @@ -161,20 +161,20 @@ For example, the following code can be used in the callback to only print output .. code:: python last_rangefinder_distance=0 - + def rangefinder_callback(rangefinder): global last_rangefinder_distance if last_rangefinder_distance == round(vehicle.rangefinder.distance, 1): return last_rangefinder_distance = round(vehicle.rangefinder.distance, 1) print " Rangefinder (metres): %s" % last_rangefinder_distance - + vehicle.add_attribute_observer('rangefinder', rangefinder_callback) -.. _vehicle_state_parameters: +.. _vehicle_state_parameters: Parameters ========== @@ -209,7 +209,7 @@ throttle at which the motors will keep spinning. - + Setting parameters ------------------ @@ -228,7 +228,7 @@ Observing parameter changes --------------------------- At time of writing :py:class:`Parameters ` does `not support `_ observing parameter changes. - + .. todo:: Check to see if observers have been implemented and if so, update the information here, in about, and in Vehicle class: @@ -305,52 +305,7 @@ The code snippet below shows how to set and clear a "demo" callback function as vehicle.unset_mavlink_callback() -.. _vehicle_state_channel_override: - -Channel Overrides ------------------ - -.. warning:: - - Channel Overrides may be useful for simulating user input and when implementing certain types of joystick control. - They should not be used for direct control of the vehicle unless there is no other choice! - - Instead use the appropriate MAVLink commands like DO_SET_SERVO/DO_SET_RELAY, or more generally set the desired position or direction/speed. - -The :py:attr:`channel_override ` attribute takes a dictionary argument defining the RC *output* channels to be overridden (specified by channel number), and their new values. Channels that are not specified in the dictionary are not overridden. All multi-channel updates are atomic. To cancel an override call ``channel_override`` again, setting zero for the overridden channels. - -The values of the first four channels map to the main flight controls: 1=Roll, 2=Pitch, 3=Throttle, 4=Yaw (the mapping is defined in ``RCMAP_`` parameters in -`Plane `_, -`Copter `_ , -`Rover `_). - -The remaining channel values are configurable, and their purpose can be determined using the -`RCn_FUNCTION parameters `_. -In general a value of 0 set for a specific ``RCn_FUNCTION`` indicates that the channel can be -`mission controlled `_ (i.e. it will not directly be -controlled by normal autopilot code). - -An example of setting and clearing overrides is given below: - -.. code:: python - - # Override the channel for roll and yaw - vehicle.channel_override = { "1" : 900, "4" : 1000 } - vehicle.flush() - - #print current override values - print "Current overrides are:", vehicle.channel_override - - # Print channel values (values if overrides removed) - print "Channel default values:", vehicle.channel_readback - - # Cancel override by setting channels to 0 - vehicle.channel_override = { "1" : 0, "4" : 0 } - vehicle.flush() - - - .. _api-information-known-issues: Known issues diff --git a/examples/channel_overrides/channel_overrides.py b/examples/channel_overrides/channel_overrides.py new file mode 100644 index 000000000..fc15a2452 --- /dev/null +++ b/examples/channel_overrides/channel_overrides.py @@ -0,0 +1,48 @@ +""" +channel_overrides.py: + +Demonstrates how set and clear channel-override information. + +# NOTE: +Channel overrides (a.k.a "RC overrides") are highly discommended (they are primarily implemented +for simulating user input and when implementing certain types of joystick control). + +They are provided for development purposes. Please raise an issue explaining why you need them +and we will try to find a better alternative: https://github.com/dronekit/dronekit-python/issues + + +Full documentation is provided at http://python.dronekit.io/examples/channel_overrides.html +""" +from dronekit import connect +from dronekit.lib import VehicleMode +from pymavlink import mavutil +import time + +#Set up option parsing to get connection string +import argparse +parser = argparse.ArgumentParser(description='Print out vehicle state information. Connects to SITL on local PC by default.') +parser.add_argument('--connect', default='127.0.0.1:14550', + help="vehicle connection target. Default '127.0.0.1:14550'") +args = parser.parse_args() + + +# Connect to the Vehicle +print 'Connecting to vehicle on: %s' % args.connect +vehicle = connect(args.connect, await_params=True) + +#Override channels +print "\nOverriding RC channels for roll and yaw" +vehicle.channel_override = { "1" : 900, "4" : 1000 } +vehicle.flush() +print " Current overrides are:", vehicle.channel_override + +# Get all original channel values (before override) +print " Channel default values:", vehicle.channel_readback + +# Cancel override by setting channels to 0 +print " Cancelling override" +vehicle.channel_override = { "1" : 0, "4" : 0 } +vehicle.flush() + +# Short wait before exiting +time.sleep(5) From 14968c89e1f08c0277abbee167d129752b7b9343 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 15 Oct 2015 15:14:25 +1100 Subject: [PATCH 056/475] Fix up Vehicle state docs to remove mavlink messages information (now in own example). Tidy up example and add vehicle.close. --- docs/examples/vehicle_state.rst | 57 ++++++++---------- docs/guide/vehicle_state_and_parameters.rst | 64 +++------------------ examples/vehicle_state/vehicle_state.py | 29 ++++------ 3 files changed, 45 insertions(+), 105 deletions(-) diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index 8e6885bf8..af8003b41 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -49,63 +49,56 @@ On the command prompt you should see (something like): .. code:: bash - MAV> api start vehicle_state.py - STABILIZE> + \dronekit-python\examples\vehicle_state>vehicle_state.py + + Connecting to vehicle on: 127.0.0.1:14550 + >>> ☺APM:Copter V3.3-rc1 (d66eec53) + >>> ☺Frame: QUAD + + Accumulating vehicle attribute messages (2s) Get all vehicle attribute values: - Location: Attitude: Attitude:pitch=-0.00405988190323,yaw=-0.0973932668567,roll=-0.00393210304901 - Velocity: [0.06, -0.07, 0.0] + Location: Location:lat=-35.3632601,lon=149.1652279,alt=-0.00999999977648,is_relative=False + Attitude: Attitude:pitch=0.00486609805375,yaw=0.489637970924,roll=0.00645932834595 + Velocity: [-0.12, 0.06, 0.0] GPS: GPSInfo:fix=3,num_sat=10 Groundspeed: 0.0 Airspeed: 0.0 Mount status: [None, None, None] - Battery: Battery voltage: 12590, current: 0, level: 99 - Rangefinder: Rangefinder: distance=0.189999997616, voltage=0.0190000012517 - Rangefinder distance: 0.189999997616 - Rangefinder voltage: 0.0190000012517 + Battery: Battery:voltage=0.0,current=None,level=None + Rangefinder: Rangefinder: distance=None, voltage=None + Rangefinder distance: None + Rangefinder voltage: None Mode: STABILIZE Armed: False + Set Vehicle.mode=GUIDED (currently: STABILIZE) Waiting for mode change ... - Got MAVLink msg: COMMAND_ACK {command : 11, result : 0} - GUIDED> Mode GUIDED + Set Vehicle.armed=True (currently: False) Waiting for arming... - APM: ARMING MOTORS - APM: Initialising APM... - Got MAVLink msg: COMMAND_ACK {command : 400, result : 0} - ARMED + >>> ☺ARMING MOTORS + >>> ☺Initialising APM... + Waiting for arming... Add mode attribute observer for Vehicle.mode Set mode=STABILIZE (currently: GUIDED) Wait 2s so callback invoked before observer removed - Got MAVLink msg: COMMAND_ACK {command : 11, result : 0} - STABILIZE> Mode STABILIZE + CALLBACK: Mode changed to: STABILIZE CALLBACK: Mode changed to: STABILIZE Get home location - Requesting 0 waypoints t=Fri May 15 11:35:58 2015 now=Fri May 15 11:35:58 2015 - Home WP: MISSION_ITEM {target_system : 255, target_component : 0, seq : 0, frame : 0, command : 16, current : 0, autocontinue : 1, param1 : 0.0, param2 : 0.0, param3 : 0.0, param4 : 0.0, x : -35.3632621765, y : 149.165237427, z : 583.729980469} + Home WP: MISSION_ITEM {target_system : 255, target_component : 0, seq : 0, frame : 0, command : 16, current : 0, autocontinue : 1, param1 : 0.0, param2 : 0.0, param3 : 0.0, param4 : 0.0, x : -35.3632583618, y : 149.165222168, z : 583.729980469} Read vehicle param 'THR_MIN': 130.0 Write vehicle param 'THR_MIN' : 10 - timeout setting THR_MIN to 10.000000 Read new value of param 'THR_MIN': 10.0 - Set MAVLink callback handler (start receiving all MAVLink messages) - Wait 1s so mavrx_debug_handler has a chance to be called before it is removed - Raw MAVLink message: RAW_IMU {time_usec : 894620000, xacc : -3, yacc : 10, zacc : -999, xgyro : 1, ygyro : 0, zgyro : 1, xmag : 153, ymag : 52, zmag : -364} - ... - Raw MAVLink message: SCALED_PRESSURE {time_boot_ms : 895340, press_abs : 945.038024902, press_diff : 0.0, temperature : 2600} - Remove the MAVLink callback handler (stop getting messages) - Reset vehicle attributes/parameters and exit - Got MAVLink msg: COMMAND_ACK {command : 11, result : 0} - APM: DISARMING MOTORS - Got MAVLink msg: COMMAND_ACK {command : 400, result : 0} - DISARMED - timeout setting THR_MIN to 130.000000 - APIThread-0 exiting... + >>> ☺DISARMING MOTORS + + Close vehicle object + diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index ca9ca9a87..d7c133fb1 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -9,8 +9,7 @@ The :py:class:`Vehicle ` class exposes *most* state inform are accessed though named elements of :py:attr:`Vehicle.parameters `. This topic explains how to get, set and observe vehicle state and parameter information (including getting the -:ref:`Home location `). It also describes a few APIs that -:ref:`should be used with caution `. +:ref:`Home location `). .. tip:: You can test most of the code in this topic by running the :ref:`Vehicle State ` example. @@ -136,7 +135,8 @@ Observers are added using :py:func:`Vehicle.add_attribute_observer() `. -The code snippet below shows how to add (and remove) a callback function to observe :py:attr:`location ` attribute changes. The two second ``sleep()`` is required because otherwise the observer might be removed before the the callback is first run. +The code snippet below shows how to add (and remove) a callback function to observe :py:attr:`location ` +attribute changes. The two second ``sleep()`` is required because otherwise the observer might be removed before the the callback is first run. .. code:: python @@ -145,17 +145,17 @@ The code snippet below shows how to add (and remove) a callback function to obse print " CALLBACK: Location changed to: ", vehicle.location # Add a callback. The first parameter the name of the observed attribute (a string). - vehicle.add_attribute_observer('location', location_callback) + vehicle.add_attribute_observer('location', location_callback) # Wait 2s so callback can be notified before the observer is removed time.sleep(2) # Remove observer - specifying the attribute and previously registered callback function - vehicle.remove_attribute_observer('location', location_callback) + vehicle.remove_attribute_observer('location', location_callback) -The callback is triggered `every time a message is received from the vehicle `_ -(whether or not the observed attribute changes). Callback code may therefore choose to cache the result and only report changes. +The callback is triggered every time a message is received from the vehicle (whether or not the observed attribute changes). +Callback code may therefore choose to cache the result and only report changes. For example, the following code can be used in the callback to only print output when the value of :py:attr:`Vehicle.rangefinder ` changes. .. code:: python @@ -170,7 +170,7 @@ For example, the following code can be used in the callback to only print output print " Rangefinder (metres): %s" % last_rangefinder_distance - vehicle.add_attribute_observer('rangefinder', rangefinder_callback) + vehicle.add_attribute_observer('rangefinder', rangefinder_callback) @@ -260,52 +260,6 @@ The returned value is a :py:class:`Command ` object. -.. _vehicle_state_disrecommended: - -Discommended APIs -================= - -This section describes methods that we recommend you do not use! In general they are provided to handle the (hopefully rare) -cases where the "proper" API is missing some needed functionality. - -If you have to use these methods please `provide feedback explaining why `_. - - -.. _vehicle_state_set_mavlink_callback: - -MAVLink Message Observer ------------------------- - -The :py:func:`Vehicle.set_mavlink_callback() ` method provides asynchronous -notification when any *MAVLink* packet is received by this vehicle. The notification can be stopped by -calling :py:func:`unset_mavlink_callback() ` to remove the callback. - - -.. tip:: - - Use :ref:`attribute observers ` instead of this method where possible. - - -The code snippet below shows how to set and clear a "demo" callback function as the callback handler: - -.. code:: python - - # Demo callback handler for raw MAVLink messages - def mavrx_debug_handler(message): - print "Received", message - - # Set MAVLink callback handler (after getting Vehicle instance) - vehicle.set_mavlink_callback(mavrx_debug_handler) - - # Wait to allow the callback to be invoked before it is removed. - time.sleep(1) - - # Remove the MAVLink callback handler. Callback will not be - # called after this point. - vehicle.unset_mavlink_callback() - - - .. _api-information-known-issues: Known issues @@ -313,11 +267,9 @@ Known issues Below are a number of bugs and known issues related to vehicle state and settings: -* `#12 Timeout error when setting a parameter `_ * `#60 Attribute observer callbacks are called with heartbeat until disabled - after first called `_ * `#107 Add implementation for observer methods in Parameter class `_ * `#114 DroneKit has no method for detecting command failure `_ -* `#115 No way to disable the callback set_mavlink_callback `_ Other API issues and improvement suggestions can viewed on `github here `_. \ No newline at end of file diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 5f9e55ed8..37ca1e618 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -1,7 +1,7 @@ """ vehicle_state.py: -Demonstrates how to get and set vehicle state, parameter and channel-override information, +Demonstrates how to get and set vehicle state and parameter information, and how to observe vehicle attribute (state) changes. Full documentation is provided at http://python.dronekit.io/examples/vehicle_state.html @@ -20,9 +20,12 @@ # Connect to the Vehicle -print 'Connecting to vehicle on: %s' % args.connect +print "\nConnecting to vehicle on: %s" % args.connect vehicle = connect(args.connect, await_params=True) +print "\nAccumulating vehicle attribute messages (2s)" +time.sleep(2) + # Get all vehicle attributes (state) print "\nGet all vehicle attribute values:" print " Global Location: %s" % v.location.global_frame @@ -42,14 +45,14 @@ # Set vehicle mode and armed attributes (the only settable attributes) -print "Set Vehicle.mode=GUIDED (currently: %s)" % vehicle.mode.name +print "\nSet Vehicle.mode=GUIDED (currently: %s)" % vehicle.mode.name vehicle.mode = VehicleMode("GUIDED") vehicle.flush() # Flush to guarantee that previous writes to the vehicle have taken place while not vehicle.mode.name=='GUIDED': #Wait until mode has changed print " Waiting for mode change ..." time.sleep(1) -print "Set Vehicle.armed=True (currently: %s)" % vehicle.armed +print "\nSet Vehicle.armed=True (currently: %s)" % vehicle.armed vehicle.armed = True vehicle.flush() while not vehicle.armed: @@ -91,22 +94,14 @@ def mode_callback(attribute): print "Read new value of param 'THR_MIN': %s" % vehicle.parameters['THR_MIN'] -# Demo callback handler for raw MAVLink messages -def mavrx_debug_handler(message): - print "Raw MAVLink message: ", message - -print "\nSet MAVLink callback handler (start receiving all MAVLink messages)" -vehicle.set_mavlink_callback(mavrx_debug_handler) - -print "Wait 1s so mavrx_debug_handler has a chance to be called before it is removed" -time.sleep(1) - -print "Remove the MAVLink callback handler (stop getting messages)" -vehicle.unset_mavlink_callback() - ## Reset variables to sensible values. print "\nReset vehicle attributes/parameters and exit" vehicle.mode = VehicleMode("STABILIZE") vehicle.armed = False vehicle.parameters['THR_MIN']=130 vehicle.flush() + + +#Close vehicle object before exiting script +print "\nClose vehicle object" +vehicle.close() From c78c1090abc9e2e36b50ee8141244616df0f97b3 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 21 Oct 2015 12:34:33 +1100 Subject: [PATCH 057/475] Fix help description. Add vehicle.close to the example --- examples/channel_overrides/channel_overrides.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/examples/channel_overrides/channel_overrides.py b/examples/channel_overrides/channel_overrides.py index fc15a2452..0ff0ed2d7 100644 --- a/examples/channel_overrides/channel_overrides.py +++ b/examples/channel_overrides/channel_overrides.py @@ -20,7 +20,7 @@ #Set up option parsing to get connection string import argparse -parser = argparse.ArgumentParser(description='Print out vehicle state information. Connects to SITL on local PC by default.') +parser = argparse.ArgumentParser(description='Example showing how to set and clear vehicle channel-override information. Connects to SITL on local PC by default.') parser.add_argument('--connect', default='127.0.0.1:14550', help="vehicle connection target. Default '127.0.0.1:14550'") args = parser.parse_args() @@ -46,3 +46,9 @@ # Short wait before exiting time.sleep(5) + +#Close vehicle object before exiting script +print "Close vehicle object" +vehicle.close() + +print("Completed") From 92107d4b7b13804d56b87728e09fa2f12dd1dffc Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 22 Oct 2015 20:10:26 +1100 Subject: [PATCH 058/475] Fix up directory paths to forward slashes. Improve vehicle_state.py handling of attribute accumulation --- docs/examples/channel_overrides.rst | 2 +- docs/examples/vehicle_state.rst | 8 +++----- examples/vehicle_state/vehicle_state.py | 19 +++++++++++++++++-- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/docs/examples/channel_overrides.rst b/docs/examples/channel_overrides.rst index 4a45b47b3..abd09fba3 100644 --- a/docs/examples/channel_overrides.rst +++ b/docs/examples/channel_overrides.rst @@ -32,7 +32,7 @@ In summary, after cloning the repository: .. code-block:: bash - cd dronekit-python\examples\channel_overrides\ + cd dronekit-python/examples/channel_overrides/ #. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index af8003b41..2f2497626 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -29,7 +29,7 @@ In summary, after cloning the repository: .. code-block:: bash - cd dronekit-python\examples\vehicle_state\ + cd dronekit-python/examples/vehicle_state/ #. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: @@ -49,11 +49,9 @@ On the command prompt you should see (something like): .. code:: bash - \dronekit-python\examples\vehicle_state>vehicle_state.py - Connecting to vehicle on: 127.0.0.1:14550 - >>> ☺APM:Copter V3.3-rc1 (d66eec53) - >>> ☺Frame: QUAD + >>> APM:Copter V3.3-rc1 (d66eec53) + >>> Frame: QUAD Accumulating vehicle attribute messages (2s) diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 37ca1e618..46fa0d4a6 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -23,8 +23,14 @@ print "\nConnecting to vehicle on: %s" % args.connect vehicle = connect(args.connect, await_params=True) -print "\nAccumulating vehicle attribute messages (2s)" -time.sleep(2) +if vehicle.mode.name == "INITIALISING": + print "Waiting for vehicle to initialise" + time.sleep(1) + +print "\nAccumulating vehicle attribute messages" +while vehicle.attitude.pitch==None: #Attitude is fairly quick to propagate + print " ..." + time.sleep(1) # Get all vehicle attributes (state) print "\nGet all vehicle attribute values:" @@ -52,6 +58,13 @@ print " Waiting for mode change ..." time.sleep(1) + +# Check we have a good gps fix (required to arm) +while vehicle.gps_0.fix_type < 2: + print "Waiting for GPS fix=3 (needed to arm):", vehicle.gps_0.fix_type + time.sleep(1) + + print "\nSet Vehicle.armed=True (currently: %s)" % vehicle.armed vehicle.armed = True vehicle.flush() @@ -105,3 +118,5 @@ def mode_callback(attribute): #Close vehicle object before exiting script print "\nClose vehicle object" vehicle.close() + +print("Completed") \ No newline at end of file From 78dccb36a901d131b81cbbea2cf0bfba4f8c0806 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Roche?= Date: Fri, 14 Aug 2015 16:05:45 -0700 Subject: [PATCH 059/475] VehicleMode is now comparable fixes #278 --- dronekit/lib/__init__.py | 10 ++++++++-- tests/unit/test_api.py | 19 ++++++++++++++----- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 6804f50ae..951668fc7 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -285,6 +285,12 @@ def __init__(self, name): def __str__(self): return "VehicleMode:%s" % self.name + def __eq__(self, other): + return self.name == other + + def __ne__(self, other): + return self.name != other + class APIConnection(object): """ An API provider. @@ -524,7 +530,7 @@ class Vehicle(HasObservers): .. py:attribute:: rangefinder - :py:class:`Rangefinder` distance and voltage values. + :py:class:`Rangefinder` distance and voltage values. .. py:attribute:: channel_override @@ -750,7 +756,7 @@ def mavrx_debug_handler(message): vehicle.set_mavlink_callback(mavrx_debug_handler) :param callback: The callback function to be invoked when a raw MAVLink message is received. - + """ self.mavrx_callback = callback diff --git a/tests/unit/test_api.py b/tests/unit/test_api.py index d83ea3f21..3cd310817 100644 --- a/tests/unit/test_api.py +++ b/tests/unit/test_api.py @@ -1,9 +1,18 @@ import mock from mock import MagicMock -import dronekit -from dronekit import FakeAPI +from nose.tools import eq_, assert_not_equal +import droneapi +from droneapi.module.api import APIModule +from droneapi.lib import VehicleMode from nose.tools import assert_equals -def test_mode(): - api = FakeAPI(MagicMock()) - assert_equals(len(api.get_vehicles()), 1) +def test_get_vehicles(): + api = APIModule(MagicMock()) + res = api.get_connection() + eq_(len(res.get_vehicles()), 1) + +def test_vehicle_mode_eq(): + eq_(VehicleMode('GUIDED'), VehicleMode('GUIDED')) + +def test_vehicle_mode_neq(): + assert_not_equal(VehicleMode('AUTO'), VehicleMode('GUIDED')) From 41b39891a91e81d05b7425d68ba6703500411889 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 22 Oct 2015 16:30:08 -0700 Subject: [PATCH 060/475] Fixes VehicleMode test. --- tests/unit/test_api.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/tests/unit/test_api.py b/tests/unit/test_api.py index 3cd310817..33c8996a0 100644 --- a/tests/unit/test_api.py +++ b/tests/unit/test_api.py @@ -1,18 +1,16 @@ import mock from mock import MagicMock -from nose.tools import eq_, assert_not_equal -import droneapi -from droneapi.module.api import APIModule -from droneapi.lib import VehicleMode -from nose.tools import assert_equals +import dronekit +from dronekit.lib import VehicleMode +from dronekit import FakeAPI +from nose.tools import assert_equals, assert_not_equals -def test_get_vehicles(): - api = APIModule(MagicMock()) - res = api.get_connection() - eq_(len(res.get_vehicles()), 1) +def test_mode(): + api = FakeAPI(MagicMock()) + assert_equals(len(api.get_vehicles()), 1) def test_vehicle_mode_eq(): - eq_(VehicleMode('GUIDED'), VehicleMode('GUIDED')) + assert_equals(VehicleMode('GUIDED'), VehicleMode('GUIDED')) def test_vehicle_mode_neq(): - assert_not_equal(VehicleMode('AUTO'), VehicleMode('GUIDED')) + assert_not_equals(VehicleMode('AUTO'), VehicleMode('GUIDED')) From a3fd9c9b40077f2fa326595b2b5208064da275c2 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 22 Oct 2015 17:41:45 -0700 Subject: [PATCH 061/475] Adds PyPi published version --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2bb29e500..11d784a22 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # DroneKit Python +![PyPi published version](https://img.shields.io/pypi/v/dronekit.svg) [![Windows Build status](https://img.shields.io/appveyor/ci/3drobotics/dronekit-python/master.svg?label=windows)](https://ci.appveyor.com/project/3drobotics/dronekit-python/branch/master) [![OS X Build Status](https://img.shields.io/travis/dronekit/dronekit-python/master.svg?label=os%20x)](https://travis-ci.org/dronekit/dronekit-python) [![Linux Build Status](https://img.shields.io/circleci/project/dronekit/dronekit-python/master.svg?label=linux)](https://circleci.com/gh/dronekit/dronekit-python) From 57f9ded9e62511ed4e399aa753e2d71c551caa11 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 22 Oct 2015 17:51:10 -0700 Subject: [PATCH 062/475] Support working SITL versions. --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index ce1b2e86f..d538d87df 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,4 +5,4 @@ nose>=1.3.7 psutil>=3.0.0 mock>=1.3.0 six>=1.9.0 -dronekit-sitl>=2.3.0 +dronekit-sitl>=2.3.0,<=2.99999 From b8d70a395a57fd49a3c1d697a9aef72aa10fadcb Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 26 Oct 2015 17:49:30 -0700 Subject: [PATCH 063/475] Runs Windows four times. --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 3aadf0baa..26ffd8f44 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ environment: global: - SITL_SPEEDUP: 10 + SITL_SPEEDUP: 20 SITL_RATE: 200 cache: @@ -26,7 +26,7 @@ install: build_script: - cmd: 'nosetests tests\\web' - - cmd: 'nosetests -s -v tests\\sitl' + - cmd: 'nosetests -s -v tests\\sitl || nosetests -s -v tests\\sitl || nosetests -s -v tests\\sitl || nosetests -s -v tests\\sitl' - cmd: 'nosetests tests\\unit' clone_depth: 10 From 7510f42bf171cbb740d47c8248d332c34216831c Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 26 Oct 2015 10:13:09 +1100 Subject: [PATCH 064/475] Fix docs showing connection string for Windows --- docs/guide/getting_started.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guide/getting_started.rst b/docs/guide/getting_started.rst index 865ba1537..d0cf27e2b 100644 --- a/docs/guide/getting_started.rst +++ b/docs/guide/getting_started.rst @@ -142,8 +142,8 @@ the more common connection types: - ``127.0.0.1:14550`` * - OSX computer connected to the vehicle via USB - ``dev/cu.usbmodem1`` - * - Windows computer connected to the vehicle via USB - - ``/dev/cu.usbmodem1`` + * - Windows computer connected to the vehicle via USB (in this case on COM14) + - ``com14`` .. tip:: From ab9fea8d135d9ec6c60a227a3ee26e3f2e2252d4 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 26 Oct 2015 13:08:02 +1100 Subject: [PATCH 065/475] Remove flush everywhere it is not needed (in examples, docs, test code). This assumes flush is only needed after adding/clearing - not for takeoff etc --- docs/examples/flight_replay.rst | 6 +- docs/examples/follow_me.rst | 1 - docs/examples/guided-set-speed-yaw-demo.rst | 5 +- docs/examples/mission_basic.rst | 9 ++- docs/examples/simple_goto.rst | 5 +- docs/guide/auto_mode.rst | 1 - docs/guide/copter/guided_mode.rst | 35 ++++---- docs/guide/migrating.rst | 2 +- docs/guide/taking_off.rst | 10 +-- docs/guide/vehicle_state_and_parameters.rst | 15 ++-- dronekit/lib/__init__.py | 21 +++-- .../channel_overrides/channel_overrides.py | 2 - examples/drone_delivery/drone_delivery.py | 6 +- examples/follow_me/follow_me.py | 3 - examples/gcs/microgcs.py | 33 ++++---- .../guided_set_speed_yaw.py | 12 --- examples/mission_basic/mission_basic.py | 6 +- examples/perf/perf_test.py | 81 +++++++------------ examples/simple_goto/simple_goto.py | 5 -- examples/vehicle_state/vehicle_state.py | 5 -- tests/sitl/test_110.py | 2 - tests/sitl/test_115.py | 2 - tests/sitl/test_goto.py | 6 -- 23 files changed, 93 insertions(+), 180 deletions(-) diff --git a/docs/examples/flight_replay.rst b/docs/examples/flight_replay.rst index e5f1747a1..942dde5a7 100644 --- a/docs/examples/flight_replay.rst +++ b/docs/examples/flight_replay.rst @@ -109,9 +109,9 @@ shown in :ref:`example_mission_basic`): .. code:: python print "Generating %s waypoints from replay..." % len(messages) - cmds = v.commands + cmds = vehicle.commands cmds.clear() - v.flush() + vehicle.flush() for i in xrange(0, len(messages)): pt = messages[i] lat = pt['lat'] @@ -127,7 +127,7 @@ shown in :ref:`example_mission_basic`): 0, 0, 0, 0, 0, 0, lat, lon, altitude) cmds.add(cmd) - v.flush() + vehicle.flush() Known issues diff --git a/docs/examples/follow_me.rst b/docs/examples/follow_me.rst index bbc7155a2..5f3c4d33d 100644 --- a/docs/examples/follow_me.rst +++ b/docs/examples/follow_me.rst @@ -142,7 +142,6 @@ the mode is changed. # A better implementation would only send new waypoints if the position had changed significantly vehicle.commands.goto(dest) - vehicle.flush() # Send a new target every two seconds # For a complete implementation of follow me you'd want adjust this delay diff --git a/docs/examples/guided-set-speed-yaw-demo.rst b/docs/examples/guided-set-speed-yaw-demo.rst index 044cd69cc..c39a53314 100644 --- a/docs/examples/guided-set-speed-yaw-demo.rst +++ b/docs/examples/guided-set-speed-yaw-demo.rst @@ -205,7 +205,6 @@ This takes a function argument of either :ref:`Vehicle.commands.goto() ` convenience function. @@ -334,7 +331,7 @@ which is used to directly specify the target location in the North, East, Down f 0, 0) # yaw, yaw_rate (not supported yet, ignored in GCS_Mavlink) # send command to vehicle vehicle.send_mavlink(msg) - vehicle.flush() + At time of writing, acceleration and yaw bits are ignored. diff --git a/docs/examples/mission_basic.rst b/docs/examples/mission_basic.rst index 81293d69e..a96e41116 100644 --- a/docs/examples/mission_basic.rst +++ b/docs/examples/mission_basic.rst @@ -147,7 +147,6 @@ After taking off (in guided mode using the ``takeoff()`` function) the example s print "Starting mission" # Set mode to AUTO to start mission vehicle.mode = VehicleMode("AUTO") - vehicle.flush() The progress of the mission is monitored in a loop. The convenience function :ref:`distance_to_current_waypoint() ` @@ -187,9 +186,11 @@ This example fails in DroneKit 2.0.0b6 and earlier releases (see `#355 DKPY2 Can This is blocked by https://github.com/dronekit/dronekit-python/issues/355 (vehicle.commands.clear not working). The code output in "running the example needs to be updated once this runs cleanly. - The above text for the error needs to be replaced with original text - > "This example works around the :ref:`known issues in the API `. - > Provided that the vehicle is connected and able to arm, it should run through to completion." + The above text for the error needs to be replaced with original text: + + > "This example works around the :ref:`known issues in the API `. + > Provided that the vehicle is connected and able to arm, it should run through to completion." + Need to check all that clearing is still strictly necessary in DKPY2 which handles race conditions more gracefully. Add image of waypoints /flight for top of page. diff --git a/docs/examples/simple_goto.rst b/docs/examples/simple_goto.rst index c300bd7bf..aafd268b8 100644 --- a/docs/examples/simple_goto.rst +++ b/docs/examples/simple_goto.rst @@ -120,14 +120,12 @@ Flying to a point - Goto ------------------------ The vehicle is already in ``GUIDED`` mode, so to send it to a certain point we just need to -call :py:func:`Vehicle.commands.goto() ` with the target location, -and then :py:func:`flush() ` the command: +call :py:func:`Vehicle.commands.goto() ` with the target location: .. code-block:: python point1 = Location(-35.361354, 149.165218, 20, is_relative=True) vehicle.commands.goto(point1) - vehicle.flush() # sleep so we can see the change in map time.sleep(30) @@ -148,7 +146,6 @@ To return to the home position and land, we set the mode to ``RTL``: .. code-block:: python vehicle.mode = VehicleMode("RTL") - vehicle.flush() Source code diff --git a/docs/guide/auto_mode.rst b/docs/guide/auto_mode.rst index 1dceb29b1..b7ed4eb2f 100644 --- a/docs/guide/auto_mode.rst +++ b/docs/guide/auto_mode.rst @@ -217,7 +217,6 @@ To start a mission change the mode to AUTO: # Set the vehicle into auto mode vehicle.mode = VehicleMode("AUTO") - vehicle.flush() .. note:: diff --git a/docs/guide/copter/guided_mode.rst b/docs/guide/copter/guided_mode.rst index 4c8d5a480..97e0b2d4e 100644 --- a/docs/guide/copter/guided_mode.rst +++ b/docs/guide/copter/guided_mode.rst @@ -46,10 +46,10 @@ The method is used as shown below: # Set mode to guided - this is optional as the goto method will change the mode if needed. vehicle.mode = VehicleMode("GUIDED") - # Set the target location and then call flush() + # Set the target location a_location = Location(-34.364114, 149.166022, 30, is_relative=True) vehicle.commands.goto(a_location) - vehicle.flush() + ``Vehicle.commands.goto()`` can be interrupted by a later command, and does not provide any functionality to indicate when the vehicle has reached its destination. Developers can use either a time delay or :ref:`measure proximity to the target ` to give the vehicle an opportunity to reach its destination. The :ref:`example-guided-mode-setting-speed-yaw` shows both approaches. @@ -88,12 +88,12 @@ which is used to directly specify the speed components of the vehicle. 0, 0) # yaw, yaw_rate (not supported yet, ignored in GCS_Mavlink) # send command to vehicle vehicle.send_mavlink(msg) - vehicle.flush() - + + The ``type_mask`` parameter is a bitmask that indicates which of the other parameters in the message are used/ignored by the vehicle (0 means that the dimension is enabled, 1 means ignored). In the example the value 0b0000111111000111 is used to enable the velocity components. - + The speed components ``velocity_x`` and ``velocity_y`` are parallel to the North and East directions (not to the front and side of the vehicle). The ``velocity_z`` component is perpendicular to the plane of ``velocity_x`` and ``velocity_y``, with a positive value **towards the ground**, following the right-hand convention. For more information about the ``mavutil.mavlink.MAV_FRAME_BODY_NED`` frame of reference, see this wikipedia article @@ -140,7 +140,7 @@ ArduPilot does not currently support controlling the vehicle by specifying accel -.. _guided_mode_copter_commands: +.. _guided_mode_copter_commands: Guided mode commands ===================== @@ -153,7 +153,7 @@ This section explains how to send MAVLink commands, what commands can be sent, a Sending messages/commands ------------------------- -MAVLink commands are sent by first using :py:func:`message_factory ` to encode the message and then calling :py:func:`send_mavlink ` and ``flush()`` to send them. +MAVLink commands are sent by first using :py:func:`message_factory ` to encode the message and then calling :py:func:`send_mavlink ` to send them. ``message_factory()`` uses a factory method for the encoding. The name of this method will always be the lower case version of the message/command name with ``_encode`` appended. For example, to encode a `SET_POSITION_TARGET_LOCAL_NED `_ message we call ``message_factory.set_position_target_local_ned_encode()`` with values for all the message fields as arguments: @@ -170,8 +170,7 @@ MAVLink commands are sent by first using :py:func:`message_factory `_ - command with zero in all parameters. The front of the vehicle will then follow the direction of travel. - + command with zero in all parameters. The front of the vehicle will then follow the direction of travel. + The ROI (and yaw) is also reset when the mode, or the command used to control movement, is changed. @@ -329,14 +323,13 @@ Send the `MAV_CMD_DO_SET_HOME ` -to guarantee that the commands have been sent, and then wait until arming is confirmed before sending the -:py:func:`takeoff ` command. +Once the vehicle is ready we set the mode to ``GUIDED`` and arm it. We then wait until arming is confirmed +before sending the :py:func:`takeoff ` command. .. code-block:: python @@ -96,7 +92,6 @@ to guarantee that the commands have been sent, and then wait until arming is con # Copter should arm in GUIDED mode vehicle.mode = VehicleMode("GUIDED") vehicle.armed = True - vehicle.flush() while not vehicle.armed: print " Waiting for arming..." @@ -104,7 +99,6 @@ to guarantee that the commands have been sent, and then wait until arming is con print "Taking off!" vehicle.commands.takeoff(aTargetAltitude) # Take off to target altitude - vehicle.flush() The ``takeoff`` command is asynchronous and can be interrupted if another command arrives before it reaches the target altitude. This could have potentially serious consequences if the vehicle is commanded to move diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index d7c133fb1..c86d9a943 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -91,22 +91,21 @@ Setting attributes Only the :py:attr:`Vehicle.mode ` and :py:attr:`Vehicle.armed ` attributes can be written. -The attributes are set by assigning a value. Calling :py:func:`Vehicle.flush() ` -then forces DroneKit to send outstanding messages. +The attributes are set by assigning a value: .. code:: python #disarm the vehicle vehicle.armed = False - vehicle.flush() # Flush to ensure changes are sent to autopilot .. warning:: - After ``flush()`` returns the message is guaranteed to have been sent to the autopilot, but it is **not guaranteed to succeed**. + Changing a value is **not guaranteed to succeed**. For example, vehicle arming can fail if the vehicle doesn't pass pre-arming checks. - While the autopilot does send information about the success (or failure) of the request, this is `not currently handled by DroneKit `_. + While the autopilot does send information about the success (or failure) of the request, + this is `not currently handled by DroneKit `_. Code should not assume that an attempt to set an attribute will succeed. The example code snippet below polls the attribute values @@ -116,7 +115,6 @@ to confirm they have changed before proceeding. vehicle.mode = VehicleMode("GUIDED") vehicle.armed = True - vehicle.flush() # Flush to ensure changes are sent to autopilot while not vehicle.mode.name=='GUIDED' and not vehicle.armed and not api.exit: print " Getting ready to take off ..." time.sleep(1) @@ -213,15 +211,12 @@ throttle at which the motors will keep spinning. Setting parameters ------------------ -Vehicle parameters are set as shown in the code fragment below, using the parameter name as a "key". As with attributes, the values are not guaranteed to have been sent to the vehicle until after -:py:func:`flush() ` returns. +Vehicle parameters are set as shown in the code fragment below, using the parameter name as a "key": .. code:: python # Change the parameter value (Copter, Rover) vehicle.parameters['THR_MIN']=100 - vehicle.flush() - Observing parameter changes diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 951668fc7..fca5ab064 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -565,11 +565,9 @@ class Vehicle(HasObservers): # Override channels 1 and 4 (only). vehicle.channel_override = { "1" : 900, "4" : 1000 } - vehicle.flush() # Cancel override on channel 1 and 4 by sending 0 vehicle.channel_override = { "1" : 0, "4" : 0 } - vehicle.flush() .. versionchanged:: 1.0 @@ -779,10 +777,9 @@ def unset_mavlink_callback(self): def flush(self): """ - It is important to understand that setting attributes/changing vehicle state may occur over a slow link. + Call ``flush()`` after :py:func:`adding ` or :py:func:`clearing ` mission commands. - It is **not** guaranteed that the effects of previous commands will be visible from reading vehicle attributes unless - ``flush()`` is called first. After the return from flush any writes are guaranteed to have completed (or thrown an + After the return from ``flush()`` any writes are guaranteed to have completed (or thrown an exception) and future reads will see their effects. """ pass @@ -816,9 +813,11 @@ class Mission(object): """ Access to historical missions. - .. warning:: This function is a *placeholder*. It has no implementation in DroneKit-Python release 1. + .. warning:: + + This function is a *placeholder*. It has no implementation in DroneKit-Python release 1. - Mission objects are only accessible from the REST API in release 1 (most use-cases requiring missions prefer a REST interface). + Mission objects are only accessible from the REST API in release 1 (most use-cases requiring missions prefer a REST interface). .. todo:: FIXME: Mission class needs to be updated when it is implemented (after DroneKit Python release 1). """ @@ -831,7 +830,6 @@ class Parameters(HasObservers): `Plane `_, `Rover `_. Attribute names are generated automatically based on parameter names. The example below shows how to get and set the value of a parameter. - Note that 'set' operations are not guaranteed to be complete until :py:func:`flush() ` is called on the parent :py:class:`Vehicle` object. .. code:: python @@ -840,7 +838,7 @@ class Parameters(HasObservers): # Change the parameter value to something different. vehicle.parameters['THR_MIN']=100 - vehicle.flush() + .. note:: @@ -983,10 +981,9 @@ def goto(self, location): # Set mode to guided - this is optional as the goto method will change the mode if needed. vehicle.mode = VehicleMode("GUIDED") - # Set the location to goto() and flush() + # Set the location to head towards a_location = Location(-34.364114, 149.166022, 30, is_relative=True) vehicle.commands.goto(a_location) - vehicle.flush() :param Location location: The target location. ''' @@ -1008,6 +1005,8 @@ def clear(self): def add(self, cmd): ''' Add a new command (waypoint) at the end of the command list. + + .. note:: Commands are sent to the vehicle only after you call :py:func:`Vehicle.flush`. :param Command cmd: The command to be added. ''' diff --git a/examples/channel_overrides/channel_overrides.py b/examples/channel_overrides/channel_overrides.py index 0ff0ed2d7..89066ce0b 100644 --- a/examples/channel_overrides/channel_overrides.py +++ b/examples/channel_overrides/channel_overrides.py @@ -33,7 +33,6 @@ #Override channels print "\nOverriding RC channels for roll and yaw" vehicle.channel_override = { "1" : 900, "4" : 1000 } -vehicle.flush() print " Current overrides are:", vehicle.channel_override # Get all original channel values (before override) @@ -42,7 +41,6 @@ # Cancel override by setting channels to 0 print " Cancelling override" vehicle.channel_override = { "1" : 0, "4" : 0 } -vehicle.flush() # Short wait before exiting time.sleep(5) diff --git a/examples/drone_delivery/drone_delivery.py b/examples/drone_delivery/drone_delivery.py index 496f0a00f..768137e42 100644 --- a/examples/drone_delivery/drone_delivery.py +++ b/examples/drone_delivery/drone_delivery.py @@ -68,12 +68,10 @@ def __init__(self, home_coords, server_enabled=True): def takeoff(self): self._log("Taking off") self.commands.takeoff(30.0) - self.vehicle.flush() def arm(self): self._log("Arming") self.vehicle.armed = True - self.vehicle.flush() def run(self): self._log('Running initial boot sequence') @@ -98,9 +96,8 @@ def _run_server(self): def change_mode(self, mode): self._log("Mode: {0}".format(mode)) - self.vehicle.mode = VehicleMode(mode) - self.vehicle.flush() + def goto(self, location, relative=None): self._log("Goto: {0}, {1}".format(location, self.altitude)) @@ -112,7 +109,6 @@ def goto(self, location, relative=None): is_relative=relative ) ) - self.vehicle.flush() def get_location(self): return [self.current_location.lat, self.current_location.lon] diff --git a/examples/follow_me/follow_me.py b/examples/follow_me/follow_me.py index 253f9ca44..05b891523 100644 --- a/examples/follow_me/follow_me.py +++ b/examples/follow_me/follow_me.py @@ -47,7 +47,6 @@ def arm_and_takeoff(aTargetAltitude): # Copter should arm in GUIDED mode vehicle.mode = VehicleMode("GUIDED") vehicle.armed = True - vehicle.flush() while not vehicle.armed: print " Waiting for arming..." @@ -55,7 +54,6 @@ def arm_and_takeoff(aTargetAltitude): print "Taking off!" vehicle.commands.takeoff(aTargetAltitude) # Take off to target altitude - vehicle.flush() # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.commands.takeoff will execute immediately). @@ -92,7 +90,6 @@ def arm_and_takeoff(aTargetAltitude): # A better implementation would only send new waypoints if the position had changed significantly vehicle.commands.goto(dest) - vehicle.flush() # Send a new target every two seconds # For a complete implementation of follow me you'd want adjust this delay diff --git a/examples/gcs/microgcs.py b/examples/gcs/microgcs.py index 6b1ed878d..720589416 100644 --- a/examples/gcs/microgcs.py +++ b/examples/gcs/microgcs.py @@ -1,10 +1,8 @@ # # This is a small example of the python drone API - an ultra minimal GCS -# Usage: -# * mavproxy.py --master=/dev/ttyACM0,115200 -# * module load api -# * api start microgcs.py # + +from dronekit import connect from dronekit.lib import VehicleMode from pymavlink import mavutil from Tkinter import * @@ -12,17 +10,22 @@ # The tkinter root object global root -# First get an instance of the API endpoint -api = local_connect() -# get our vehicle - when running with mavproxy it only knows about one vehicle (for now) -v = api.get_vehicles()[0] +#Set up option parsing to get connection string +import argparse +parser = argparse.ArgumentParser(description='Tracks GPS position of your computer (Linux only). Connects to SITL on local PC by default.') +parser.add_argument('--connect', default='127.0.0.1:14550', + help="vehicle connection target. Default '127.0.0.1:14550'") +args = parser.parse_args() + + +# Connect to the Vehicle +print 'Connecting to vehicle on: %s' % args.connect +vehicle = connect(args.connect, await_params=True) def setMode(mode): # Now change the vehicle into auto mode - v.mode = VehicleMode(mode) + vehicle.mode = VehicleMode(mode) - # Always call flush to guarantee that previous writes to the vehicle have taken place - v.flush() def updateGUI(label, value): label['text'] = value @@ -30,7 +33,7 @@ def updateGUI(label, value): def addObserverAndInit(name, cb): """We go ahead and call our observer once at startup to get an initial value""" cb(name) - v.add_attribute_observer(name, cb) + vehicle.add_attribute_observer(name, cb) root = Tk() root.wm_title("microGCS - the worlds crummiest GCS") @@ -44,9 +47,9 @@ def addObserverAndInit(name, cb): modeLabel = Label(frame, text = "mode") modeLabel.pack() -addObserverAndInit('attitude', lambda attr: updateGUI(attitudeLabel, v.attitude)) -addObserverAndInit('location', lambda attr: updateGUI(locationLabel, v.location)) -addObserverAndInit('mode', lambda attr: updateGUI(modeLabel, v.mode)) +addObserverAndInit('attitude', lambda attr: updateGUI(attitudeLabel, vehicle.attitude)) +addObserverAndInit('location', lambda attr: updateGUI(locationLabel, vehicle.location)) +addObserverAndInit('mode', lambda attr: updateGUI(modeLabel, vehicle.mode)) Button(frame, text = "Auto", command = lambda : setMode("AUTO")).pack() Button(frame, text = "RTL", command = lambda : setMode("RTL")).pack() diff --git a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py index 818e11fbc..91cf0a19c 100644 --- a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py +++ b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py @@ -43,7 +43,6 @@ def arm_and_takeoff(aTargetAltitude): # Copter should arm in GUIDED mode vehicle.mode = VehicleMode("GUIDED") vehicle.armed = True - vehicle.flush() while not vehicle.armed: print " Waiting for arming..." @@ -51,7 +50,6 @@ def arm_and_takeoff(aTargetAltitude): print "Taking off!" vehicle.commands.takeoff(aTargetAltitude) # Take off to target altitude - vehicle.flush() # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.commands.takeoff will execute immediately). @@ -112,7 +110,6 @@ def condition_yaw(heading, relative=False): 0, 0, 0) # param 5 ~ 7 not used # send command to vehicle vehicle.send_mavlink(msg) - vehicle.flush() def set_roi(location): @@ -135,7 +132,6 @@ def set_roi(location): ) # send command to vehicle vehicle.send_mavlink(msg) - vehicle.flush() def set_speed(speed): @@ -163,7 +159,6 @@ def set_speed(speed): # send command to vehicle vehicle.send_mavlink(msg) - vehicle.flush() def set_home(aLocation, aCurrent=1): @@ -188,7 +183,6 @@ def set_home(aLocation, aCurrent=1): ) # send command to vehicle vehicle.send_mavlink(msg) - vehicle.flush() @@ -300,7 +294,6 @@ def goto_position_target_global_int(aLocation): 0, 0) # yaw, yaw_rate (not supported yet, ignored in GCS_Mavlink) # send command to vehicle vehicle.send_mavlink(msg) - vehicle.flush() @@ -334,7 +327,6 @@ def goto_position_target_local_ned(north, east, down): 0, 0) # yaw, yaw_rate (not supported yet, ignored in GCS_Mavlink) # send command to vehicle vehicle.send_mavlink(msg) - vehicle.flush() @@ -352,7 +344,6 @@ def goto(dNorth, dEast, gotoFunction=vehicle.commands.goto): targetLocation=get_location_metres(currentLocation, dNorth, dEast) targetDistance=get_distance_metres(currentLocation, targetLocation) gotoFunction(targetLocation) - vehicle.flush() while vehicle.mode.name=="GUIDED": #Stop action if we are no longer in guided mode. @@ -395,7 +386,6 @@ def send_ned_velocity(velocity_x, velocity_y, velocity_z): 0, 0) # yaw, yaw_rate (not supported yet, ignored in GCS_Mavlink) # send command to vehicle vehicle.send_mavlink(msg) - vehicle.flush() @@ -425,7 +415,6 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z): 0, 0) # yaw, yaw_rate (not supported yet, ignored in GCS_Mavlink) # send command to vehicle vehicle.send_mavlink(msg) - vehicle.flush() @@ -642,7 +631,6 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z): print("Setting LAND mode...") vehicle.mode = VehicleMode("LAND") -vehicle.flush() #Close vehicle object before exiting script diff --git a/examples/mission_basic/mission_basic.py b/examples/mission_basic/mission_basic.py index c644ef555..36a5e912d 100644 --- a/examples/mission_basic/mission_basic.py +++ b/examples/mission_basic/mission_basic.py @@ -151,7 +151,6 @@ def arm_and_takeoff(aTargetAltitude): # Copter should arm in GUIDED mode vehicle.mode = VehicleMode("GUIDED") vehicle.armed = True - vehicle.flush() while not vehicle.armed: print " Waiting for arming..." @@ -159,7 +158,6 @@ def arm_and_takeoff(aTargetAltitude): print "Taking off!" vehicle.commands.takeoff(aTargetAltitude) # Take off to target altitude - vehicle.flush() # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.commands.takeoff will execute immediately). @@ -186,7 +184,7 @@ def arm_and_takeoff(aTargetAltitude): print "Starting mission" # Set mode to AUTO to start mission vehicle.mode = VehicleMode("AUTO") -vehicle.flush() + # Monitor mission. # Demonstrates getting and setting the command number @@ -207,7 +205,7 @@ def arm_and_takeoff(aTargetAltitude): print 'Return to launch' vehicle.mode = VehicleMode("RTL") -vehicle.flush() # Flush to ensure changes are sent to autopilot + #Close vehicle object before exiting script print "Close vehicle object" diff --git a/examples/perf/perf_test.py b/examples/perf/perf_test.py index 03a334e53..e43d590d3 100644 --- a/examples/perf/perf_test.py +++ b/examples/perf/perf_test.py @@ -1,10 +1,7 @@ # # This is a small example of the python drone API -# Usage: -# * mavproxy.py -# * module load api -# * api start small-demo.py # +from dronekit import connect from dronekit.lib import VehicleMode from pymavlink import mavutil import time @@ -103,7 +100,19 @@ mavproxy.py --master=/dev/ttyMFD1,115200 --cmd="api start perf_test.py" """ -global v +#Set up option parsing to get connection string +import argparse +parser = argparse.ArgumentParser(description='Example that demonstrates mission import/export from a file. Connects to SITL on local PC by default.') +parser.add_argument('--connect', default='127.0.0.1:14550', + help="vehicle connection target. Default '127.0.0.1:14550'") +args = parser.parse_args() + + +# Connect to the Vehicle +print 'Connecting to vehicle on: %s' % args.connect +vehicle = connect(args.connect, await_params=True) + +#global vehicle def scatterplot(x,y): @@ -168,7 +177,7 @@ def send_testpackets(): #print "send ROI cmds" # create the SET_POSITION_TARGET_GLOBAL_INT command - msg = v.message_factory.set_position_target_global_int_encode( + msg = vehicle.message_factory.set_position_target_global_int_encode( 0, # time_boot_ms (not used) 1, 1, # target system, target component mavutil.mavlink.MAV_FRAME_GLOBAL, # frame @@ -179,10 +188,10 @@ def send_testpackets(): 0, 0) # yaw, yaw_rate (not used) # send command to vehicle - v.send_mavlink(msg) + vehicle.send_mavlink(msg) # set ROI - msg = v.message_factory.command_long_encode( + msg = vehicle.message_factory.command_long_encode( 1, 1, # target system, target component #mavutil.mavlink.MAV_CMD_DO_SET_RELAY, #command mavutil.mavlink.MAV_CMD_DO_SET_ROI, #command @@ -193,67 +202,37 @@ def send_testpackets(): 0 ) - v.send_mavlink(msg) + vehicle.send_mavlink(msg) - # Always call flush to guarantee that previous writes to the vehicle have taken place - v.flush() -# First get an instance of the API endpoint -api = local_connect() -# get our vehicle - when running with mavproxy it only knows about one vehicle (for now) -v = api.get_vehicles()[0] # Print out some interesting stats about the vehicle -print "Mode: %s" % v.mode -print "Location: %s" % v.location -print "Attitude: %s" % v.attitude -print "Velocity: %s" % v.velocity -print "GPS: %s" % v.gps_0 -print "Armed: %s" % v.armed -print "groundspeed: %s" % v.groundspeed -print "airspeed: %s" % v.airspeed +print "Mode: %s" % vehicle.mode +print "Location: %s" % vehicle.location +print "Attitude: %s" % vehicle.attitude +print "Velocity: %s" % vehicle.velocity +print "GPS: %s" % vehicle.gps_0 +print "Armed: %s" % vehicle.armed +print "groundspeed: %s" % vehicle.groundspeed +print "airspeed: %s" % vehicle.airspeed import time time.sleep(30) # Use of the following method is not recommended (it is better to add observer callbacks to attributes) but if you need it # it is available... -v.set_mavlink_callback(mavrx_debug_handler) +vehicle.set_mavlink_callback(mavrx_debug_handler) # You can read and write parameters -#print "Param: %s" % v.parameters['THR_MAX'] +#print "Param: %s" % vehicle.parameters['THR_MAX'] # Now download the vehicle waypoints -cmds = v.commands +cmds = vehicle.commands cmds.download() cmds.wait_valid() print "Home WP: %s" % cmds[0] print "Current dest: %s" % cmds.next -# Test custom commands -# Note: For mavlink messages that include a target_system & target_component, those values -# can just be filled with zero. The API will take care of using the correct values -# For instance, from the xml for command_long: -# Send a command with up to seven parameters to the MAV -# -# target_system : System which should execute the command (uint8_t) -# target_component : Component which should execute the command, 0 for all components (uint8_t) -# command : Command ID, as defined by MAV_CMD enum. (uint16_t) -# confirmation : 0: First transmission of this command. 1-255: Confirmation transmissions (e.g. for kill command) (uint8_t) -# param1 : Parameter 1, as defined by MAV_CMD enum. (float) -# param2 : Parameter 2, as defined by MAV_CMD enum. (float) -# param3 : Parameter 3, as defined by MAV_CMD enum. (float) -# param4 : Parameter 4, as defined by MAV_CMD enum. (float) -# param5 : Parameter 5, as defined by MAV_CMD enum. (float) -# param6 : Parameter 6, as defined by MAV_CMD enum. (float) -# param7 : Parameter 7, as defined by MAV_CMD enum. (float) -#msg = v.message_factory.command_long_encode(0, 0, -# mavutil.mavlink.MAV_CMD_CONDITION_YAW, 0, -# 0, 0, 0, 0, 1, 0, 0) -#print "Created msg: %s" % msg -#v.send_mavlink(msg) print "Disarming..." -v.armed = False -v.flush() +vehicle.armed = False -# send_testpackets() diff --git a/examples/simple_goto/simple_goto.py b/examples/simple_goto/simple_goto.py index 53f9d0d0e..d3ff8afb5 100644 --- a/examples/simple_goto/simple_goto.py +++ b/examples/simple_goto/simple_goto.py @@ -44,7 +44,6 @@ def arm_and_takeoff(aTargetAltitude): # Copter should arm in GUIDED mode vehicle.mode = VehicleMode("GUIDED") vehicle.armed = True - vehicle.flush() while not vehicle.armed: print " Waiting for arming..." @@ -52,7 +51,6 @@ def arm_and_takeoff(aTargetAltitude): print "Taking off!" vehicle.commands.takeoff(aTargetAltitude) # Take off to target altitude - vehicle.flush() # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.commands.takeoff will execute immediately). @@ -69,7 +67,6 @@ def arm_and_takeoff(aTargetAltitude): print "Going to first point..." point1 = Location(-35.361354, 149.165218, 20, is_relative=True) vehicle.commands.goto(point1) -vehicle.flush() # sleep so we can see the change in map time.sleep(30) @@ -77,14 +74,12 @@ def arm_and_takeoff(aTargetAltitude): print "Going to second point..." point2 = Location(-35.363244, 149.168801, 20, is_relative=True) vehicle.commands.goto(point2) -vehicle.flush() # sleep so we can see the change in map time.sleep(30) print "Returning to Launch" vehicle.mode = VehicleMode("RTL") -vehicle.flush() #Close vehicle object before exiting script print "Close vehicle object" diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 46fa0d4a6..cad36ba5c 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -53,7 +53,6 @@ # Set vehicle mode and armed attributes (the only settable attributes) print "\nSet Vehicle.mode=GUIDED (currently: %s)" % vehicle.mode.name vehicle.mode = VehicleMode("GUIDED") -vehicle.flush() # Flush to guarantee that previous writes to the vehicle have taken place while not vehicle.mode.name=='GUIDED': #Wait until mode has changed print " Waiting for mode change ..." time.sleep(1) @@ -67,7 +66,6 @@ print "\nSet Vehicle.armed=True (currently: %s)" % vehicle.armed vehicle.armed = True -vehicle.flush() while not vehicle.armed: print " Waiting for arming..." time.sleep(1) @@ -82,7 +80,6 @@ def mode_callback(attribute): print " Set mode=STABILIZE (currently: %s)" % vehicle.mode.name vehicle.mode = VehicleMode("STABILIZE") -vehicle.flush() print " Wait 2s so callback invoked before observer removed" time.sleep(2) @@ -103,7 +100,6 @@ def mode_callback(attribute): print "\nRead vehicle param 'THR_MIN': %s" % vehicle.parameters['THR_MIN'] print "Write vehicle param 'THR_MIN' : 10" vehicle.parameters['THR_MIN']=10 -vehicle.flush() print "Read new value of param 'THR_MIN': %s" % vehicle.parameters['THR_MIN'] @@ -112,7 +108,6 @@ def mode_callback(attribute): vehicle.mode = VehicleMode("STABILIZE") vehicle.armed = False vehicle.parameters['THR_MIN']=130 -vehicle.flush() #Close vehicle object before exiting script diff --git a/tests/sitl/test_110.py b/tests/sitl/test_110.py index da8203b22..c7afed19e 100644 --- a/tests/sitl/test_110.py +++ b/tests/sitl/test_110.py @@ -40,7 +40,6 @@ def armed_callback(attribute): # Disarm and see update. v.armed = False - v.flush() # Wait for ACK. time.sleep(3) @@ -58,7 +57,6 @@ def armed_callback(attribute): # Re-arm and see update. v.armed = True - v.flush() # Wait for ack time.sleep(3) diff --git a/tests/sitl/test_115.py b/tests/sitl/test_115.py index 93d4c0d86..834357f45 100644 --- a/tests/sitl/test_115.py +++ b/tests/sitl/test_115.py @@ -33,7 +33,6 @@ def mavlink_callback(*args): # Disarm. A callback of None should not throw errors v.armed = False - v.flush() # NOTE wait crudely for ACK on mode update time.sleep(3) @@ -42,6 +41,5 @@ def mavlink_callback(*args): # Re-arm should not throw errors. v.armed = True - v.flush() # NOTE wait crudely for ACK on mode update time.sleep(3) diff --git a/tests/sitl/test_goto.py b/tests/sitl/test_goto.py index 3327ab7f8..ee7f9a649 100644 --- a/tests/sitl/test_goto.py +++ b/tests/sitl/test_goto.py @@ -43,7 +43,6 @@ def arm_and_takeoff(aTargetAltitude): # print "Arming motors" # Copter should arm in GUIDED mode vehicle.mode = VehicleMode("GUIDED") - vehicle.flush() i = 60 while vehicle.mode.name != 'GUIDED' and i > 0: @@ -52,7 +51,6 @@ def arm_and_takeoff(aTargetAltitude): i = i - 1 vehicle.armed = True - vehicle.flush() i = 60 while not vehicle.armed and vehicle.mode.name == 'GUIDED' and i > 0: @@ -66,7 +64,6 @@ def arm_and_takeoff(aTargetAltitude): # print "Taking off!" vehicle.commands.takeoff(aTargetAltitude) # Take off to target altitude - vehicle.flush() # Wait until the vehicle reaches a safe height before # processing the goto (otherwise the command after @@ -86,7 +83,6 @@ def arm_and_takeoff(aTargetAltitude): # print "Going to first point..." point1 = LocationGlobal(-35.361354, 149.165218, 20, is_relative=True) vehicle.commands.goto(point1) - vehicle.flush() # sleep so we can see the change in map time.sleep(3) @@ -94,11 +90,9 @@ def arm_and_takeoff(aTargetAltitude): # print "Going to second point..." point2 = LocationGlobal(-35.363244, 149.168801, 20, is_relative=True) vehicle.commands.goto(point2) - vehicle.flush() # sleep so we can see the change in map time.sleep(3) # print "Returning to Launch" vehicle.mode = VehicleMode("RTL") - vehicle.flush() From daae4d45c34d67d121f5bfea8d97c4290b3f8880 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 26 Oct 2015 13:45:30 +1100 Subject: [PATCH 066/475] Fix up API Reference so that connect is used rather than APICOnnection etc --- docs/automodule.rst | 2 +- dronekit/lib/__init__.py | 48 ++++++++++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/docs/automodule.rst b/docs/automodule.rst index 28b53c593..5a43bb22f 100644 --- a/docs/automodule.rst +++ b/docs/automodule.rst @@ -8,7 +8,7 @@ DroneKit-Python API Reference .. automodule:: dronekit.lib :members: :inherited-members: - :exclude-members: Mission, get_mission, ConnectionInfo, web_connect, AuthInfo, delete + :exclude-members: Mission, get_mission, ConnectionInfo, web_connect, AuthInfo, delete, notify_observers, remove_all_observers, local_connect, APIConnection diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index fca5ab064..e12d060c0 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -4,34 +4,55 @@ This is the API Reference for the DroneKit-Python API. The main API is the :py:class:`Vehicle ` class. -The code snippet below shows how to obtain an instance of the (first) connected vehicle: +The code snippet below shows how to use :py:func:`connect` to obtain an instance a connected vehicle: .. code:: python - # Get a local APIConnection to the autopilot (from companion computer or GCS). - api_connection = local_connect() - # Get the first connected vehicle from the APIConnection - vehicle = api.get_vehicles()[0] + from dronekit import connect + + # Connect to the Vehicle using "connection string" (in this case an address on network) + vehicle = connect('127.0.0.1:14550', await_params=True) + :py:class:`Vehicle ` provides access to vehicle *state* through python attributes -(e.g. :py:attr:`Vehicle.location `) +(e.g. :py:attr:`Vehicle.mode `) and to settings/parameters though the :py:attr:`Vehicle.parameters ` attribute. Asynchronous notification on vehicle attribute changes is available by registering observers. :py:class:`Vehicle ` provides two main ways to control vehicle movement and other operations: -* Missions are downloaded and uploaded through the :py:attr:`Vehicle.commands ` attribute - (see :py:class:`CommandSequence ` for more information). * Direct control of movement outside of missions is also supported. To set a target position you can use :py:func:`CommandSequence.goto `. Control over speed, direction, altitude, camera trigger and any other aspect of the vehicle is supported using custom MAVLink messages (:py:func:`Vehicle.send_mavlink `, :py:func:`Vehicle.message_factory `). - +* Missions are downloaded and uploaded through the :py:attr:`Vehicle.commands ` attribute + (see :py:class:`CommandSequence ` for more information). + A number of other useful classes and methods are listed below. ---- .. todo:: Update this when have confirmed how to register for parameter notifications. + + + +.. py:function:: connect(ip, await_params=False, status_printer=errprinter, vehicle_class=Vehicle, rate=4) + + Returns a :py:class:`Vehicle` object connected to the address specified by string parameter ``ip``. + Connection string parameters for different targets are listed in the :ref:`getting started guide `. + + :param String ip: Connection string for target address - e.g. 127.0.0.1:14550. + :param Bool await_params: Wait until all :py:func:`Vehicle.parameters` have downloaded before the method returns (default is false) + :param status_printer: NA + :param Vehicle vehicle_class: NA + :param int rate: NA + + :returns: A connected :py:class:`Vehicle` object. + +---- + + .. todo:: Confirm what status_printer, vehicle_class and rate "mean". Can we hide in API. Can we get method defined in this file. + """ import threading @@ -266,10 +287,6 @@ def mode_callback(self, mode): .. code:: python - # Get an instance of the API endpoint and a vehicle - api = local_connect() - vehicle = api.get_vehicles()[0] - # Set the vehicle into auto mode vehicle.mode = VehicleMode("AUTO") @@ -908,9 +925,8 @@ class CommandSequence(object): .. code-block:: python :emphasize-lines: 5-10 - # Connect to API provider and get vehicle - api = local_connect() - vehicle = api.get_vehicles()[0] + #Connect to a vehicle object (for example, on com14) + vehicle = connect('com14', await_params=True) # Download the vehicle waypoints (commands). Wait until download is complete. cmds = vehicle.commands From 3bd0f5304351eb4ca7fff77731d8f5aab7cae166 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 26 Oct 2015 13:46:07 +1100 Subject: [PATCH 067/475] Fix layout issue in todo reminder note - just removes build warnings --- docs/examples/mission_import_export.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/examples/mission_import_export.rst b/docs/examples/mission_import_export.rst index f8252d4a6..3e2245dd7 100644 --- a/docs/examples/mission_import_export.rst +++ b/docs/examples/mission_import_export.rst @@ -139,7 +139,9 @@ Known issues This is blocked by https://github.com/dronekit/dronekit-python/issues/355 (vehicle.commands.clear not working). The code output in "running the example"" needs to be updated once this runs cleanly. The above text for the error needs to be replaced with original text - > "This example works around known issues in the API:." + + > "This example works around known issues in the API:." + Need to check all that clearing is still strictly necessary in DKPY2 which handles race conditions more gracefully. From bed6320aa27601899599547f956dc3ffe3af5d5e Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 26 Oct 2015 20:12:45 +1100 Subject: [PATCH 068/475] Global updates to fix the examples to use LocationGlobal rather than Location --- docs/examples/drone_delivery.rst | 2 +- docs/examples/follow_me.rst | 2 +- docs/examples/guided-set-speed-yaw-demo.rst | 8 ++-- docs/examples/mission_basic.rst | 2 +- docs/examples/simple_goto.rst | 4 +- docs/examples/vehicle_state.rst | 15 +++--- docs/guide/auto_mode.rst | 8 ++-- docs/guide/copter/guided_mode.rst | 36 +++++++-------- docs/guide/taking_off.rst | 8 ++-- docs/guide/vehicle_state_and_parameters.rst | 11 +++-- dronekit/lib/__init__.py | 39 +++++++++------- examples/drone_delivery/drone_delivery.py | 4 +- examples/follow_me/follow_me.py | 9 ++-- .../guided_set_speed_yaw.py | 46 ++++++++++--------- examples/mission_basic/mission_basic.py | 20 ++++---- examples/simple_goto/simple_goto.py | 15 +++--- examples/vehicle_state/vehicle_state.py | 8 ++-- 17 files changed, 125 insertions(+), 112 deletions(-) diff --git a/docs/examples/drone_delivery.rst b/docs/examples/drone_delivery.rst index b73904ce8..581021f35 100644 --- a/docs/examples/drone_delivery.rst +++ b/docs/examples/drone_delivery.rst @@ -114,7 +114,7 @@ All attributes in DroneKit can have observers - this is the primary mechanism yo ... def location_callback(self, location): - location = self.vehicle.location + location = self.vehicle.location.global_frame if location.alt is not None: self.altitude = location.alt diff --git a/docs/examples/follow_me.rst b/docs/examples/follow_me.rst index 5f3c4d33d..78a886d2d 100644 --- a/docs/examples/follow_me.rst +++ b/docs/examples/follow_me.rst @@ -137,7 +137,7 @@ the mode is changed. # Once we have a valid location (see gpsd documentation) we can start moving our vehicle around if (gpsd.valid & gps.LATLON_SET) != 0: altitude = 30 # in meters - dest = Location(gpsd.fix.latitude, gpsd.fix.longitude, altitude, is_relative=True) + dest = LocationGlobal(gpsd.fix.latitude, gpsd.fix.longitude, altitude, is_relative=True) print "Going to: %s" % dest # A better implementation would only send new waypoints if the position had changed significantly diff --git a/docs/examples/guided-set-speed-yaw-demo.rst b/docs/examples/guided-set-speed-yaw-demo.rst index c39a53314..f76961d8c 100644 --- a/docs/examples/guided-set-speed-yaw-demo.rst +++ b/docs/examples/guided-set-speed-yaw-demo.rst @@ -201,13 +201,13 @@ This takes a function argument of either :ref:`Vehicle.commands.goto() ` is relatively self-do operations are explained in the guide topic :ref:`auto_mode_vehicle_control` . In overview, the example first calls ``clear_mission()`` to clear the current mission and then creates and -uploads a new mission using ``adds_square_mission(vehicle.location,50)``. This function defines a mission with a takeoff +uploads a new mission using ``adds_square_mission(vehicle.location.global_frame,50)``. This function defines a mission with a takeoff command and four waypoints arranged in a square around the central position. After taking off (in guided mode using the ``takeoff()`` function) the example starts the mission by setting the mode to AUTO: diff --git a/docs/examples/simple_goto.rst b/docs/examples/simple_goto.rst index aafd268b8..0440eef39 100644 --- a/docs/examples/simple_goto.rst +++ b/docs/examples/simple_goto.rst @@ -120,11 +120,11 @@ Flying to a point - Goto ------------------------ The vehicle is already in ``GUIDED`` mode, so to send it to a certain point we just need to -call :py:func:`Vehicle.commands.goto() ` with the target location: +call :py:func:`Vehicle.commands.goto() ` with the target ``LocationGlobal``: .. code-block:: python - point1 = Location(-35.361354, 149.165218, 20, is_relative=True) + point1 = LocationGlobal(-35.361354, 149.165218, 20, is_relative=True) vehicle.commands.goto(point1) # sleep so we can see the change in map diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index 2f2497626..6f4c5bacf 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -7,15 +7,15 @@ Example: Vehicle State This example shows how to get/set vehicle attribute and parameter information, how to observe vehicle attribute changes, and how to get the home position. -The guide topic :ref:`vehicle-information` provides a more detailed explanation of how the API -should be used. +The guide topic :ref:`vehicle-information` provides a more detailed explanation +of how the API should be used. Running the example =================== -The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle -and DroneKit have been set up as described in :ref:`get-started`). +The example can be run as described in :doc:`running_examples` (which in turn assumes that +the vehicle and DroneKit have been set up as described in :ref:`get-started`). If you're using a simulated vehicle remember to :ref:`disable arming checks ` so that the example can run. You can also @@ -56,7 +56,8 @@ On the command prompt you should see (something like): Accumulating vehicle attribute messages (2s) Get all vehicle attribute values: - Location: Location:lat=-35.3632601,lon=149.1652279,alt=-0.00999999977648,is_relative=False + Global Location: LocationGlobal:lat=-35.363261,lon=149.1652299,alt=0.0,is_relative=False + Local Location: LocationLocal:north=None,east=None,down=None Attitude: Attitude:pitch=0.00486609805375,yaw=0.489637970924,roll=0.00645932834595 Velocity: [-0.12, 0.06, 0.0] GPS: GPSInfo:fix=3,num_sat=10 @@ -117,10 +118,8 @@ Known issues This example works around the :ref:`known issues in the API `. Provided that the vehicle is connected and able to arm, it should run through to completion. -Two cases where you may observe issues are: +You may observe these issues: -* You will see an error ``Timeout setting THR_MIN to 10.000000``. This can be ignored because the value is actually set. - See `#12 Timeout error when setting a parameter `_ for information. * When the observer sets the mode callback, it waits two seconds after changing the mode before removing the observer (to ensure that the callback function is run before the observer is removed). In this time you may see the callback being called twice even though the mode is only changed once. diff --git a/docs/guide/auto_mode.rst b/docs/guide/auto_mode.rst index b7ed4eb2f..6cbeb4426 100644 --- a/docs/guide/auto_mode.rst +++ b/docs/guide/auto_mode.rst @@ -343,8 +343,8 @@ The commands are added to a list which is returned by the function. ln_param4=float(linearray[7]) ln_param5=float(linearray[8]) ln_param6=float(linearray[9]) - ln_param7=float(linearray[10]) - ln_autocontinue=int(linearray[11].strip()) + ln_param7=float(linearray[10]) + ln_autocontinue=int(linearray[11].strip()) cmd = Command( 0, 0, 0, ln_frame, ln_command, ln_currentwp, ln_autocontinue, ln_param1, ln_param2, ln_param3, ln_param4, ln_param5, ln_param6, ln_param7) missionlist.append(cmd) return missionlist @@ -416,8 +416,8 @@ Get distance to waypoint lat=missionitem.x lon=missionitem.y alt=missionitem.z - targetWaypointLocation=Location(lat,lon,alt,is_relative=True) - distancetopoint = get_distance_metres(vehicle.location, targetWaypointLocation) + targetWaypointLocation=LocationGlobal(lat,lon,alt,is_relative=True) + distancetopoint = get_distance_metres(vehicle.location.global_frame, targetWaypointLocation) return distancetopoint The function determines the current target waypoint number with :py:func:`Vehicle.commands.next ` diff --git a/docs/guide/copter/guided_mode.rst b/docs/guide/copter/guided_mode.rst index 97e0b2d4e..861d4950b 100644 --- a/docs/guide/copter/guided_mode.rst +++ b/docs/guide/copter/guided_mode.rst @@ -37,7 +37,7 @@ Position control Controlling the vehicle by explicitly setting the target position is useful when the final position is known/fixed. -The recommended method for position control is :py:func:`Vehicle.commands.goto() `. This takes a :py:class:`Location ` argument for the target position in the global `WGS84 coordinate system `_, but with altitude relative to the home location (home altitude = 0). +The recommended method for position control is :py:func:`Vehicle.commands.goto() `. This takes a :py:class:`LocationGlobal ` argument for the target position in the global `WGS84 coordinate system `_, but with altitude relative to the home location (home altitude = 0). The method is used as shown below: @@ -46,8 +46,8 @@ The method is used as shown below: # Set mode to guided - this is optional as the goto method will change the mode if needed. vehicle.mode = VehicleMode("GUIDED") - # Set the target location - a_location = Location(-34.364114, 149.166022, 30, is_relative=True) + # Set the target location in global frame + a_location = LocationGlobal(-34.364114, 149.166022, 30, is_relative=True) vehicle.commands.goto(a_location) @@ -282,8 +282,8 @@ The command is useful when setting the vehicle position directly. It is not need Setting the ROI --------------- -Send the `MAV_CMD_DO_SET_ROI `_ command to point camera gimbal at a specified region of interest (:py:class:`Location `). The vehicle may also turn to face the ROI. - +Send the `MAV_CMD_DO_SET_ROI `_ command to point camera gimbal at a specified region of interest (:py:class:`LocationGlobal `). The vehicle may also turn to face the ROI. + .. code-block:: python def set_roi(location): @@ -336,8 +336,8 @@ The *home location* is updated immediately in ArduPilot, but the change may not .. code-block:: python - # Set new Home location to current location - set_home(vehicle.location) + # Set new Home location to current LocationGlobal + set_home(vehicle.location.global_frame) # Reloads the home location in GCSs cmds = vehicle.commands cmds.download() @@ -370,8 +370,8 @@ to the Earth's poles. def get_location_metres(original_location, dNorth, dEast): """ - Returns a Location object containing the latitude/longitude `dNorth` and `dEast` metres from the - specified `original_location`. The returned Location has the same `alt and `is_relative` values + Returns a LocationGlobal object containing the latitude/longitude `dNorth` and `dEast` metres from the + specified `original_location`. The returned LocationGlobal has the same `alt and `is_relative` values as `original_location`. The function is useful when you want to move the vehicle around specifying locations relative to @@ -390,34 +390,34 @@ to the Earth's poles. #New position in decimal degrees newlat = original_location.lat + (dLat * 180/math.pi) newlon = original_location.lon + (dLon * 180/math.pi) - return Location(newlat, newlon,original_location.alt,original_location.is_relative) + return LocationGlobal(newlat, newlon,original_location.alt,original_location.is_relative) .. code-block:: python def get_distance_metres(aLocation1, aLocation2): """ - Returns the ground distance in metres between two Location objects. - + Returns the ground distance in metres between two LocationGlobal objects. + This method is an approximation, and will not be accurate over large distances and close to the earth's poles. It comes from the ArduPilot test code: https://github.com/diydrones/ardupilot/blob/master/Tools/autotest/common.py """ - dlat = aLocation2.lat - aLocation1.lat - dlong = aLocation2.lon - aLocation1.lon + dlat = aLocation2.lat - aLocation1.lat + dlong = aLocation2.lon - aLocation1.lon return math.sqrt((dlat*dlat) + (dlong*dlong)) * 1.113195e5 - + .. code-block:: python def get_bearing(aLocation1, aLocation2): """ - Returns the bearing between the two Location objects passed as parameters. - + Returns the bearing between the two LocationGlobal objects passed as parameters. + This method is an approximation, and may not be accurate over large distances and close to the earth's poles. It comes from the ArduPilot test code: https://github.com/diydrones/ardupilot/blob/master/Tools/autotest/common.py - """ + """ off_x = aLocation2.lon - aLocation1.lon off_y = aLocation2.lat - aLocation1.lat bearing = 90.00 + math.atan2(-off_y, off_x) * 57.2957795 diff --git a/docs/guide/taking_off.rst b/docs/guide/taking_off.rst index 40a1f6421..369444125 100644 --- a/docs/guide/taking_off.rst +++ b/docs/guide/taking_off.rst @@ -55,8 +55,8 @@ The code below shows a function to arm a Copter, take off, and fly to a specifie # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.commands.takeoff will execute immediately). while True: - print " Altitude: ", vehicle.location.alt - if vehicle.location.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. + print " Altitude: ", vehicle.location.global_frame.alt + if vehicle.location.global_frame.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. print "Reached target altitude" break time.sleep(1) @@ -111,8 +111,8 @@ concerned about reaching a particular height, a simpler implementation might jus .. code-block:: python while True: - print " Altitude: ", vehicle.location.alt - if vehicle.location.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. + print " Altitude: ", vehicle.location.global_frame.alt + if vehicle.location.global_frame.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. print "Reached target altitude" break time.sleep(1) diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index c86d9a943..d5e08606e 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -50,7 +50,8 @@ The code fragment below shows how to read and print all the attributes. The valu .. code:: python # vehicle is an instance of the Vehicle class - print "Location: %s" % vehicle.location + print "Global Location: %s" % vehicle.location.global_frame + print "Local Location: %s" % vehicle.location.local_frame #NED print "Attitude: %s" % vehicle.attitude print "Velocity: %s" % vehicle.velocity print "GPS: %s" % vehicle.gps_0 @@ -140,8 +141,9 @@ attribute changes. The two second ``sleep()`` is required because otherwise the # Callback function. The parameter is the name of the observed attribute (a string) def location_callback(attribute): - print " CALLBACK: Location changed to: ", vehicle.location - + print " CALLBACK: Global Location changed to: ", vehicle.location.global_frame + print " CALLBACK: Location changed to: ", vehicle.location.local_frame + # Add a callback. The first parameter the name of the observed attribute (a string). vehicle.add_attribute_observer('location', location_callback) @@ -154,7 +156,8 @@ attribute changes. The two second ``sleep()`` is required because otherwise the The callback is triggered every time a message is received from the vehicle (whether or not the observed attribute changes). Callback code may therefore choose to cache the result and only report changes. -For example, the following code can be used in the callback to only print output when the value of :py:attr:`Vehicle.rangefinder ` changes. +For example, the following code can be used in the callback to only print output when the value of +:py:attr:`Vehicle.rangefinder ` changes. .. code:: python diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index e12d060c0..4cc9ddac4 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -145,11 +145,11 @@ class LocationGlobal(object): The latitude and longitude are relative to the `WGS84 coordinate system `_. The altitude is relative to either the *home position* or "mean sea-level", depending on the value of the ``is_relative``. - For example, a location object might be defined as: + For example, a global location object might be defined as: .. code:: python - Location(-34.364114, 149.166022, 30, is_relative=True) + LocationGlobal(-34.364114, 149.166022, 30, is_relative=True) .. todo:: FIXME: Location class - possibly add a vector3 representation. @@ -372,19 +372,22 @@ def add_attribute_observer(self, attr_name, observer): """ Add an attribute observer. - The observer is called with the ``attr_name`` argument. This can be used to access - the vehicle parameter, as shown below: + The observer callback function is called with the ``attr_name`` argument. + This can be used to infer the related attribute if the same callback is used + for watching several attributes. + + The example below shows how to get callbacks for location changes: .. code:: python - #Add observer for the vehicle's current location - vehicle.add_attribute_observer('location', location_callback) - - #Callback to print the location + #Callback to print the location in global and local frames def location_callback(location): - print "Location: ", vehicle.location - + print "Location (Global): ", vehicle.location.global_frame + print "Location (Local): ", vehicle.location.local_frame + #Add observer for the vehicle's current location + vehicle.add_attribute_observer('location', location_callback) + .. note:: Attribute changes will only be published for changes due to some other entity. They will not be published for changes made by the local API client @@ -393,7 +396,7 @@ def location_callback(location): :param attr_name: The attribute to watch. :param observer: The callback to invoke when a change in the attribute is detected. - .. todo:: Check that the defect for endless repetition after thread closes is fixed: https://github.com/dronekit/dronekit-python/issues/74 + """ l = self.__observers.get(attr_name) if l is None: @@ -406,11 +409,11 @@ def remove_attribute_observer(self, attr_name, observer): """ Remove an observer. - For example, the following line would remove a previously added vehicle 'location' observer called location_callback: + For example, the following line would remove a previously added vehicle 'global_frame' observer called location_callback: .. code:: python - vehicle.remove_attribute_observer('location', location_callback) + vehicle.remove_attribute_observer('global_frame', location_callback) :param attr_name: The attribute name that is to have an observer removed. @@ -990,18 +993,20 @@ def wait_valid(self): def goto(self, location): ''' - Go to a specified location (changing :py:class:`VehicleMode` to ``GUIDED`` if necessary). + Go to a specified global location (:py:class:`LocationGlobal`). + + The method will change the :py:class:`VehicleMode` to ``GUIDED`` if necessary. .. code:: python # Set mode to guided - this is optional as the goto method will change the mode if needed. vehicle.mode = VehicleMode("GUIDED") - # Set the location to head towards - a_location = Location(-34.364114, 149.166022, 30, is_relative=True) + # Set the LocationGlobal to head towards + a_location = LocationGlobal(-34.364114, 149.166022, 30, is_relative=True) vehicle.commands.goto(a_location) - :param Location location: The target location. + :param LocationGlobal location: The target location. ''' pass diff --git a/examples/drone_delivery/drone_delivery.py b/examples/drone_delivery/drone_delivery.py index 768137e42..85a1d21bd 100644 --- a/examples/drone_delivery/drone_delivery.py +++ b/examples/drone_delivery/drone_delivery.py @@ -11,7 +11,7 @@ from pymavlink import mavutil import dronekit.lib from dronekit import connect -from dronekit.lib import VehicleMode, Location +from dronekit.lib import VehicleMode, LocationGlobal import cherrypy from cherrypy.process import wspbus, plugins @@ -114,7 +114,7 @@ def get_location(self): return [self.current_location.lat, self.current_location.lon] def location_callback(self, location): - location = self.vehicle.location + location = self.vehicle.location.global_frame if location.alt is not None: self.altitude = location.alt diff --git a/examples/follow_me/follow_me.py b/examples/follow_me/follow_me.py index 05b891523..2db35cdd7 100644 --- a/examples/follow_me/follow_me.py +++ b/examples/follow_me/follow_me.py @@ -14,7 +14,8 @@ import gps import socket import time -from dronekit.lib import VehicleMode, Location +import sys +from dronekit.lib import VehicleMode, LocationGlobal #Set up option parsing to get connection string import argparse @@ -58,8 +59,8 @@ def arm_and_takeoff(aTargetAltitude): # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.commands.takeoff will execute immediately). while True: - print " Altitude: ", vehicle.location.alt - if vehicle.location.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. + print " Altitude: ", vehicle.location.global_frame.alt + if vehicle.location.global_frame.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. print "Reached target altitude" break; time.sleep(1) @@ -85,7 +86,7 @@ def arm_and_takeoff(aTargetAltitude): # Once we have a valid location (see gpsd documentation) we can start moving our vehicle around if (gpsd.valid & gps.LATLON_SET) != 0: altitude = 30 # in meters - dest = Location(gpsd.fix.latitude, gpsd.fix.longitude, altitude, is_relative=True) + dest = LocationGlobal(gpsd.fix.latitude, gpsd.fix.longitude, altitude, is_relative=True) print "Going to: %s" % dest # A better implementation would only send new waypoints if the position had changed significantly diff --git a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py index 91cf0a19c..f658dd275 100644 --- a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py +++ b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py @@ -7,7 +7,7 @@ """ from dronekit import connect -from dronekit.lib import VehicleMode, Location +from dronekit.lib import VehicleMode, LocationGlobal from pymavlink import mavutil import time import math @@ -46,6 +46,7 @@ def arm_and_takeoff(aTargetAltitude): while not vehicle.armed: print " Waiting for arming..." + vehicle.armed = True time.sleep(1) print "Taking off!" @@ -54,8 +55,8 @@ def arm_and_takeoff(aTargetAltitude): # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.commands.takeoff will execute immediately). while True: - print " Altitude: ", vehicle.location.alt - if vehicle.location.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. + print " Altitude: ", vehicle.location.global_frame.alt + if vehicle.location.global_frame.alt>=aTargetAltitude*0.95: #Trigger just below target alt. print "Reached target altitude" break; time.sleep(1) @@ -114,7 +115,8 @@ def condition_yaw(heading, relative=False): def set_roi(location): """ - Send MAV_CMD_DO_SET_ROI message to point camera gimbal at a specified region of interest (Location). + Send MAV_CMD_DO_SET_ROI message to point camera gimbal at a + specified region of interest (LocationGlobal). The vehicle may also turn to face the ROI. For more information see: @@ -163,7 +165,7 @@ def set_speed(speed): def set_home(aLocation, aCurrent=1): """ - Send MAV_CMD_DO_SET_HOME command to set the Home location to either the current location + Send MAV_CMD_DO_SET_HOME command to set the Home location to either the current LocationGlobal or a specified location. For more information see: @@ -195,15 +197,15 @@ def set_home(aLocation, aCurrent=1): to the Earth's poles. Specifically, it provides: -* get_location_metres - Get Location (decimal degrees) at distance (m) North & East of a given Location. -* get_distance_metres - Get the distance between two Location objects in metres -* get_bearing - Get the bearing in degrees to a Location +* get_location_metres - Get LocationGlobal (decimal degrees) at distance (m) North & East of a given LocationGlobal. +* get_distance_metres - Get the distance between two LocationGlobal objects in metres +* get_bearing - Get the bearing in degrees to a LocationGlobal """ def get_location_metres(original_location, dNorth, dEast): """ - Returns a Location object containing the latitude/longitude `dNorth` and `dEast` metres from the - specified `original_location`. The returned Location has the same `alt and `is_relative` values + Returns a LocationGlobal object containing the latitude/longitude `dNorth` and `dEast` metres from the + specified `original_location`. The returned LocationGlobal has the same `alt and `is_relative` values as `original_location`. The function is useful when you want to move the vehicle around specifying locations relative to @@ -222,12 +224,12 @@ def get_location_metres(original_location, dNorth, dEast): #New position in decimal degrees newlat = original_location.lat + (dLat * 180/math.pi) newlon = original_location.lon + (dLon * 180/math.pi) - return Location(newlat, newlon,original_location.alt,original_location.is_relative) + return LocationGlobal(newlat, newlon,original_location.alt,original_location.is_relative) def get_distance_metres(aLocation1, aLocation2): """ - Returns the ground distance in metres between two Location objects. + Returns the ground distance in metres between two LocationGlobal objects. This method is an approximation, and will not be accurate over large distances and close to the earth's poles. It comes from the ArduPilot test code: @@ -240,7 +242,7 @@ def get_distance_metres(aLocation1, aLocation2): def get_bearing(aLocation1, aLocation2): """ - Returns the bearing between the two Location objects passed as parameters. + Returns the bearing between the two LocationGlobal objects passed as parameters. This method is an approximation, and may not be accurate over large distances and close to the earth's poles. It comes from the ArduPilot test code: @@ -271,7 +273,7 @@ def get_bearing(aLocation1, aLocation2): def goto_position_target_global_int(aLocation): """ - Send SET_POSITION_TARGET_GLOBAL_INT command to request the vehicle fly to a specified location. + Send SET_POSITION_TARGET_GLOBAL_INT command to request the vehicle fly to a specified LocationGlobal. For more information see: https://pixhawk.ethz.ch/mavlink/#SET_POSITION_TARGET_GLOBAL_INT @@ -334,20 +336,20 @@ def goto(dNorth, dEast, gotoFunction=vehicle.commands.goto): """ Moves the vehicle to a position dNorth metres North and dEast metres East of the current position. - The method takes a function pointer argument with a single `dronekit.lib.Location` parameter for + The method takes a function pointer argument with a single `dronekit.lib.LocationGlobal` parameter for the target position. This allows it to be called with different position-setting commands. By default it uses the standard method: dronekit.lib.Vehicle.commands.goto(). The method reports the distance to target every two seconds. """ - currentLocation=vehicle.location + currentLocation=vehicle.location.global_frame targetLocation=get_location_metres(currentLocation, dNorth, dEast) targetDistance=get_distance_metres(currentLocation, targetLocation) gotoFunction(targetLocation) while vehicle.mode.name=="GUIDED": #Stop action if we are no longer in guided mode. - remainingDistance=get_distance_metres(vehicle.location, targetLocation) + remainingDistance=get_distance_metres(vehicle.location.global_frame, targetLocation) print "Distance to target: ", remainingDistance if remainingDistance<=targetDistance*0.01: #Just below target, in case of undershoot. print "Reached target" @@ -402,7 +404,7 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z): msg = vehicle.message_factory.set_position_target_global_int_encode( 0, # time_boot_ms (not used) 0, 0, # target system, target component - mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT_INT, # frame + mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT_INT, # frame 0b0000111111000111, # type_mask (only speeds enabled) 0, # lat_int - X Position in WGS84 frame in 1e7 * meters 0, # lon_int - Y Position in WGS84 frame in 1e7 * meters @@ -437,6 +439,8 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z): + + """ Fly a triangular path using the SET_POSITION_TARGET_GLOBAL_INT command and specifying a target position (rather than controlling movement using velocity vectors). The command is @@ -494,7 +498,7 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z): print("Point ROI at current location (home position)") # NOTE that this has to be called after the goto command as first "move" command of a particular type # "resets" ROI/YAW commands -set_roi(vehicle.location) +set_roi(vehicle.location.global_frame) time.sleep(DURATION) print("North 50m, East 50m, 10m altitude") @@ -502,7 +506,7 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z): time.sleep(DURATION) print("Point ROI at current location") -set_roi(vehicle.location) +set_roi(vehicle.location.global_frame) print("North 0m, East 50m, 10m altitude") goto_position_target_local_ned(0,50,-10) @@ -603,7 +607,7 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z): send_global_velocity(0,0,0) print("Set new Home location to current location") -set_home(vehicle.location) +set_home(vehicle.location.global_frame) print "Get new home location" #This reloads the home location in GCSs cmds = vehicle.commands cmds.download() diff --git a/examples/mission_basic/mission_basic.py b/examples/mission_basic/mission_basic.py index 36a5e912d..56a4ad2f3 100644 --- a/examples/mission_basic/mission_basic.py +++ b/examples/mission_basic/mission_basic.py @@ -7,7 +7,7 @@ from dronekit import connect import time import math -from dronekit.lib import VehicleMode, Location, Command +from dronekit.lib import VehicleMode, LocationGlobal, Command from pymavlink import mavutil @@ -26,7 +26,7 @@ def get_location_metres(original_location, dNorth, dEast): """ - Returns a Location object containing the latitude/longitude `dNorth` and `dEast` metres from the + Returns a LocationGlobal object containing the latitude/longitude `dNorth` and `dEast` metres from the specified `original_location`. The returned Location has the same `alt and `is_relative` values as `original_location`. @@ -44,12 +44,12 @@ def get_location_metres(original_location, dNorth, dEast): #New position in decimal degrees newlat = original_location.lat + (dLat * 180/math.pi) newlon = original_location.lon + (dLon * 180/math.pi) - return Location(newlat, newlon,original_location.alt,original_location.is_relative) + return LocationGlobal(newlat, newlon,original_location.alt,original_location.is_relative) def get_distance_metres(aLocation1, aLocation2): """ - Returns the ground distance in metres between two Location objects. + Returns the ground distance in metres between two LocationGlobal objects. This method is an approximation, and will not be accurate over large distances and close to the earth's poles. It comes from the ArduPilot test code: @@ -73,8 +73,8 @@ def distance_to_current_waypoint(): lat=missionitem.x lon=missionitem.y alt=missionitem.z - targetWaypointLocation=Location(lat,lon,alt,is_relative=True) - distancetopoint = get_distance_metres(vehicle.location, targetWaypointLocation) + targetWaypointLocation=LocationGlobal(lat,lon,alt,is_relative=True) + distancetopoint = get_distance_metres(vehicle.location.global_frame, targetWaypointLocation) return distancetopoint @@ -107,7 +107,7 @@ def download_mission(): def adds_square_mission(aLocation, aSize): """ Adds a takeoff command and four waypoint commands to the current mission. - The waypoints are positioned to form a square of side length 2*aSize around the specified location (aLocation). + The waypoints are positioned to form a square of side length 2*aSize around the specified LocationGlobal (aLocation). The function assumes vehicle.commands matches the vehicle mission state (you must have called download at least once in the session and after clearing the mission) @@ -162,8 +162,8 @@ def arm_and_takeoff(aTargetAltitude): # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.commands.takeoff will execute immediately). while True: - print " Altitude: ", vehicle.location.alt - if vehicle.location.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. + print " Altitude: ", vehicle.location.global_frame.alt + if vehicle.location.global_frame.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. print "Reached target altitude" break; time.sleep(1) @@ -174,7 +174,7 @@ def arm_and_takeoff(aTargetAltitude): clear_mission() print 'Create a new mission' -adds_square_mission(vehicle.location,50) +adds_square_mission(vehicle.location.global_frame,50) time.sleep(2) # This is here so that mission being sent is displayed on console diff --git a/examples/simple_goto/simple_goto.py b/examples/simple_goto/simple_goto.py index d3ff8afb5..10caa358c 100644 --- a/examples/simple_goto/simple_goto.py +++ b/examples/simple_goto/simple_goto.py @@ -8,7 +8,7 @@ import time from dronekit import connect -from dronekit.lib import VehicleMode, Location +from dronekit.lib import VehicleMode, LocationGlobal from pymavlink import mavutil import time @@ -40,12 +40,13 @@ def arm_and_takeoff(aTargetAltitude): print "Waiting for GPS...:", vehicle.gps_0.fix_type time.sleep(1) + print "Arming motors" # Copter should arm in GUIDED mode vehicle.mode = VehicleMode("GUIDED") - vehicle.armed = True + vehicle.armed = True - while not vehicle.armed: + while not vehicle.armed: print " Waiting for arming..." time.sleep(1) @@ -55,8 +56,8 @@ def arm_and_takeoff(aTargetAltitude): # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.commands.takeoff will execute immediately). while True: - print " Altitude: ", vehicle.location.alt - if vehicle.location.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. + print " Altitude: ", vehicle.location.global_frame.alt + if vehicle.location.global_frame.alt>=aTargetAltitude*0.95: #Trigger just below target alt. print "Reached target altitude" break time.sleep(1) @@ -65,14 +66,14 @@ def arm_and_takeoff(aTargetAltitude): print "Going to first point..." -point1 = Location(-35.361354, 149.165218, 20, is_relative=True) +point1 = LocationGlobal(-35.361354, 149.165218, 20, is_relative=True) vehicle.commands.goto(point1) # sleep so we can see the change in map time.sleep(30) print "Going to second point..." -point2 = Location(-35.363244, 149.168801, 20, is_relative=True) +point2 = LocationGlobal(-35.363244, 149.168801, 20, is_relative=True) vehicle.commands.goto(point2) # sleep so we can see the change in map diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index cad36ba5c..f0cba15ae 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -34,8 +34,8 @@ # Get all vehicle attributes (state) print "\nGet all vehicle attribute values:" -print " Global Location: %s" % v.location.global_frame -print " Local Location: %s" % v.location.local_frame +print " Global Location: %s" % vehicle.location.global_frame +print " Local Location: %s" % vehicle.location.local_frame print " Attitude: %s" % vehicle.attitude print " Velocity: %s" % vehicle.velocity print " GPS: %s" % vehicle.gps_0 @@ -85,7 +85,7 @@ def mode_callback(attribute): time.sleep(2) # Remove observer - specifying the attribute and previously registered callback function -vehicle.remove_attribute_observer('mode', mode_callback) +vehicle.remove_attribute_observer('mode', mode_callback) # Get Vehicle Home location ((0 index in Vehicle.commands) @@ -114,4 +114,4 @@ def mode_callback(attribute): print "\nClose vehicle object" vehicle.close() -print("Completed") \ No newline at end of file +print("Completed") From 1ccc27014ac38fb168a8dfca0cbdcc1b9ebbbd92 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 26 Oct 2015 18:56:24 -0700 Subject: [PATCH 069/475] Fixes waypoints clear. --- dronekit/module/api.py | 6 +++--- tests/sitl/test_waypoints.py | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 tests/sitl/test_waypoints.py diff --git a/dronekit/module/api.py b/dronekit/module/api.py index c410cc22d..1b8219bf8 100644 --- a/dronekit/module/api.py +++ b/dronekit/module/api.py @@ -92,14 +92,14 @@ def clear(self): '''Clears the command list''' self.wait_valid() self.__module.wploader.clear() - self.__module.vehicle.wpts_dirty = True + self.__module.api._FakeAPI__vehicle.wpts_dirty = True def add(self, cmd): '''Add a new command at the end of the command list''' self.wait_valid() self.__module.fix_targets(cmd) self.__module.wploader.add(cmd, comment = 'Added by DroneAPI') - self.__module.vehicle.wpts_dirty = True + self.__module.api._FakeAPI__vehicle.wpts_dirty = True @property def count(self): @@ -123,7 +123,7 @@ def __getitem__(self, index): def __setitem__(self, index, value): self.__module.wploader.set(value, index) - self.__module.vehicle.wpts_dirty = True + self.__module.api._FakeAPI__vehicle.wpts_dirty = True class MPVehicle(Vehicle): def __init__(self, module): diff --git a/tests/sitl/test_waypoints.py b/tests/sitl/test_waypoints.py new file mode 100644 index 000000000..ef3e132f1 --- /dev/null +++ b/tests/sitl/test_waypoints.py @@ -0,0 +1,21 @@ +from dronekit import connect +import time +import math +from dronekit import connect +from dronekit.tools import with_sitl +from dronekit.lib import VehicleMode, LocationGlobal +import time +from nose.tools import assert_not_equals + +# This test runs first! +@with_sitl +def test_parameter(connpath): + # Connect to the Vehicle + vehicle = connect(connpath, await_params=True) + + cmds = vehicle.commands + cmds.download() + cmds.wait_valid() + + vehicle.commands.clear() + vehicle.flush() From a16546e1990bead7a4a087e05d5d635e9666163c Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 26 Oct 2015 20:27:53 -0700 Subject: [PATCH 070/475] 2.0.0c1 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 1899def33..628e9204e 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.0.0b7' +version = '2.0.0c1' setup(name='dronekit', zip_safe=True, From b44c903de4c172250a041ec3bf8c513b3d4d1df1 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 27 Oct 2015 13:58:41 -0700 Subject: [PATCH 071/475] Cleans up many shim classes. --- dronekit/__init__.py | 84 +++++++----------------- dronekit/lib/__init__.py | 134 --------------------------------------- dronekit/module/api.py | 77 +++------------------- tests/unit/test_api.py | 5 -- 4 files changed, 32 insertions(+), 268 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 8072024c3..325f3ab57 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -5,9 +5,12 @@ import os import platform import re +import dronekit.module.api from pymavlink import mavutil, mavwp from Queue import Empty from pymavlink.dialects.v10 import ardupilotmega +from Queue import Queue +from threading import Thread import types if platform.system() == 'Windows': @@ -15,28 +18,12 @@ else: from errno import ECONNABORTED -# Clean impl of mp dependencies for dronekit - -import dronekit.module.api as api - -# Public exports -Vehicle = api.MPVehicle +# Public re-exports +Vehicle = dronekit.module.api.MPVehicle def errprinter(*args): print(*args, file=sys.stderr) -class FakeAPI: - def __init__(self, module): - self.__vehicle = module.vehicle_class(module) - self.exit = False - - def get_vehicles(self, query=None): - return [ self.__vehicle ] - -# def mav_thread(conn, state): - -# return (in_queue, out_queue) - class MavWriter(): def __init__(self, queue): self.queue = queue @@ -55,43 +42,25 @@ def request_data_stream_send(master, rate=1): master.mav.request_data_stream_send(master.target_system, master.target_component, mavutil.mavlink.MAV_DATA_STREAM_ALL, rate, 1) -from Queue import Queue -from threading import Thread - class MPFakeState: def __init__(self, master, vehicle_class=Vehicle): self.vehicle_class = vehicle_class self.master = master - out_queue = Queue() - # self.mav_thread = mav_thread(master, self) - # self.mav = master.mav - - self.api = None + self.vehicle = None # TODO get rid of "master" object as exposed, # keep it private, expose something smaller for dronekit - self.out_queue = out_queue + self.out_queue = Queue() self.master.mav = mavutil.mavlink.MAVLink(MavWriter(self.out_queue), srcSystem=self.master.source_system, use_native=False) - self.command_map = {} - self.completions = {} - + # Targets self.target_system = 0 self.target_component = 0 - self.status = type('MPStatus',(object,),{ - 'flightmode': 'AUTO', - 'armed': False, - })() - + # Parameters self.mav_param = {} - # Weird - self.mpstate = self - self.functions = self - self.mpstate.settings = self - # waypoints self.wploader = mavwp.MAVWPLoader() self.wp_loaded = True @@ -204,10 +173,14 @@ def listener(self, name, m): self.level = m.battery_remaining self._notify_attribute_listeners('battery') + self.flightmode = 'AUTO' + self.armed = False self.system_status = None @message_default('HEARTBEAT') def listener(self, name, m): + self.armed = (m.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED) != 0 + self.flightmode = {v: k for k, v in self.master.mode_mapping().items()}[m.custom_mode] self.system_status = m.system_status self._notify_attribute_listeners('mode', 'armed') @@ -269,7 +242,7 @@ def listener(self, name, m): # boolean: EKF's predicted horizontal position (absolute) estimate is good status_predposhorizabs = (m.flags & ardupilotmega.EKF_PRED_POS_HORIZ_ABS) > 0 - if self.status.armed: + if self.armed: self.ekf_ok = status_poshorizabs and not status_constposmode else: self.ekf_ok = status_poshorizabs or status_predposhorizabs @@ -294,11 +267,10 @@ def send_all_waypoints(self): def fix_targets(self, message): pass # """Set correct target IDs for our vehicle""" - # settings = self.mpstate.settings # if hasattr(message, 'target_system'): - # message.target_system = settings.target_system + # message.target_system = self.target_system # if hasattr(message, 'target_component'): - # message.target_component = settings.target_component + # message.target_component = self.target_component def module(self, which): # psyche @@ -331,8 +303,7 @@ def param_set(self, name, value, retries=3): def __on_change(self, *args): for a in args: - for v in self.api.get_vehicles(): - v.notify_observers(a) + self.vehicle.notify_observers(a) def _notify_attribute_listeners(self, *args): return self.__on_change(*args) @@ -366,10 +337,8 @@ def mavlink_packet(self, m): for fn in self.message_listeners.get('*', []): fn(self, typ, m) - if self.api: - for v in self.api.get_vehicles(): - if v.mavrx_callback: - v.mavrx_callback(m) + if self.vehicle.mavrx_callback: + self.vehicle.mavrx_callback(m) def prepare(self, await_params=False, rate=None): # errprinter('Await heartbeat.') @@ -377,6 +346,8 @@ def prepare(self, await_params=False, rate=None): # invalid MAVLink prefix '73' # invalid MAVLink prefix '13' + self.vehicle = self.vehicle_class(self) + params = type('PState',(object,),{ "mav_param_count": -1, "mav_param_set": [], @@ -385,7 +356,6 @@ def prepare(self, await_params=False, rate=None): })() self.mav_param = {} self.pstate = params - self.api = FakeAPI(self) import atexit self.exiting = False @@ -541,12 +511,9 @@ def mavlink_thread(): # Heartbeat: armed + mode update if msg.get_type() == 'HEARTBEAT': - self.status.armed = (msg.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED) != 0 - self.status.flightmode = {v: k for k, v in self.master.mode_mapping().items()}[msg.custom_mode] last_heartbeat_received = time.time() - if self.api: - self.mavlink_packet(msg) + self.mavlink_packet(msg) except Exception as e: # http://bugs.python.org/issue1856 @@ -592,8 +559,6 @@ def mavlink_thread(): while self.fix_type == None: time.sleep(0.1) - return self.api - def close(self): # TODO this can block forever if parameters continue to be added self.exiting = True @@ -602,8 +567,7 @@ def close(self): self.master.close() def connect(ip, await_params=False, status_printer=errprinter, vehicle_class=Vehicle, rate=4): - import dronekit.module.api as api state = MPFakeState(mavutil.mavlink_connection(ip), vehicle_class=vehicle_class) state.status_printer = status_printer - # api.init(state) - return state.prepare(await_params=await_params, rate=rate).get_vehicles()[0] + state.prepare(await_params=await_params, rate=rate) + return state.vehicle diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 4cc9ddac4..8a3c08390 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -60,27 +60,6 @@ local_path = '' - - -def web_connect(authinfo): - """ - .. warning:: This API is not fully implemented and should not be used. - - Connect to the central dronehub server. - - :param AuthInfo authinfo: A container for authentication information (username, password, challenge info, etc.) - """ - return APIConnection() - -def local_connect(): - """ - Connect to the API provider for the local vehicle or ground control station. - - :return: The API provider. - :rtype: APIConnection - """ - return APIConnection() - class APIException(Exception): """ Base class for DroneKit related exceptions. @@ -91,30 +70,6 @@ class APIException(Exception): def __init__(self, msg): self.msg = msg -class AuthInfo(object): - """ - Not implemented. This is part of a (currently) internal API. - - .. INTERNAL NOTE: Base class for various authentication flavors. - - Currently only simple username & password authentication are supported - - :param object: username/password values. - """ - def __init__(self, username, password): - self.username = username - self.password = password - -class ConnectionInfo(object): - """ - Internal API. Do not use. - - Connection information object used by MAVProxy. - """ - - def __init__(self, mavproxy_options): - self.maxproxy_options = mavproxy_options - class Attitude(object): """ Attitude information. @@ -308,56 +263,6 @@ def __eq__(self, other): def __ne__(self, other): return self.name != other -class APIConnection(object): - """ - An API provider. - - This is the top level API connection returned from :py:func:`local_connect()`. You should not manually create instances of - this class. - - .. INTERNAL_COMMENT: This is also returned by :py:func:`web_connect()` (not supported/fully implemented). - """ - - def get_vehicles(self, query=None): - """ - Get the set of vehicles that are controllable from this connection. - - For example, to get the first vehicle in the set with ``get_vehicles()``: - - .. code:: python - - api = local_connect() # Get an APIConnection - first_vehicle = api.get_vehicles()[0] - - .. note:: - - The set of vehicles connected by the API is configured through MAVProxy. When running on a companion computer there will only ever - be one ``Vehicle`` in the returned set. A ground control station might potentially control (and hence return) more than one vehicle. - - - :param query: This parameter is ignored. Use the default. - :returns: Set of :py:class:`Vehicle` objects controllable from this connection. - """ - # return [ Vehicle(), Vehicle() ] - raise Exception("Subclasses must override") - - @property - def exit(self): - """ - True if the current thread has been asked to exit. - - The connection to the UAV is owned by MAVProxy, which uses this property to signal that the thread should be closed (for whatever reason). - Scripts are expected to check the property and close the thread if this if ``True``. For example: - - .. code:: python - - while not api.exit: - # send commands to vehicle etc. - - .. todo:: FIXME: APIConnection.exit - should this be private, or even part of the drone api at all? - """ - return threading.current_thread().exit - class HasObservers(object): def __init__(self): # A mapping from attr_name to a list of observers @@ -804,45 +709,6 @@ def flush(self): """ pass -#=============================================================================== -# def __getattr__(self, name): -# """ -# Attributes are automatically populated based on vehicle type. -# -# This override provides that behavior. -# """ -# -# try: -# return self.__dict[name] -# except KeyError: -# msg = "'{0}' object has no attribute '{1}'" -# raise AttributeError(msg.format(type(self).__name__, name)) -# -# def __setattr__(self, name, value): -# """ -# An override to support setting for vehicle attributes. -# -# Note: Exceptions due to loss of communications, missing attributes or insufficient permissions are not guaranteed -# to be thrown from inside this method. Most failures will not be seen until flush() is called. If you require immediate -# notification of failure set autoflush. -# """ -# pass -#=============================================================================== - -class Mission(object): - """ - Access to historical missions. - - .. warning:: - - This function is a *placeholder*. It has no implementation in DroneKit-Python release 1. - - Mission objects are only accessible from the REST API in release 1 (most use-cases requiring missions prefer a REST interface). - - .. todo:: FIXME: Mission class needs to be updated when it is implemented (after DroneKit Python release 1). - """ - pass - class Parameters(HasObservers): """ This object is used to get and set the values of named parameters for a vehicle. See the following links for information about diff --git a/dronekit/module/api.py b/dronekit/module/api.py index 1b8219bf8..22399287d 100644 --- a/dronekit/module/api.py +++ b/dronekit/module/api.py @@ -5,7 +5,7 @@ import logging import math from pymavlink import mavutil -from dronekit.lib import APIConnection, Vehicle, VehicleMode, LocationLocal, \ +from dronekit.lib import Vehicle, VehicleMode, LocationLocal, \ LocationGlobal, Attitude, GPSInfo, Parameters, CommandSequence, \ APIException, Battery, Rangefinder @@ -30,12 +30,12 @@ def __getitem__(self, name): def __setitem__(self, name, value): self.wait_valid() - self.__module.mpstate.functions.param_set(name, value) + self.__module.param_set(name, value) def set(self, name, value, retries=3, await_valid=False): if await_valid: self.wait_valid() - return self.__module.mpstate.param_set(name, value, retries=retries) + return self.__module.param_set(name, value, retries=retries) def wait_valid(self): '''Block the calling thread until parameters have been downloaded''' @@ -92,14 +92,14 @@ def clear(self): '''Clears the command list''' self.wait_valid() self.__module.wploader.clear() - self.__module.api._FakeAPI__vehicle.wpts_dirty = True + self.__module.vehicle.wpts_dirty = True def add(self, cmd): '''Add a new command at the end of the command list''' self.wait_valid() self.__module.fix_targets(cmd) self.__module.wploader.add(cmd, comment = 'Added by DroneAPI') - self.__module.api._FakeAPI__vehicle.wpts_dirty = True + self.__module.vehicle.wpts_dirty = True @property def count(self): @@ -123,7 +123,7 @@ def __getitem__(self, index): def __setitem__(self, index, value): self.__module.wploader.set(value, index) - self.__module.api._FakeAPI__vehicle.wpts_dirty = True + self.__module.vehicle.wpts_dirty = True class MPVehicle(Vehicle): def __init__(self, module): @@ -165,7 +165,7 @@ def mode(self): def __get_mode(self): """Private method to read current vehicle mode without polling""" - return VehicleMode(self.__module.status.flightmode) + return VehicleMode(self.__module.flightmode) @mode.setter def mode(self, v): @@ -202,7 +202,7 @@ def gps_0(self): @property def armed(self): - return self.__module.mpstate.status.armed + return self.__module.armed @armed.setter def armed(self, value): @@ -299,64 +299,3 @@ def on_message(self, name, fn): def handler(state, name, m): return fn(self, name, m) return self.__module.on_message(name, handler) - -class MPAPIConnection(APIConnection): - """ - A small private version of the APIConnection class - - In Mavproxy you probably just want to call get_vehicles - """ - def __init__(self, module): - self.__vehicle = MPVehicle(module) - - def get_vehicles(self, query=None): - return [ self.__vehicle ] - -class APIThread(threading.Thread): - def __init__(self, module, fn, description): - super(APIThread, self).__init__() - self.module = module - self.description = description - self.exit = False # Python has no standard way to kill threads, this allows - self.fn = fn - self.thread_num = module.next_thread_num - module.next_thread_num = module.next_thread_num + 1 - self.daemon = True # For now I think it is okay to let mavproxy exit if api clients are still running - self.start() - self.name = "APIThread-%s" % self.thread_num - self.module.thread_add(self) - - # DroneAPI might generate many commands, which in turn generate ots of acks and status text, in the interest of speed we ignore processing those messages - try: - self.module.mpstate.rx_blacklist.add('COMMAND_ACK') - self.module.mpstate.rx_blacklist.add('STATUSTEXT') - except: - pass # Silently work with old mavproxies - - def kill(self): - """Ask the thread to exit. The thread must check threading.current_thread().exit periodically""" - print("Asking %s to exit..." % self.name) - self.exit = True - - def run(self): - try: - self.fn() - print("%s exiting..." % self.name) - except Exception as e: - print("Exception in %s: %s" % (self.name, str(e))) - traceback.print_exc() - - try: - self.module.mpstate.rx_blacklist.remove('COMMAND_ACK') - self.module.mpstate.rx_blacklist.remove('STATUSTEXT') - except: - pass # Silently work with old mavproxies - - # Remove all observers. - self.module.vehicle.remove_all_observers() - self.module.vehicle.unset_mavlink_callback() - - self.module.thread_remove(self) - - def __str__(self): - return "%s: %s" % (self.thread_num, self.description) diff --git a/tests/unit/test_api.py b/tests/unit/test_api.py index 33c8996a0..b43b7ab2e 100644 --- a/tests/unit/test_api.py +++ b/tests/unit/test_api.py @@ -2,13 +2,8 @@ from mock import MagicMock import dronekit from dronekit.lib import VehicleMode -from dronekit import FakeAPI from nose.tools import assert_equals, assert_not_equals -def test_mode(): - api = FakeAPI(MagicMock()) - assert_equals(len(api.get_vehicles()), 1) - def test_vehicle_mode_eq(): assert_equals(VehicleMode('GUIDED'), VehicleMode('GUIDED')) From ebcf7346da29486aabc74a819d710434f8e0623a Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 27 Oct 2015 14:01:53 -0700 Subject: [PATCH 072/475] Merges MPParameters with Parameters. --- dronekit/module/api.py | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/dronekit/module/api.py b/dronekit/module/api.py index 22399287d..6e249d59a 100644 --- a/dronekit/module/api.py +++ b/dronekit/module/api.py @@ -14,36 +14,6 @@ logger = logging.getLogger(__name__) -class MPParameters(Parameters): - """ - See Parameters baseclass for documentation. - - FIXME - properly publish change notification - """ - - def __init__(self, module): - self.__module = module - - def __getitem__(self, name): - self.wait_valid() - return self.__module.mav_param[name] - - def __setitem__(self, name, value): - self.wait_valid() - self.__module.param_set(name, value) - - def set(self, name, value, retries=3, await_valid=False): - if await_valid: - self.wait_valid() - return self.__module.param_set(name, value, retries=retries) - - def wait_valid(self): - '''Block the calling thread until parameters have been downloaded''' - # FIXME this is a super crufty spin-wait, also we should give the user the option of specifying a timeout - pstate = self.__module.pstate - while (pstate.mav_param_count == 0 or len(pstate.mav_param_set) != pstate.mav_param_count) and not self.__module.api.exit: - time.sleep(0.200) - class MPCommandSequence(CommandSequence): """ See CommandSequence baseclass for documentation. @@ -129,7 +99,7 @@ class MPVehicle(Vehicle): def __init__(self, module): super(MPVehicle, self).__init__() self.__module = module - self._parameters = MPParameters(module) + self._parameters = Parameters(module) self._waypoints = None self.wpts_dirty = False From 71de7e8a8ecd90b9a2e029b703fc6b3a84ec7048 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 27 Oct 2015 14:05:49 -0700 Subject: [PATCH 073/475] Merges MPCommandSequence into CommandSequence. --- dronekit/lib/__init__.py | 90 +++++++++++++++++++++++++++++++++------- dronekit/module/api.py | 83 +----------------------------------- 2 files changed, 75 insertions(+), 98 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 8a3c08390..4e9933084 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -737,6 +737,29 @@ class Parameters(HasObservers): https://github.com/dronekit/dronekit-python/issues/107 """ + def __init__(self, module): + self.__module = module + + def __getitem__(self, name): + self.wait_valid() + return self.__module.mav_param[name] + + def __setitem__(self, name, value): + self.wait_valid() + self.__module.param_set(name, value) + + def set(self, name, value, retries=3, await_valid=False): + if await_valid: + self.wait_valid() + return self.__module.param_set(name, value, retries=retries) + + def wait_valid(self): + '''Block the calling thread until parameters have been downloaded''' + # FIXME this is a super crufty spin-wait, also we should give the user the option of specifying a timeout + pstate = self.__module.pstate + while (pstate.mav_param_count == 0 or len(pstate.mav_param_set) != pstate.mav_param_count) and not self.__module.api.exit: + time.sleep(0.200) + class Command(mavutil.mavlink.MAVLink_mission_item_message): """ A waypoint object. @@ -840,13 +863,18 @@ class CommandSequence(object): .. todo:: This is a hack. The actual function should be defined here. See https://github.com/dronekit/dronekit-python/issues/64 """ + def __init__(self, module): + self.__module = module + def download(self): ''' Download all waypoints from the vehicle. The download is asynchronous. Use :py:func:`wait_valid()` to block your thread until the download is complete. ''' - pass + self.wait_valid() + self.__module.fetch() + # BIG FIXME - wait for full wpt download before allowing any of the accessors to work def wait_valid(self): ''' @@ -854,10 +882,22 @@ def wait_valid(self): This can be called after :py:func:`download()` to block the thread until the asynchronous download is complete. ''' - pass - - - def goto(self, location): + # FIXME this is a super crufty spin-wait, also we should give the user the option of specifying a timeout + while not self.__module.wp_loaded: + time.sleep(0.1) + + def takeoff(self, alt=None): + if alt is not None: + altitude = float(alt) + if math.isnan(alt) or math.isinf(alt): + raise ValueError("Altitude was NaN or Infinity. Please provide a real number") + self.__module.master.mav.command_long_send(self.__module.target_system, + self.__module.target_component, + mavutil.mavlink.MAV_CMD_NAV_TAKEOFF, + 0, 0, 0, 0, 0, 0, 0, + altitude) + + def goto(self, l): ''' Go to a specified global location (:py:class:`LocationGlobal`). @@ -874,7 +914,17 @@ def goto(self, location): :param LocationGlobal location: The target location. ''' - pass + if l.is_relative: + frame = mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT + else: + frame = mavutil.mavlink.MAV_FRAME_GLOBAL + self.__module.master.mav.mission_item_send(self.__module.target_system, + self.__module.target_component, + 0, + frame, + mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, + 2, 0, 0, 0, 0, 0, + l.lat, l.lon, l.alt) def clear(self): ''' @@ -887,7 +937,9 @@ def clear(self): .. todo:: The above note should be removed when https://github.com/dronekit/dronekit-python/issues/132 fixed ''' - pass + self.wait_valid() + self.__module.wploader.clear() + self.__module.vehicle.wpts_dirty = True def add(self, cmd): ''' @@ -897,7 +949,10 @@ def add(self, cmd): :param Command cmd: The command to be added. ''' - pass + self.wait_valid() + self.__module.fix_targets(cmd) + self.__module.wploader.add(cmd, comment = 'Added by DroneAPI') + self.__module.vehicle.wpts_dirty = True @property def count(self): @@ -906,22 +961,25 @@ def count(self): :return: The number of waypoints in the sequence. ''' - return 0 + return self.__module.wploader.count() @property def next(self): """ Get the currently active waypoint number. - - .. INTERNAL NOTE: (implementation provided by subclass) """ - return None + return self.__module.last_waypoint @next.setter - def next(self, value): + def next(self, index): """ Set a new ``next`` waypoint for the vehicle. - - .. INTERNAL NOTE: (implementation provided by subclass) """ - pass + self.__module.master.waypoint_set_current_send(index) + + def __getitem__(self, index): + return self.__module.wploader.wp(index) + + def __setitem__(self, index, value): + self.__module.wploader.set(value, index) + self.__module.vehicle.wpts_dirty = True diff --git a/dronekit/module/api.py b/dronekit/module/api.py index 6e249d59a..e7a64dd5b 100644 --- a/dronekit/module/api.py +++ b/dronekit/module/api.py @@ -14,87 +14,6 @@ logger = logging.getLogger(__name__) -class MPCommandSequence(CommandSequence): - """ - See CommandSequence baseclass for documentation. - """ - - def __init__(self, module): - self.__module = module - - def download(self): - '''Download all waypoints from the vehicle''' - self.wait_valid() - self.__module.fetch() - # BIG FIXME - wait for full wpt download before allowing any of the accessors to work - - def wait_valid(self): - '''Block the calling thread until waypoints have been downloaded''' - # FIXME this is a super crufty spin-wait, also we should give the user the option of specifying a timeout - while not self.__module.wp_loaded: - time.sleep(0.1) - - def takeoff(self, alt=None): - if alt is not None: - altitude = float(alt) - if math.isnan(alt) or math.isinf(alt): - raise ValueError("Altitude was NaN or Infinity. Please provide a real number") - self.__module.master.mav.command_long_send(self.__module.target_system, - self.__module.target_component, - mavutil.mavlink.MAV_CMD_NAV_TAKEOFF, - 0, 0, 0, 0, 0, 0, 0, - altitude) - - def goto(self, l): - if l.is_relative: - frame = mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT - else: - frame = mavutil.mavlink.MAV_FRAME_GLOBAL - self.__module.master.mav.mission_item_send(self.__module.target_system, - self.__module.target_component, - 0, - frame, - mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, - 2, 0, 0, 0, 0, 0, - l.lat, l.lon, l.alt) - - def clear(self): - '''Clears the command list''' - self.wait_valid() - self.__module.wploader.clear() - self.__module.vehicle.wpts_dirty = True - - def add(self, cmd): - '''Add a new command at the end of the command list''' - self.wait_valid() - self.__module.fix_targets(cmd) - self.__module.wploader.add(cmd, comment = 'Added by DroneAPI') - self.__module.vehicle.wpts_dirty = True - - @property - def count(self): - return self.__module.wploader.count() - - @property - def next(self): - """ - Currently active waypoint number - - (implementation provided by subclass) - """ - return self.__module.last_waypoint - - @next.setter - def next(self, index): - self.__module.master.waypoint_set_current_send(index) - - def __getitem__(self, index): - return self.__module.wploader.wp(index) - - def __setitem__(self, index, value): - self.__module.wploader.set(value, index) - self.__module.vehicle.wpts_dirty = True - class MPVehicle(Vehicle): def __init__(self, module): super(MPVehicle, self).__init__() @@ -224,7 +143,7 @@ def commands(self): The (editable) waypoints for this vehicle. """ if(self._waypoints is None): # We create the wpts lazily (because this will start a fetch) - self._waypoints = MPCommandSequence(self.__module) + self._waypoints = CommandSequence(self.__module) return self._waypoints def send_mavlink(self, message): From bf3332ba7c3c38cc01b3b09f4add54955140f725 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 27 Oct 2015 15:22:39 -0700 Subject: [PATCH 074/475] Merges Vehicle class with MPVehicle. --- dronekit/__init__.py | 8 +- dronekit/lib/__init__.py | 276 +++++++++++++++++++--------- dronekit/module/api.py | 300 +++++++++++++++++++++++++++++-- tests/sitl/test_110.py | 6 +- tests/sitl/test_115.py | 6 +- tests/sitl/test_12.py | 6 +- tests/sitl/test_goto.py | 4 +- tests/sitl/test_localposition.py | 5 +- tests/sitl/test_simpledemo.py | 6 +- tests/sitl/test_vehicleclass.py | 2 +- tests/sitl/test_waypoints.py | 5 +- 11 files changed, 502 insertions(+), 122 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 325f3ab57..ae62a04e3 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -5,7 +5,7 @@ import os import platform import re -import dronekit.module.api +import dronekit.lib from pymavlink import mavutil, mavwp from Queue import Empty from pymavlink.dialects.v10 import ardupilotmega @@ -19,7 +19,11 @@ from errno import ECONNABORTED # Public re-exports -Vehicle = dronekit.module.api.MPVehicle +Vehicle = dronekit.lib.Vehicle +VehicleMode = dronekit.lib.VehicleMode +LocationGlobal = dronekit.lib.LocationGlobal +LocationLocal = dronekit.lib.LocationLocal +CloudClient = dronekit.lib.CloudClient def errprinter(*args): print(*args, file=sys.stderr) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 4e9933084..bb83cda93 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1,5 +1,10 @@ # DroneAPI module +import threading, time, math +import CloudClient + +from pymavlink import mavutil + """ This is the API Reference for the DroneKit-Python API. @@ -55,9 +60,6 @@ """ -import threading -from pymavlink import mavutil - local_path = '' class APIException(Exception): @@ -553,106 +555,172 @@ class Vehicle(HasObservers): """ - def __init__(self): + def __init__(self, module): super(Vehicle, self).__init__() self.mavrx_callback = None + self.__module = module + self._parameters = Parameters(module) + self._waypoints = None + self.wpts_dirty = False - @property - def commands(self): - """ - Gets the editable waypoints for this vehicle (the current "mission"). + def close(self): + return self.__module.close() - This can be used to get, create, and modify a mission. It can also be used for direct control of vehicle position - (outside missions) using the :py:func:`goto ` method. + def flush(self): + """ + Call ``flush()`` after :py:func:`adding ` or :py:func:`clearing ` mission commands. - :returns: A :py:class:`CommandSequence` containing the waypoints for this vehicle. + After the return from ``flush()`` any writes are guaranteed to have completed (or thrown an + exception) and future reads will see their effects. """ - None + if self.wpts_dirty: + self.__module.send_all_waypoints() + self.wpts_dirty = False + + # + # Private sugar methods + # @property - def parameters(self): - """ - The (editable) parameters for this vehicle (:py:class:`Parameters `). - """ - return self._parameters + def __master(self): + return self.__module.master - def delete(self): - """ - Delete this vehicle object. + @property + def __mode_mapping(self): + return self.__master.mode_mapping() - This requests deletion of the Vehicle object on the server. This operation may throw an exception on failure (i.e. for - local connections or insufficient user permissions). + # + # Operations to support the standard API (FIXME - possibly/probably this + # will move into a private dict of getter/setter tuples (invisible to the API consumer). + # - It is not supported for local connections. - """ - pass + @property + def mode(self): + self.wait_init() # We must know vehicle type before this operation can work + return self.__get_mode() - def get_mission(self, query_params): - """ - Not implemented. + def __get_mode(self): + """Private method to read current vehicle mode without polling""" + return VehicleMode(self.__module.flightmode) - Returns an object providing access to historical missions. + @mode.setter + def mode(self, v): + self.wait_init() # We must know vehicle type before this operation can work + self.__master.set_mode(self.__mode_mapping[v.name]) - .. warning:: + @property + def location(self): + # For backward compatibility, this is (itself) a LocationLocal object. + ret = LocationGlobal(self.__module.lat, self.__module.lon, self.__module.alt, is_relative=False) + ret.local_frame = LocationLocal(self.__module.north, self.__module.east, self.__module.down) + ret.global_frame = LocationGlobal(self.__module.lat, self.__module.lon, self.__module.alt, is_relative=False) + return ret - Mission objects are only accessible from the REST API in release 1 (most use-cases requiring missions prefer a + @property + def battery(self): + return Battery(self.__module.voltage, self.__module.current, self.__module.level) - :param query_params: Some set of arguments that can be used to find a past mission - :return: Mission - the mission object. + @property + def rangefinder(self): + return Rangefinder(self.__module.rngfnd_distance, self.__module.rngfnd_voltage) - .. todo:: FIXME: get_mission needs to be updated when class Mission is implemented. The warning needs to be removed and the values of the query_params specified. - """ + @property + def velocity(self): + return [ self.__module.vx, self.__module.vy, self.__module.vz ] - return Mission() + @property + def attitude(self): + return Attitude(self.__module.pitch, self.__module.yaw, self.__module.roll) @property - def message_factory(self): - """ - Returns an object that can be used to create 'raw' MAVLink messages that are appropriate for this vehicle. - The message can then be sent using :py:func:`send_mavlink(message) `. + def gps_0(self): + return GPSInfo(self.__module.eph, self.__module.epv, self.__module.fix_type, self.__module.satellites_visible) - These message types are defined in the central MAVLink github repository. For example, a Pixhawk understands - the following messages (from `pixhawk.xml `_): + @property + def armed(self): + return self.__module.armed - .. code:: xml + @armed.setter + def armed(self, value): + if value: + self.__master.arducopter_arm() + else: + self.__master.arducopter_disarm() - - 0 to disable, 1 to enable - + @property + def system_status(self): + return self.__module.system_status - The name of the factory method will always be the lower case version of the message name with *_encode* appended. - Each field in the XML message definition must be listed as arguments to this factory method. So for this example - message, the call would be: + @property + def groundspeed(self): + return self.__module.groundspeed - .. code:: python + @property + def airspeed(self): + return self.__module.airspeed - msg = vehicle.message_factory.image_trigger_control_encode(True) - vehicle.send_mavlink(msg) + @property + def mount_status(self): + return [ self.__module.mount_pitch, self.__module.mount_yaw, self.__module.mount_roll ] - There is no need to specify the system id, component id or sequence number of messages (if defined in the message type) as the - API will set these appropriately when the message is sent. + @property + def ekf_ok(self): + return self.__module.ekf_ok - .. todo:: When I have a custom message guide topic. Link from here to it. + @property + def channel_override(self): + overrides = self.__rc.override + # Only return entries that have a non zero override + return dict((str(num + 1), overrides[num]) for num in range(8) if overrides[num] != 0) + + @channel_override.setter + def channel_override(self, newch): + overrides = self.__rc.override + for k, v in newch.iteritems(): + overrides[int(k) - 1] = v + self.__rc.set_override(overrides) - .. todo:: Check if the standard MAV_CMD messages can be sent this way too, and if so add link. - """ - None + @property + def channel_readback(self): + return self.__module.rc_readback - def send_mavlink(self, message): + @property + def commands(self): """ - This method is used to send raw MAVLink "custom messages" to the vehicle. + Gets the editable waypoints for this vehicle (the current "mission"). - The function can send arbitrary messages/commands to a vehicle at any time and in any vehicle mode. It is particularly useful for - controlling vehicles outside of missions (for example, in GUIDED mode). + This can be used to get, create, and modify a mission. It can also be used for direct control of vehicle position + (outside missions) using the :py:func:`goto ` method. - The :py:func:`message_factory ` is used to create messages in the appropriate format. - Callers do not need to populate sysId/componentId/crc in the packet as the method will take care of that before sending. + :returns: A :py:class:`CommandSequence` containing the waypoints for this vehicle. + """ + if(self._waypoints is None): # We create the wpts lazily (because this will start a fetch) + self._waypoints = CommandSequence(self.__module) + return self._waypoints - :param message: A ``MAVLink_message`` instance, created using :py:func:`message_factory `. - There is need to specify the system id, component id or sequence number of messages as the API will set these appropriately. + @property + def parameters(self): + """ + The (editable) parameters for this vehicle (:py:class:`Parameters `). + """ + return self._parameters + + def unset_mavlink_callback(self): """ - pass + Clears the asynchronous notification added by :py:func:`set_mavlink_callback `. + + The code snippet below shows how to set, then clear, a MAVLink callback function. + + .. code:: python + # Set MAVLink callback handler (after getting Vehicle instance) + vehicle.set_mavlink_callback(mavrx_debug_handler) + + # Remove the MAVLink callback handler. Callback will not be + # called after this point. + vehicle.unset_mavlink_callback() + """ + self.mavrx_callback = None def set_mavlink_callback(self, callback): """ @@ -683,31 +751,73 @@ def mavrx_debug_handler(message): """ self.mavrx_callback = callback - def unset_mavlink_callback(self): + def send_mavlink(self, message): """ - Clears the asynchronous notification added by :py:func:`set_mavlink_callback `. - - The code snippet below shows how to set, then clear, a MAVLink callback function. + This method is used to send raw MAVLink "custom messages" to the vehicle. - .. code:: python + The function can send arbitrary messages/commands to a vehicle at any time and in any vehicle mode. It is particularly useful for + controlling vehicles outside of missions (for example, in GUIDED mode). - # Set MAVLink callback handler (after getting Vehicle instance) - vehicle.set_mavlink_callback(mavrx_debug_handler) + The :py:func:`message_factory ` is used to create messages in the appropriate format. + Callers do not need to populate sysId/componentId/crc in the packet as the method will take care of that before sending. - # Remove the MAVLink callback handler. Callback will not be - # called after this point. - vehicle.unset_mavlink_callback() + :param message: A ``MAVLink_message`` instance, created using :py:func:`message_factory `. + There is need to specify the system id, component id or sequence number of messages as the API will set these appropriately. """ - self.mavrx_callback = None + self.__module.fix_targets(message) + self.__module.master.mav.send(message) - def flush(self): + @property + def message_factory(self): """ - Call ``flush()`` after :py:func:`adding ` or :py:func:`clearing ` mission commands. + Returns an object that can be used to create 'raw' MAVLink messages that are appropriate for this vehicle. + The message can then be sent using :py:func:`send_mavlink(message) `. - After the return from ``flush()`` any writes are guaranteed to have completed (or thrown an - exception) and future reads will see their effects. + These message types are defined in the central MAVLink github repository. For example, a Pixhawk understands + the following messages (from `pixhawk.xml `_): + + .. code:: xml + + + 0 to disable, 1 to enable + + + The name of the factory method will always be the lower case version of the message name with *_encode* appended. + Each field in the XML message definition must be listed as arguments to this factory method. So for this example + message, the call would be: + + .. code:: python + + msg = vehicle.message_factory.image_trigger_control_encode(True) + vehicle.send_mavlink(msg) + + There is no need to specify the system id, component id or sequence number of messages (if defined in the message type) as the + API will set these appropriately when the message is sent. + + .. todo:: When I have a custom message guide topic. Link from here to it. + + .. todo:: Check if the standard MAV_CMD messages can be sent this way too, and if so add link. """ - pass + return self.__module.master.mav + + def wait_init(self): + """Wait for the vehicle to exit the initializing step""" + timeout = 30 + pollinterval = 0.2 + for i in range(0, int(timeout / pollinterval)): + # Don't let the user try to fly while the board is still booting + mode = self.__get_mode().name + # print "mode is", mode + if mode != "INITIALISING" and mode != "MAV": + return + + time.sleep(pollinterval) + raise APIException("Vehicle did not complete initialization") + + def on_message(self, name, fn): + def handler(state, name, m): + return fn(self, name, m) + return self.__module.on_message(name, handler) class Parameters(HasObservers): """ diff --git a/dronekit/module/api.py b/dronekit/module/api.py index e7a64dd5b..bc77e0703 100644 --- a/dronekit/module/api.py +++ b/dronekit/module/api.py @@ -14,9 +14,200 @@ logger = logging.getLogger(__name__) -class MPVehicle(Vehicle): +class Vehicle(HasObservers): + """ + The main vehicle API + + Asynchronous notification on change of vehicle state is available by registering observers (callbacks) for attribute changes. + + Most vehicle state is exposed through python attributes (e.g. ``vehicle.location``). Most of these attributes are + auto-populated based on the capabilities of the connected autopilot/vehicle. + + Particular autopilots/vehicles may define different attributes from this standard list (extra batteries, GPIOs, etc.) + However if a standard attribute is defined it must follow the rules specified below. + + **Autopilot specific attributes & types:** + + To prevent name clashes the following naming convention should be used: + + * ``ap_`` - For autopilot specific parameters (apm 2.5, pixhawk etc.). For example "ap_pin5_mode" and "ap_pin5_value". + * ``user_`` - For user specific parameters + + **Standard attributes & types:** + + .. py:attribute:: location.global_frame + + Current :py:class:`LocationGlobal`. + + + .. py:attribute:: location.local_frame + + Current :py:class:`LocationLocal`. + + + .. py:attribute:: attitude + + Current vehicle :py:class:`Attitude` (pitch, yaw, roll). + + + .. py:attribute:: velocity + + Current velocity as a three element list ``[ vx, vy, vz ]`` (in meter/sec). + + + .. py:attribute:: mode + + This attribute is used to get and set the current flight mode (:py:class:`VehicleMode`). + + + .. py:attribute:: airspeed + + Current airspeed in metres/second (``double``). + + .. todo:: FIXME: Should airspeed value move somewhere else from "Standard attributes & types" table? + + .. py:attribute:: groundspeed + + Groundspeed in metres/second (``double``). + + .. py:attribute:: gps_0 + + GPS position information (:py:class:`GPSInfo`). + + + .. py:attribute:: armed + + This attribute can be used to get and set the ``armed`` state of the vehicle (``boolean``). + + The code below shows how to read the state, and to arm/disam the vehicle: + + .. code:: python + + # Print the armed state for the vehicle + print "Armed: %s" % vehicle.armed + + # Disarm the vehicle + vehicle.armed = False + + # Arm the vehicle + vehicle.armed = True + + + .. py:attribute:: mount_status + + Current status of the camera mount (gimbal) as a three element list: ``[ pitch, yaw, roll ]``. + + The values in the list are set to ``None`` if no mount is configured. + + + .. py:attribute:: battery + + Current system :py:class:`Battery` status. + + + .. py:attribute:: rangefinder + + :py:class:`Rangefinder` distance and voltage values. + + + .. py:attribute:: channel_override + + .. warning:: + + RC override may be useful for simulating user input and when implementing certain types of joystick control. + It should not be used for direct control of vehicle channels unless there is no other choice! + + Instead use the appropriate MAVLink commands like DO_SET_SERVO/DO_SET_RELAY, or more generally + set the desired position or direction/speed. + + This attribute takes a dictionary argument defining the RC *output* channels to be overridden (specified by channel number), and their new values. + Channels that are not specified in the dictionary are not overridden. All multi-channel updates are atomic. + + To cancel an override call ``channel_override`` again, setting zero for the overridden channels. + + The values of the first four channels map to the main flight controls: 1=Roll, 2=Pitch, 3=Throttle, 4=Yaw (the mapping is defined in ``RCMAP_`` parameters: + `Plane `_, + `Copter `_ , + `Rover `_). + + The remaining channel values are configurable, and their purpose can be determined using the + `RCn_FUNCTION parameters `_. + In general a value of 0 set for a specific ``RCn_FUNCTION`` indicates that the channel can be + `mission controlled `_ (i.e. it will not directly be + controlled by normal autopilot code). + + An example of setting and clearing the override is given below: + + .. code:: python + + # Override channels 1 and 4 (only). + vehicle.channel_override = { "1" : 900, "4" : 1000 } + + # Cancel override on channel 1 and 4 by sending 0 + vehicle.channel_override = { "1" : 0, "4" : 0 } + + + .. versionchanged:: 1.0 + + This update replaces ``rc_override`` with ``channel_override``/``channel_readback`` documentation. + + + .. todo:: Add note to the examples/guide like warning above not to use this mechanism except as intended: + + https://github.com/dronekit/dronekit-python/issues/72 + + .. todo:: + + channel_override/channel_readback documentation + + In a future update strings will be defined per vehicle type ('pitch', 'yaw', 'roll' etc...) + and rather than setting channel 3 to 1400 (for instance), you will pass in a dict with + 'throttle':1200. + + This change will be useful in two ways: + + * we can hide (eventually we can deprecate) any notion of rc channel numbers at all. + * vehicles can eventually define new 'channels' for overridden values. + + FIXME: Remaining channel_override/channel_readback FIXMEs: + + * how to address the units issue? Merely with documentation or some other way? + * is there any benefit of using lists rather than tuples for these attributes + + + .. py:attribute:: channel_readback + + This read-only attribute returns a dictionary containing the *original* vehicle RC channel values (ignoring any overrides set using + :py:attr:`channel_override `). Dictionary entries have the format ``channelName -> value``. + + For example, the returned dictionary might look like this: + + .. code:: python + + RC readback: {'1': 1500, '3': 1000, '2': 1500, '5': 1800, '4': 1500, '7': 1000, '6': 1000, '8': 1800} ? Dictionary () (read only) + + + + .. todo:: In V2, there may be ardupilot specific attributes & types (as in the introduction). If so, text below might be useful. + + **Autopilot specific attributes & types:** + + .. py:attribute:: ap_pin5_mode + + string (adc, dout, din) + + .. py:attribute:: ap_pin5_value + + ? double (0, 1, 2.3 etc...) + + + .. todo:: Add waypoint_home attribute IF this is added: https://github.com/dronekit/dronekit-python/issues/105 + + """ + def __init__(self, module): - super(MPVehicle, self).__init__() + super(Vehicle, self).__init__() + self.mavrx_callback = None self.__module = module self._parameters = Parameters(module) self._waypoints = None @@ -26,6 +217,12 @@ def close(self): return self.__module.close() def flush(self): + """ + Call ``flush()`` after :py:func:`adding ` or :py:func:`clearing ` mission commands. + + After the return from ``flush()`` any writes are guaranteed to have completed (or thrown an + exception) and future reads will see their effects. + """ if self.wpts_dirty: self.__module.send_all_waypoints() self.wpts_dirty = False @@ -140,33 +337,116 @@ def channel_readback(self): @property def commands(self): """ - The (editable) waypoints for this vehicle. + Gets the editable waypoints for this vehicle (the current "mission"). + + This can be used to get, create, and modify a mission. It can also be used for direct control of vehicle position + (outside missions) using the :py:func:`goto ` method. + + :returns: A :py:class:`CommandSequence` containing the waypoints for this vehicle. """ if(self._waypoints is None): # We create the wpts lazily (because this will start a fetch) self._waypoints = CommandSequence(self.__module) return self._waypoints + @property + def parameters(self): + """ + The (editable) parameters for this vehicle (:py:class:`Parameters `). + """ + return self._parameters + + def unset_mavlink_callback(self): + """ + Clears the asynchronous notification added by :py:func:`set_mavlink_callback `. + + The code snippet below shows how to set, then clear, a MAVLink callback function. + + .. code:: python + + # Set MAVLink callback handler (after getting Vehicle instance) + vehicle.set_mavlink_callback(mavrx_debug_handler) + + # Remove the MAVLink callback handler. Callback will not be + # called after this point. + vehicle.unset_mavlink_callback() + """ + self.mavrx_callback = None + + def set_mavlink_callback(self, callback): + """ + Provides asynchronous notification when any MAVLink packet is received by this vehicle. + + Only a single callback can be set. :py:func:`unset_mavlink_callback ` removes the callback. + + .. tip:: + + This method is implemented - but we hope you don't need it. + + Because of the asynchronous attribute/waypoint/parameter notifications there should be no need for + API clients to see raw MAVLink. Please provide feedback if we missed a use-case. + + The code snippet below shows how to set a "demo" callback function as the callback handler: + + .. code:: python + + # Demo callback handler for raw MAVLink messages + def mavrx_debug_handler(message): + print "Received", message + + # Set MAVLink callback handler (after getting Vehicle instance) + vehicle.set_mavlink_callback(mavrx_debug_handler) + + :param callback: The callback function to be invoked when a raw MAVLink message is received. + + """ + self.mavrx_callback = callback + def send_mavlink(self, message): + """ + This method is used to send raw MAVLink "custom messages" to the vehicle. + + The function can send arbitrary messages/commands to a vehicle at any time and in any vehicle mode. It is particularly useful for + controlling vehicles outside of missions (for example, in GUIDED mode). + + The :py:func:`message_factory ` is used to create messages in the appropriate format. + Callers do not need to populate sysId/componentId/crc in the packet as the method will take care of that before sending. + + :param message: A ``MAVLink_message`` instance, created using :py:func:`message_factory `. + There is need to specify the system id, component id or sequence number of messages as the API will set these appropriately. + """ self.__module.fix_targets(message) self.__module.master.mav.send(message) @property def message_factory(self): """ - Returns an object that can be used to create 'raw' mavlink messages that are appropriate for this vehicle. - These message types are defined in the central Mavlink github repository. For example, a Pixhawk understands - the following messages: (from https://github.com/mavlink/mavlink/blob/master/message_definitions/v1.0/pixhawk.xml). + Returns an object that can be used to create 'raw' MAVLink messages that are appropriate for this vehicle. + The message can then be sent using :py:func:`send_mavlink(message) `. + + These message types are defined in the central MAVLink github repository. For example, a Pixhawk understands + the following messages (from `pixhawk.xml `_): + + .. code:: xml 0 to disable, 1 to enable - The name of the factory method will always be the lower case version of the message name with _encode appended. - Each field in the xml message definition must be listed as arguments to this factory method. So for this example + The name of the factory method will always be the lower case version of the message name with *_encode* appended. + Each field in the XML message definition must be listed as arguments to this factory method. So for this example message, the call would be: - msg = vehicle.message_factory.image_trigger_control_encode(True) - vehicle.send_mavlink(msg) + .. code:: python + + msg = vehicle.message_factory.image_trigger_control_encode(True) + vehicle.send_mavlink(msg) + + There is no need to specify the system id, component id or sequence number of messages (if defined in the message type) as the + API will set these appropriately when the message is sent. + + .. todo:: When I have a custom message guide topic. Link from here to it. + + .. todo:: Check if the standard MAV_CMD messages can be sent this way too, and if so add link. """ return self.__module.master.mav diff --git a/tests/sitl/test_110.py b/tests/sitl/test_110.py index c7afed19e..62d400d6b 100644 --- a/tests/sitl/test_110.py +++ b/tests/sitl/test_110.py @@ -1,10 +1,8 @@ -from dronekit import connect -from dronekit.lib import VehicleMode -from dronekit.tools import with_sitl -from pymavlink import mavutil import time import sys import os +from dronekit import connect, VehicleMode +from dronekit.tools import with_sitl from nose.tools import assert_equals @with_sitl diff --git a/tests/sitl/test_115.py b/tests/sitl/test_115.py index 834357f45..7437b2d6e 100644 --- a/tests/sitl/test_115.py +++ b/tests/sitl/test_115.py @@ -1,10 +1,8 @@ -from dronekit import connect -from dronekit.lib import VehicleMode -from dronekit.tools import with_sitl -from pymavlink import mavutil import time import sys import os +from dronekit import connect, VehicleMode +from dronekit.tools import with_sitl from nose.tools import assert_equals @with_sitl diff --git a/tests/sitl/test_12.py b/tests/sitl/test_12.py index 2380f2fba..71d25e5fd 100644 --- a/tests/sitl/test_12.py +++ b/tests/sitl/test_12.py @@ -1,10 +1,8 @@ -from dronekit import connect -from dronekit.lib import VehicleMode -from dronekit.tools import with_sitl -from pymavlink import mavutil import time import sys import os +from dronekit import connect, VehicleMode +from dronekit.tools import with_sitl from nose.tools import assert_equals def current_milli_time(): diff --git a/tests/sitl/test_goto.py b/tests/sitl/test_goto.py index ee7f9a649..31de61d57 100644 --- a/tests/sitl/test_goto.py +++ b/tests/sitl/test_goto.py @@ -8,10 +8,8 @@ """ import time -from dronekit import connect -from dronekit.lib import VehicleMode, LocationGlobal +from dronekit import connect, VehicleMode, LocationGlobal from dronekit.tools import with_sitl -from pymavlink import mavutil from nose.tools import assert_equals @with_sitl diff --git a/tests/sitl/test_localposition.py b/tests/sitl/test_localposition.py index 42063edc1..e3e116a67 100644 --- a/tests/sitl/test_localposition.py +++ b/tests/sitl/test_localposition.py @@ -1,7 +1,6 @@ -from dronekit import connect -from dronekit.tools import with_sitl -from dronekit.lib import VehicleMode, LocationGlobal import time +from dronekit import connect, VehicleMode, LocationGlobal +from dronekit.tools import with_sitl from nose.tools import assert_not_equals @with_sitl diff --git a/tests/sitl/test_simpledemo.py b/tests/sitl/test_simpledemo.py index 760f66866..e3abe755d 100644 --- a/tests/sitl/test_simpledemo.py +++ b/tests/sitl/test_simpledemo.py @@ -3,13 +3,11 @@ Feel free to copy and modify at your leisure. """ -from dronekit import connect -from dronekit.lib import VehicleMode -from dronekit.tools import with_sitl -from pymavlink import mavutil import time import sys import os +from dronekit import connect, VehicleMode +from dronekit.tools import with_sitl from nose.tools import assert_equals # This test runs first! diff --git a/tests/sitl/test_vehicleclass.py b/tests/sitl/test_vehicleclass.py index 0d87d1527..551691f89 100644 --- a/tests/sitl/test_vehicleclass.py +++ b/tests/sitl/test_vehicleclass.py @@ -1,6 +1,6 @@ +import time from dronekit import connect, Vehicle from dronekit.tools import with_sitl -import time from nose.tools import assert_equals class DummyVehicle(Vehicle): diff --git a/tests/sitl/test_waypoints.py b/tests/sitl/test_waypoints.py index ef3e132f1..8e9dd788c 100644 --- a/tests/sitl/test_waypoints.py +++ b/tests/sitl/test_waypoints.py @@ -1,10 +1,7 @@ -from dronekit import connect import time import math -from dronekit import connect +from dronekit import connect, VehicleMode, LocationGlobal from dronekit.tools import with_sitl -from dronekit.lib import VehicleMode, LocationGlobal -import time from nose.tools import assert_not_equals # This test runs first! From 69bfec0618c4602d09e451ed86e38bf1f925c542 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 28 Oct 2015 12:37:44 +1100 Subject: [PATCH 075/475] Fixes incorrect string for serial connection to device with baud rate --- docs/guide/getting_started.rst | 350 ++++++++++++++++----------------- 1 file changed, 175 insertions(+), 175 deletions(-) diff --git a/docs/guide/getting_started.rst b/docs/guide/getting_started.rst index d0cf27e2b..452af9b33 100644 --- a/docs/guide/getting_started.rst +++ b/docs/guide/getting_started.rst @@ -1,175 +1,175 @@ -.. _get-started: - -=============== -Getting Started -=============== - -DroneKit-Python apps are typically run on Linux-based *companion computers* that travel -on the vehicle and communicate with the autopilot via a serial port. However, during development it is usually easier to -prototype apps on a standard Mac, Windows, or Linux computer using a *simulated* autopilot. - - -This topic explains how to set up and run DroneKit-Python on the different host operating systems -and then create and run a basic DroneKit app. - - - -Setting up the vehicle/autopilot -================================ - -For information on how to set up a vehicle (real and simulated) see: - -* :ref:`supported-companion-computers` for links to tested hardware/software configurations for a number of onboard Linux computers. -* :ref:`sitl_setup` for links explaining how to set up a simulated vehicle for Copter, Plane, or Rover. - - - -Installing DroneKit -=================== - -*DroneKit* can be installed on Linux, Windows and Mac OSX. - - -.. _getting_started_installing_dronekit_linux: - -Installing DroneKit on Linux ----------------------------- - -If you are using Ubuntu or Debian Linux you can get most of the *DroneKit* dependencies by running: - -.. code:: bash - - sudo apt-get install python-pip python-dev - - -The remaining dependencies are installed when you get DroneKit-Python from the public PyPi repository: - -.. code:: bash - - sudo pip install dronekit - - - -.. tip:: - - If you are planning to run *DroneKit* on a :ref:`companion computer `, make sure that the - computer runs a variant of Linux that support Python and can install Python packages from the internet. - - -Installing DroneKit on Mac OSX ------------------------------- - -Install DroneKit-Python and its dependencies from the public PyPi repository: - -.. code:: bash - - sudo pip install dronekit - - - -.. _get_started_install_dk_windows: - -Installing DroneKit on Windows ------------------------------- - -Set up a command line DroneKit-Python installation using *WinPython* (this Python distribution already includes most of the needed dependencies). - - -#. Download and run the correct `WinPython installer `_ (**v2.7**) for your platform (win32 vs win64). - - * Run the installer as an administrator (**Right-click** on file, select **Run as Administrator**). - * When prompted for the destination location, specify **C:\\Program Files (x86)** - (the default location is under the **Downloads** folder). - -#. Register the Python that came from *WinPython* as the preferred interpreter for your machine: - - Open the folder where you installed WinPython, run *WinPython Control Panel* and choose **Advanced/Register Distribution**. - - .. image:: http://dev.ardupilot.com/wp-content/uploads/sites/6/2014/03/Screenshot-from-2014-09-03-083816.png - -#. Install DroneKit-Python and its remaining dependencies from the public PyPi repository: - - Open the *WinPython Command Prompt* and run the following command: - - .. code:: bash - - pip install dronekit - - - -.. _get_started_connect_string: - -.. _get_started_connecting: - -Connecting to a Vehicle -======================= - -The connection to the vehicle is set up within the DroneKit script. Scripts import and call the :py:func:`connect()` method. -After connecting this returns a :py:class:`Vehicle ` object from which you can get/set parameters -and attributes, and control vehicle movement. - -.. code:: python - - from dronekit import connect - - # Connect to UDP endpoint. - vehicle = connect('127.0.0.1:14550', await_params=True) - -.. note:: - - Calling ``connect()`` with ``await_params=True`` (as shown above) ensures that the method will not return until - :py:attr:`Vehicle.parameters ` is fully populated with values from the vehicle. - Vehicle *attributes* are populated in parallel but are not guaranteed to have values when ``connect()`` completes - (an attribute will have value ``None`` if a corresponding MAVLink message has not been received - for example, - if the attribute is not supported by the vehicle). - -The example above connects to the udp address ``127.0.0.1:14550``. The table below shows addresses to use some of -the more common connection types: - - - -.. list-table:: Connection string options - :widths: 10 10 - :header-rows: 1 - - * - Connection type - - Connection string - * - Linux computer connected to the vehicle via USB - - ``/dev/ttyUSB0`` - * - Linux computer connected to the vehicle via Serial port (RaspberryPi example) - - ``/dev/ttyAMA0 --baudrate 57600`` - * - SITL connected to the vehicle via UDP - - ``127.0.0.1:14550`` - * - OSX computer connected to the vehicle via USB - - ``dev/cu.usbmodem1`` - * - Windows computer connected to the vehicle via USB (in this case on COM14) - - ``com14`` - -.. tip:: - - The strings above are the same as you would use if connecting with MAVProxy. For other options see the - `MAVProxy documentation `_. - - -You can start this simple script in the same way you would start any other standalone Python script. - -.. code-block:: bash - - python your_dronekit_script.py - - - -.. todo:: Connect method here needs to link to the function, but it isn't exported yet. Fix that once the API tidied. - - - - -.. _getting-started-running_examples: - -Running an app/example -====================== - -This SDK has :ref:`numerous examples `. We recommend you start with :ref:`example-vehicle-state`, -which reads and writes :ref:`vehicle state and parameter ` information. - -For general information on running the examples (and other apps) see :ref:`running_examples_top`. +.. _get-started: + +=============== +Getting Started +=============== + +DroneKit-Python apps are typically run on Linux-based *companion computers* that travel +on the vehicle and communicate with the autopilot via a serial port. However, during development it is usually easier to +prototype apps on a standard Mac, Windows, or Linux computer using a *simulated* autopilot. + + +This topic explains how to set up and run DroneKit-Python on the different host operating systems +and then create and run a basic DroneKit app. + + + +Setting up the vehicle/autopilot +================================ + +For information on how to set up a vehicle (real and simulated) see: + +* :ref:`supported-companion-computers` for links to tested hardware/software configurations for a number of onboard Linux computers. +* :ref:`sitl_setup` for links explaining how to set up a simulated vehicle for Copter, Plane, or Rover. + + + +Installing DroneKit +=================== + +*DroneKit* can be installed on Linux, Windows and Mac OSX. + + +.. _getting_started_installing_dronekit_linux: + +Installing DroneKit on Linux +---------------------------- + +If you are using Ubuntu or Debian Linux you can get most of the *DroneKit* dependencies by running: + +.. code:: bash + + sudo apt-get install python-pip python-dev + + +The remaining dependencies are installed when you get DroneKit-Python from the public PyPi repository: + +.. code:: bash + + sudo pip install dronekit + + + +.. tip:: + + If you are planning to run *DroneKit* on a :ref:`companion computer `, make sure that the + computer runs a variant of Linux that support Python and can install Python packages from the internet. + + +Installing DroneKit on Mac OSX +------------------------------ + +Install DroneKit-Python and its dependencies from the public PyPi repository: + +.. code:: bash + + sudo pip install dronekit + + + +.. _get_started_install_dk_windows: + +Installing DroneKit on Windows +------------------------------ + +Set up a command line DroneKit-Python installation using *WinPython* (this Python distribution already includes most of the needed dependencies). + + +#. Download and run the correct `WinPython installer `_ (**v2.7**) for your platform (win32 vs win64). + + * Run the installer as an administrator (**Right-click** on file, select **Run as Administrator**). + * When prompted for the destination location, specify **C:\\Program Files (x86)** + (the default location is under the **Downloads** folder). + +#. Register the Python that came from *WinPython* as the preferred interpreter for your machine: + + Open the folder where you installed WinPython, run *WinPython Control Panel* and choose **Advanced/Register Distribution**. + + .. image:: http://dev.ardupilot.com/wp-content/uploads/sites/6/2014/03/Screenshot-from-2014-09-03-083816.png + +#. Install DroneKit-Python and its remaining dependencies from the public PyPi repository: + + Open the *WinPython Command Prompt* and run the following command: + + .. code:: bash + + pip install dronekit + + + +.. _get_started_connect_string: + +.. _get_started_connecting: + +Connecting to a Vehicle +======================= + +The connection to the vehicle is set up within the DroneKit script. Scripts import and call the :py:func:`connect()` method. +After connecting this returns a :py:class:`Vehicle ` object from which you can get/set parameters +and attributes, and control vehicle movement. + +.. code:: python + + from dronekit import connect + + # Connect to UDP endpoint. + vehicle = connect('127.0.0.1:14550', await_params=True) + +.. note:: + + Calling ``connect()`` with ``await_params=True`` (as shown above) ensures that the method will not return until + :py:attr:`Vehicle.parameters ` is fully populated with values from the vehicle. + Vehicle *attributes* are populated in parallel but are not guaranteed to have values when ``connect()`` completes + (an attribute will have value ``None`` if a corresponding MAVLink message has not been received - for example, + if the attribute is not supported by the vehicle). + +The example above connects to the udp address ``127.0.0.1:14550``. The table below shows addresses to use some of +the more common connection types: + + + +.. list-table:: Connection string options + :widths: 10 10 + :header-rows: 1 + + * - Connection type + - Connection string + * - Linux computer connected to the vehicle via USB + - ``/dev/ttyUSB0`` + * - Linux computer connected to the vehicle via Serial port (RaspberryPi example) + - ``/dev/ttyAMA0,57600`` + * - SITL connected to the vehicle via UDP + - ``127.0.0.1:14550`` + * - OSX computer connected to the vehicle via USB + - ``dev/cu.usbmodem1`` + * - Windows computer connected to the vehicle via USB (in this case on COM14) + - ``com14`` + +.. tip:: + + The strings above are the same as you would use if connecting with MAVProxy. For other options see the + `MAVProxy documentation `_. + + +You can start this simple script in the same way you would start any other standalone Python script. + +.. code-block:: bash + + python your_dronekit_script.py + + + +.. todo:: Connect method here needs to link to the function, but it isn't exported yet. Fix that once the API tidied. + + + + +.. _getting-started-running_examples: + +Running an app/example +====================== + +This SDK has :ref:`numerous examples `. We recommend you start with :ref:`example-vehicle-state`, +which reads and writes :ref:`vehicle state and parameter ` information. + +For general information on running the examples (and other apps) see :ref:`running_examples_top`. From f3187d31d0a1f10c3b1a4fdaa8c36aa5de30a6b0 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 28 Oct 2015 15:08:53 +1100 Subject: [PATCH 076/475] Improve about section of docs --- docs/about/github_latest_release.txt | 2 +- docs/about/overview.rst | 15 +++++++++++---- docs/about/release_notes.rst | 8 +++++--- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/docs/about/github_latest_release.txt b/docs/about/github_latest_release.txt index 719294867..90a1b229f 100644 --- a/docs/about/github_latest_release.txt +++ b/docs/about/github_latest_release.txt @@ -17,7 +17,7 @@ Source Code ----------- -Source code is available at . +Source code is available `here `_. * View `**commits** included in this release `_ * View `**bugs** closed by this release `_ diff --git a/docs/about/overview.rst b/docs/about/overview.rst index f9372f8a2..4de1008bc 100644 --- a/docs/about/overview.rst +++ b/docs/about/overview.rst @@ -18,9 +18,16 @@ If you want to join the community, then see our :doc:`contributing section <../c Compatibility ============= -DroneKit-Python is compatible with all vehicles using the `MAVLink protocol `_ (including most vehicles made by 3DR and other members of the `DroneCode foundation `_). It runs on Linux, Mac OS X, or Windows. +DroneKit-Python is compatible with vehicles that communicate using the `MAVLink protocol `_ (including most vehicles made by `3DR `_ and other members of the `DroneCode foundation `_). It runs on Linux, Mac OS X, or Windows. -In addition to "Air apps", it can be used to create apps that run on a desktop ground station and communicate with ArduPilot over a higher latency RF-link. +.. note:: + + DroneKit-Python is validated against, and hence *most compatible* with, the `ArduPilot UAV Platform `_. + Vehicles running other autopilots may be be less compatible due to differences in adhererence/interpretation of the MAVLink specification. + Please report any autopilot-specific issues `on Github here `_. + + +In addition to creating apps that run on companion computers, DroneKit-Python apps can be used on ground stations and communicate with vehicles over a higher latency RF-link. API features @@ -29,12 +36,12 @@ API features The API provides classes and methods to: -- Get a list of connected vehicles. +- Connect to a vehicle (or multiple vehicles) from a script - Get and set vehicle state/telemetry and parameter information. - Receive asynchronous notification of state changes. -- Create and manage waypoint missions (AUTO mode). - Guide a UAV to specified position (GUIDED mode). - Send arbitrary custom messages to control UAV movement and other hardware (GUIDED mode). +- Create and manage waypoint missions (AUTO mode). - Override RC channel settings. A complete API reference is available :ref:`here `. diff --git a/docs/about/release_notes.rst b/docs/about/release_notes.rst index fb4c44d60..4e5b91107 100644 --- a/docs/about/release_notes.rst +++ b/docs/about/release_notes.rst @@ -23,12 +23,14 @@ For information about all past releases, please see `this link on Github `_ for a list of all releases available on PyPI. From d196e57f06afafed11783b24e22fc098bba44664 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 28 Oct 2015 16:53:55 +1100 Subject: [PATCH 077/475] Remove focus on air-interface --- docs/about/overview.rst | 7 +++---- docs/index.rst | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/about/overview.rst b/docs/about/overview.rst index 4de1008bc..3d94e9fd4 100644 --- a/docs/about/overview.rst +++ b/docs/about/overview.rst @@ -2,9 +2,10 @@ About DroneKit ============== -DroneKit-Python is DroneKit's main API for *Air Computing* — allowing developers to create apps that run on an onboard :ref:`companion computer ` and communicate with the `ArduPilot `_ flight controller using a low-latency link. *Air apps* can significantly enhance the autopilot, adding greater intelligence to vehicle behaviour, and performing tasks that are computationally intensive or time-sensitive (for example, computer vision, path planning, or 3D modelling). +DroneKit-Python allows developers to create apps that run on an onboard :ref:`companion computer ` and communicate with the `ArduPilot `_ flight controller using a low-latency link. Onboard apps can significantly enhance the autopilot, adding greater intelligence to vehicle behaviour, and performing tasks that are computationally intensive or time-sensitive (for example, computer vision, path planning, or 3D modelling). DroneKit-Python can also be used for ground station apps, communicating with vehicles over a higher latency RF-link. + +The API communicates with vehicles over MAVLink. It provides programmatic access to a connected vehicle's telemetry, state and parameter information, and enables both mission management and direct control over vehicle movement and operations. -The API communicates with "locally connected" vehicles over MAVLink. It provides programmatic access to a connected vehicle's telemetry, state and parameter information, and enables both mission management and direct control over vehicle movement and operations. Open source community @@ -27,8 +28,6 @@ DroneKit-Python is compatible with vehicles that communicate using the `MAVLink Please report any autopilot-specific issues `on Github here `_. -In addition to creating apps that run on companion computers, DroneKit-Python apps can be used on ground stations and communicate with vehicles over a higher latency RF-link. - API features ============ diff --git a/docs/index.rst b/docs/index.rst index 9e6be77d0..c01be21b5 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -7,9 +7,9 @@ Welcome to DroneKit-Python's documentation! =========================================== -DroneKit's Python API helps you create powerful apps for air-based control of UAVs. These apps run on a UAV's :ref:`Companion Computer `, and augment the autopilot by performing tasks that are both computationally intensive and require a low-latency link (e.g. computer vision). +DroneKit-Python helps you create powerful apps for UAVs. These apps run on a UAV's :ref:`Companion Computer `, and augment the autopilot by performing tasks that are both computationally intensive and require a low-latency link (e.g. computer vision). -This documentation provides everything you need to :ref:`get started ` with DroneKit-Python, including an :doc:`overview ` of the API, guide material, a number of demos and examples, and :doc:`API Reference `. +This documentation provides everything you need to :doc:`get started ` with DroneKit-Python, including an :doc:`overview ` of the API, guide material, a number of demos and examples, and :doc:`API Reference `. Contents: From 26d82b48bee7ded2b70ce3115d2d2e8db95cd314 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 28 Oct 2015 15:10:46 -0700 Subject: [PATCH 078/475] Exports Commands. Implements Commands.__len__ --- dronekit/__init__.py | 2 ++ dronekit/lib/__init__.py | 8 ++++++++ tests/sitl/test_waypoints.py | 30 +++++++++++++++++++++++++++--- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index ae62a04e3..424574f3d 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -20,6 +20,8 @@ # Public re-exports Vehicle = dronekit.lib.Vehicle +Command = dronekit.lib.Command +CommandSequence = dronekit.lib.CommandSequence VehicleMode = dronekit.lib.VehicleMode LocationGlobal = dronekit.lib.LocationGlobal LocationLocal = dronekit.lib.LocationLocal diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index bb83cda93..779893823 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1087,6 +1087,14 @@ def next(self, index): """ self.__module.master.waypoint_set_current_send(index) + def __len__(self): + ''' + Return number of waypoints. + + :return: The number of waypoints in the sequence. + ''' + return self.__module.wploader.count() + def __getitem__(self, index): return self.__module.wploader.wp(index) diff --git a/tests/sitl/test_waypoints.py b/tests/sitl/test_waypoints.py index 8e9dd788c..17d3b4328 100644 --- a/tests/sitl/test_waypoints.py +++ b/tests/sitl/test_waypoints.py @@ -1,10 +1,9 @@ import time import math -from dronekit import connect, VehicleMode, LocationGlobal +from dronekit import connect, VehicleMode, LocationGlobal, Command from dronekit.tools import with_sitl from nose.tools import assert_not_equals -# This test runs first! @with_sitl def test_parameter(connpath): # Connect to the Vehicle @@ -13,6 +12,31 @@ def test_parameter(connpath): cmds = vehicle.commands cmds.download() cmds.wait_valid() + cmds.clear() + vehicle.flush() + + print 'hi' + + # home + cmds.download() + cmds.wait_valid() - vehicle.commands.clear() + for command in [ + Command(0, 0, 0, 0, 16, 1, 1, 0.0, 0.0, 0.0, 0.0, -35.3605, 149.172363, 747.0), + Command(0, 0, 0, 3, 22, 0, 1, 0.0, 0.0, 0.0, 0.0, -35.359831, 149.166334, 100.0), + Command(0, 0, 0, 3, 16, 0, 1, 0.0, 0.0, 0.0, 0.0, -35.363489, 149.167213, 100.0), + Command(0, 0, 0, 3, 16, 0, 1, 0.0, 0.0, 0.0, 0.0, -35.355491, 149.169595, 100.0), + Command(0, 0, 0, 3, 16, 0, 1, 0.0, 0.0, 0.0, 0.0, -35.355071, 149.175839, 100.0), + Command(0, 0, 0, 3, 113, 0, 1, 0.0, 0.0, 0.0, 0.0, -35.362666, 149.178715, 22222.0), + Command(0, 0, 0, 3, 115, 0, 1, 2.0, 22.0, 1.0, 3.0, 0.0, 0.0, 0.0), + Command(0, 0, 0, 3, 16, 0, 1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), + ]: + cmds.add(command) vehicle.flush() + + cmds.download() + cmds.wait_valid() + for cmd in cmds[1:]: #skip first item as it is home waypoint. + print(cmd) + + print(len(cmds)) From ea8ff0dba970cc14b26ede992781dbd3cd6354c2 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 28 Oct 2015 15:36:52 -0700 Subject: [PATCH 079/475] Implements waypoint uploading. --- dronekit/__init__.py | 14 +++++++++++--- tests/sitl/test_waypoints.py | 18 +++++++++--------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 424574f3d..73a6ba128 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -70,6 +70,7 @@ def __init__(self, master, vehicle_class=Vehicle): # waypoints self.wploader = mavwp.MAVWPLoader() self.wp_loaded = True + self.wp_uploaded = None # Attaches message listeners. self.message_listeners = dict() @@ -268,7 +269,11 @@ def send_all_waypoints(self): """ self.master.waypoint_clear_all_send() if self.wploader.count() > 0: + self.wp_uploaded = [False]*self.wploader.count() self.master.waypoint_count_send(self.wploader.count()) + while False in self.wp_uploaded: + time.sleep(0.1) + self.wp_uploaded = None def fix_targets(self, message): pass @@ -511,9 +516,12 @@ def mavlink_thread(): self.last_waypoint = msg.seq # Waypoint send to master - # TODO - if msg.get_type() in ["WAYPOINT_REQUEST", "MISSION_REQUEST"]: - pass + if self.wp_uploaded != None and msg.get_type() in ["WAYPOINT_REQUEST", "MISSION_REQUEST"]: + wp = self.wploader.wp(msg.seq) + wp.target_system = self.target_system + wp.target_component = self.target_component + self.master.mav.send(wp) + self.wp_uploaded[msg.seq] = True # Heartbeat: armed + mode update if msg.get_type() == 'HEARTBEAT': diff --git a/tests/sitl/test_waypoints.py b/tests/sitl/test_waypoints.py index 17d3b4328..1a745e560 100644 --- a/tests/sitl/test_waypoints.py +++ b/tests/sitl/test_waypoints.py @@ -2,25 +2,27 @@ import math from dronekit import connect, VehicleMode, LocationGlobal, Command from dronekit.tools import with_sitl -from nose.tools import assert_not_equals +from nose.tools import assert_not_equals, assert_equals @with_sitl def test_parameter(connpath): # Connect to the Vehicle vehicle = connect(connpath, await_params=True) + # Initial cmds = vehicle.commands cmds.download() cmds.wait_valid() + assert_equals(len(cmds), 1) + + # After clearing cmds.clear() vehicle.flush() - - print 'hi' - - # home cmds.download() cmds.wait_valid() + assert_equals(len(cmds), 1) + # Upload for command in [ Command(0, 0, 0, 0, 16, 1, 1, 0.0, 0.0, 0.0, 0.0, -35.3605, 149.172363, 747.0), Command(0, 0, 0, 3, 22, 0, 1, 0.0, 0.0, 0.0, 0.0, -35.359831, 149.166334, 100.0), @@ -34,9 +36,7 @@ def test_parameter(connpath): cmds.add(command) vehicle.flush() + # After upload cmds.download() cmds.wait_valid() - for cmd in cmds[1:]: #skip first item as it is home waypoint. - print(cmd) - - print(len(cmds)) + assert_equals(len(cmds), 9) From c041c8ee0d23adfd38431a51b9bf6836fcc06839 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 28 Oct 2015 18:36:06 -0700 Subject: [PATCH 080/475] 2.0.0rc2 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 628e9204e..9b98e22ec 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.0.0c1' +version = '2.0.0rc2' setup(name='dronekit', zip_safe=True, From f51df48d509feb15f98c3acffdc06b099c89d3c7 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 29 Oct 2015 09:55:13 +1100 Subject: [PATCH 081/475] Update README.md New readme - already reviewed by @mrpollo --- README.md | 77 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 11d784a22..ee3dad2c3 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,69 @@ # DroneKit Python +![dronekit_python_logo](https://cloud.githubusercontent.com/assets/5368500/10805537/90dd4b14-7e22-11e5-9592-5925348a7df9.png) + ![PyPi published version](https://img.shields.io/pypi/v/dronekit.svg) [![Windows Build status](https://img.shields.io/appveyor/ci/3drobotics/dronekit-python/master.svg?label=windows)](https://ci.appveyor.com/project/3drobotics/dronekit-python/branch/master) [![OS X Build Status](https://img.shields.io/travis/dronekit/dronekit-python/master.svg?label=os%20x)](https://travis-ci.org/dronekit/dronekit-python) -[![Linux Build Status](https://img.shields.io/circleci/project/dronekit/dronekit-python/master.svg?label=linux)](https://circleci.com/gh/dronekit/dronekit-python) +[![Linux Build Status](https://img.shields.io/circleci/project/dronekit/dronekit-python/master.svg?label=linux)](https://circleci.com/gh/dronekit/dronekit-python) + +DroneKit-Python helps you create powerful apps for UAVs. + + +## Overview + +DroneKit-Python (formerly DroneAPI-Python) contains the python language implementation of DroneKit. + +The API allows developers to create Python apps that communicate with vehicles over MAVLink. It provides programmatic access to a connected vehicle's telemetry, state and parameter information, and enables both mission management and direct control over vehicle movement and operations. + +The API is primarily intended for use in onboard companion computers (to support advanced use cases including computer vision, path planning, 3D modelling etc). It can also be used for ground station apps, communicating with vehicles over a higher latency RF-link. + +## Getting Started + +The [Getting Started](http://python.dronekit.io/guide/getting_started.html) guide explains how to set up DroneKit on each of the supported platforms (Linux, Mac OSX, Windows) and how to write a script to connect to verhicle (real or simulated). + +A basic script looks like this: + +```python +from dronekit import connect +from dronekit.lib import VehicleMode + +# Connect to UDP endpoint. +vehicle = connect('127.0.0.1:14550', await_params=True) +# Use returned Vehicle object to query device state - e.g. to get the mode: +print " Mode: %s" % vehicle.mode.name +``` + +Once you've got DroneKit set up, the [guide](http://python.dronekit.io/guide/index.html) explains how to perform operations like taking off and flying the vehicle. You can also try out most of the tasks by running the [examples](http://python.dronekit.io/examples/index.html). + +## Resources + +The project has documentation is available at http://python.dronekit.io/. This includes [guide](http://python.dronekit.io/guide/index.html), [example](http://python.dronekit.io/examples/index.html) and [API Reference](http://python.dronekit.io/automodule.html) material. + +The example source code is hosted here on Github as sub-folders of [/dronekit-python/examples](https://github.com/dronekit/dronekit-python/tree/master/examples). + +The [DroneKit Forums](http://discuss.dronekit.io) are the best place to ask for technical support on how to use the library. You can also check out our [Gitter channel](https://gitter.im/dronekit/dronekit-python?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) though we prefer posts on the forums where possible. + +* **Documentation:** (http://python.dronekit.io/)[http://python.dronekit.io/] +* **Guides:** (http://python.dronekit.io/guide/index.html)[http://python.dronekit.io/guide/index.html] +* **API Reference:** (http://python.dronekit.io/automodule.html)[http://python.dronekit.io/automodule.html] +* **Examples:** [/dronekit-python/examples](https://github.com/dronekit/dronekit-python/tree/master/examples) +* **Forums:** [http://discuss.dronekit.io/](http://discuss.dronekit.io) +* **Gitter:** [https://gitter.im/dronekit/dronekit-python](https://gitter.im/dronekit/dronekit-python?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) though we prefer posts on the forums where possible. + -[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/dronekit/dronekit-python?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +## Users and contributors wanted! -*(Formerly DroneAPI-python.)* +We'd love your [feedback and suggestions](https://github.com/dronekit/dronekit-python/issues) about this API and are eager to evolve it to meet your needs, please feel free to create an issue to report bugs or feature requests. -This package contains the python language implementation of DroneKit. +If you want to contribute, see our [Contributing](http://python.dronekit.io/contributing/index.html) guidelines, we welcome all types of contributions but mostly contributions that would help us shrink our issues list [https://github.com/dronekit/dronekit-python/issues](https://github.com/dronekit/dronekit-python/issues) -## Users wanted! -We'd love your [feedback and suggestions](https://github.com/dronekit/dronekit-python/issues) about this API and are eager to evolve it to meet your needs. +## Licence -For documentation on how to use this API please see: +DroneKit-Python is made available under the permissive open source [Apache 2.0 License](http://python.dronekit.io/about/license.html). -* The new DroneKit-python [website](http://python.dronekit.io/) -* Our [tutorial](http://dev.ardupilot.com/wiki/droneapi-tutorial/) on the ardupilot wiki -* The [overview document](https://docs.google.com/document/d/1ihKneLwA4hXmKS1W2pbG9lty_EAwbmy0giusUwQ8dto) -* The [python autodocs](http://python.dronekit.io/automodule.html) -* The [python code](droneapi/lib/__init__.py) itself -* Answers to [technical support queries](http://stackoverflow.com/questions/tagged/dronekit-python) on Stack Overflow. -* Example code can be found here: ['examples/'](examples/) - * Beginner ['vehicle_state'](examples/vehicle_state/vehicle_state.py) - * Beginner ['simple_goto'](examples/simple_goto/simple_goto.py) - * Beginner ['flight_replay'](examples/flight_replay/flight_replay.py) - * Beginner ['gcs'](examples/gcs/microgcs.py) - * Advanced ['drone_delivery'](examples/drone_delivery/) - * Advanced ['follow-me'](examples/follow_me/) -The [DroneKit Forums](http://discuss.dronekit.io) is the best place to ask for technical support on how to use the library. +*** -Copyright 2015 3D Robotics, Inc. Licensed under the Apache 2.0 License. +Copyright 2015 3D Robotics, Inc. From 29dda664fe98c9d8f73239014e9d97293ca41b6c Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 29 Oct 2015 10:04:04 +1100 Subject: [PATCH 082/475] Update README.md Fix up some of the links --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ee3dad2c3..7e97bf5cd 100644 --- a/README.md +++ b/README.md @@ -44,9 +44,9 @@ The example source code is hosted here on Github as sub-folders of [/dronekit-py The [DroneKit Forums](http://discuss.dronekit.io) are the best place to ask for technical support on how to use the library. You can also check out our [Gitter channel](https://gitter.im/dronekit/dronekit-python?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) though we prefer posts on the forums where possible. -* **Documentation:** (http://python.dronekit.io/)[http://python.dronekit.io/] -* **Guides:** (http://python.dronekit.io/guide/index.html)[http://python.dronekit.io/guide/index.html] -* **API Reference:** (http://python.dronekit.io/automodule.html)[http://python.dronekit.io/automodule.html] +* **Documentation:** [http://python.dronekit.io/](http://python.dronekit.io/) +* **Guides:** [http://python.dronekit.io/guide/index.html](http://python.dronekit.io/guide/index.html) +* **API Reference:** [http://python.dronekit.io/automodule.html](http://python.dronekit.io/automodule.html) * **Examples:** [/dronekit-python/examples](https://github.com/dronekit/dronekit-python/tree/master/examples) * **Forums:** [http://discuss.dronekit.io/](http://discuss.dronekit.io) * **Gitter:** [https://gitter.im/dronekit/dronekit-python](https://gitter.im/dronekit/dronekit-python?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) though we prefer posts on the forums where possible. From 3b2f4f48844d9d13aaf95d2455f91bb0c14cf69a Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 29 Oct 2015 10:25:28 +1100 Subject: [PATCH 083/475] Update README.md More fixes to the way links are presented, and one typo fix. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7e97bf5cd..1d27a8c38 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Once you've got DroneKit set up, the [guide](http://python.dronekit.io/guide/ind ## Resources -The project has documentation is available at http://python.dronekit.io/. This includes [guide](http://python.dronekit.io/guide/index.html), [example](http://python.dronekit.io/examples/index.html) and [API Reference](http://python.dronekit.io/automodule.html) material. +The project documentation is available at [python.dronekit.io](http://python.dronekit.io/). This includes [guide](http://python.dronekit.io/guide/index.html), [example](http://python.dronekit.io/examples/index.html) and [API Reference](http://python.dronekit.io/automodule.html) material. The example source code is hosted here on Github as sub-folders of [/dronekit-python/examples](https://github.com/dronekit/dronekit-python/tree/master/examples). @@ -56,7 +56,7 @@ The [DroneKit Forums](http://discuss.dronekit.io) are the best place to ask for We'd love your [feedback and suggestions](https://github.com/dronekit/dronekit-python/issues) about this API and are eager to evolve it to meet your needs, please feel free to create an issue to report bugs or feature requests. -If you want to contribute, see our [Contributing](http://python.dronekit.io/contributing/index.html) guidelines, we welcome all types of contributions but mostly contributions that would help us shrink our issues list [https://github.com/dronekit/dronekit-python/issues](https://github.com/dronekit/dronekit-python/issues) +If you want to contribute, see our [Contributing](http://python.dronekit.io/contributing/index.html) guidelines, we welcome all types of contributions but mostly contributions that would help us shrink our [issues list](https://github.com/dronekit/dronekit-python/issues). ## Licence From 68f4a5c05dd7bf051d0c6ec5c7592ea3ec2f8ad0 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 29 Oct 2015 11:02:00 +1100 Subject: [PATCH 084/475] Update README.md Yet another typo fix. Grrr. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1d27a8c38..f04ee20af 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ The API is primarily intended for use in onboard companion computers (to support ## Getting Started -The [Getting Started](http://python.dronekit.io/guide/getting_started.html) guide explains how to set up DroneKit on each of the supported platforms (Linux, Mac OSX, Windows) and how to write a script to connect to verhicle (real or simulated). +The [Getting Started](http://python.dronekit.io/guide/getting_started.html) guide explains how to set up DroneKit on each of the supported platforms (Linux, Mac OSX, Windows) and how to write a script to connect to a vehicle (real or simulated). A basic script looks like this: From 04fa3e26c71204d069e36a74ef584348c0fce315 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 29 Oct 2015 14:51:17 -0700 Subject: [PATCH 085/475] Removes dronekit.module --- dronekit/module/__init__.py | 0 dronekit/module/api.py | 470 ------------------------------------ 2 files changed, 470 deletions(-) delete mode 100644 dronekit/module/__init__.py delete mode 100644 dronekit/module/api.py diff --git a/dronekit/module/__init__.py b/dronekit/module/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/dronekit/module/api.py b/dronekit/module/api.py deleted file mode 100644 index bc77e0703..000000000 --- a/dronekit/module/api.py +++ /dev/null @@ -1,470 +0,0 @@ -import os -import time -import threading -import traceback -import logging -import math -from pymavlink import mavutil -from dronekit.lib import Vehicle, VehicleMode, LocationLocal, \ - LocationGlobal, Attitude, GPSInfo, Parameters, CommandSequence, \ - APIException, Battery, Rangefinder - -# Enable logging here (until this code can be moved into mavproxy) -logging.basicConfig(level=logging.DEBUG) - -logger = logging.getLogger(__name__) - -class Vehicle(HasObservers): - """ - The main vehicle API - - Asynchronous notification on change of vehicle state is available by registering observers (callbacks) for attribute changes. - - Most vehicle state is exposed through python attributes (e.g. ``vehicle.location``). Most of these attributes are - auto-populated based on the capabilities of the connected autopilot/vehicle. - - Particular autopilots/vehicles may define different attributes from this standard list (extra batteries, GPIOs, etc.) - However if a standard attribute is defined it must follow the rules specified below. - - **Autopilot specific attributes & types:** - - To prevent name clashes the following naming convention should be used: - - * ``ap_`` - For autopilot specific parameters (apm 2.5, pixhawk etc.). For example "ap_pin5_mode" and "ap_pin5_value". - * ``user_`` - For user specific parameters - - **Standard attributes & types:** - - .. py:attribute:: location.global_frame - - Current :py:class:`LocationGlobal`. - - - .. py:attribute:: location.local_frame - - Current :py:class:`LocationLocal`. - - - .. py:attribute:: attitude - - Current vehicle :py:class:`Attitude` (pitch, yaw, roll). - - - .. py:attribute:: velocity - - Current velocity as a three element list ``[ vx, vy, vz ]`` (in meter/sec). - - - .. py:attribute:: mode - - This attribute is used to get and set the current flight mode (:py:class:`VehicleMode`). - - - .. py:attribute:: airspeed - - Current airspeed in metres/second (``double``). - - .. todo:: FIXME: Should airspeed value move somewhere else from "Standard attributes & types" table? - - .. py:attribute:: groundspeed - - Groundspeed in metres/second (``double``). - - .. py:attribute:: gps_0 - - GPS position information (:py:class:`GPSInfo`). - - - .. py:attribute:: armed - - This attribute can be used to get and set the ``armed`` state of the vehicle (``boolean``). - - The code below shows how to read the state, and to arm/disam the vehicle: - - .. code:: python - - # Print the armed state for the vehicle - print "Armed: %s" % vehicle.armed - - # Disarm the vehicle - vehicle.armed = False - - # Arm the vehicle - vehicle.armed = True - - - .. py:attribute:: mount_status - - Current status of the camera mount (gimbal) as a three element list: ``[ pitch, yaw, roll ]``. - - The values in the list are set to ``None`` if no mount is configured. - - - .. py:attribute:: battery - - Current system :py:class:`Battery` status. - - - .. py:attribute:: rangefinder - - :py:class:`Rangefinder` distance and voltage values. - - - .. py:attribute:: channel_override - - .. warning:: - - RC override may be useful for simulating user input and when implementing certain types of joystick control. - It should not be used for direct control of vehicle channels unless there is no other choice! - - Instead use the appropriate MAVLink commands like DO_SET_SERVO/DO_SET_RELAY, or more generally - set the desired position or direction/speed. - - This attribute takes a dictionary argument defining the RC *output* channels to be overridden (specified by channel number), and their new values. - Channels that are not specified in the dictionary are not overridden. All multi-channel updates are atomic. - - To cancel an override call ``channel_override`` again, setting zero for the overridden channels. - - The values of the first four channels map to the main flight controls: 1=Roll, 2=Pitch, 3=Throttle, 4=Yaw (the mapping is defined in ``RCMAP_`` parameters: - `Plane `_, - `Copter `_ , - `Rover `_). - - The remaining channel values are configurable, and their purpose can be determined using the - `RCn_FUNCTION parameters `_. - In general a value of 0 set for a specific ``RCn_FUNCTION`` indicates that the channel can be - `mission controlled `_ (i.e. it will not directly be - controlled by normal autopilot code). - - An example of setting and clearing the override is given below: - - .. code:: python - - # Override channels 1 and 4 (only). - vehicle.channel_override = { "1" : 900, "4" : 1000 } - - # Cancel override on channel 1 and 4 by sending 0 - vehicle.channel_override = { "1" : 0, "4" : 0 } - - - .. versionchanged:: 1.0 - - This update replaces ``rc_override`` with ``channel_override``/``channel_readback`` documentation. - - - .. todo:: Add note to the examples/guide like warning above not to use this mechanism except as intended: - - https://github.com/dronekit/dronekit-python/issues/72 - - .. todo:: - - channel_override/channel_readback documentation - - In a future update strings will be defined per vehicle type ('pitch', 'yaw', 'roll' etc...) - and rather than setting channel 3 to 1400 (for instance), you will pass in a dict with - 'throttle':1200. - - This change will be useful in two ways: - - * we can hide (eventually we can deprecate) any notion of rc channel numbers at all. - * vehicles can eventually define new 'channels' for overridden values. - - FIXME: Remaining channel_override/channel_readback FIXMEs: - - * how to address the units issue? Merely with documentation or some other way? - * is there any benefit of using lists rather than tuples for these attributes - - - .. py:attribute:: channel_readback - - This read-only attribute returns a dictionary containing the *original* vehicle RC channel values (ignoring any overrides set using - :py:attr:`channel_override `). Dictionary entries have the format ``channelName -> value``. - - For example, the returned dictionary might look like this: - - .. code:: python - - RC readback: {'1': 1500, '3': 1000, '2': 1500, '5': 1800, '4': 1500, '7': 1000, '6': 1000, '8': 1800} ? Dictionary () (read only) - - - - .. todo:: In V2, there may be ardupilot specific attributes & types (as in the introduction). If so, text below might be useful. - - **Autopilot specific attributes & types:** - - .. py:attribute:: ap_pin5_mode - - string (adc, dout, din) - - .. py:attribute:: ap_pin5_value - - ? double (0, 1, 2.3 etc...) - - - .. todo:: Add waypoint_home attribute IF this is added: https://github.com/dronekit/dronekit-python/issues/105 - - """ - - def __init__(self, module): - super(Vehicle, self).__init__() - self.mavrx_callback = None - self.__module = module - self._parameters = Parameters(module) - self._waypoints = None - self.wpts_dirty = False - - def close(self): - return self.__module.close() - - def flush(self): - """ - Call ``flush()`` after :py:func:`adding ` or :py:func:`clearing ` mission commands. - - After the return from ``flush()`` any writes are guaranteed to have completed (or thrown an - exception) and future reads will see their effects. - """ - if self.wpts_dirty: - self.__module.send_all_waypoints() - self.wpts_dirty = False - - # - # Private sugar methods - # - - @property - def __master(self): - return self.__module.master - - @property - def __mode_mapping(self): - return self.__master.mode_mapping() - - # - # Operations to support the standard API (FIXME - possibly/probably this - # will move into a private dict of getter/setter tuples (invisible to the API consumer). - # - - @property - def mode(self): - self.wait_init() # We must know vehicle type before this operation can work - return self.__get_mode() - - def __get_mode(self): - """Private method to read current vehicle mode without polling""" - return VehicleMode(self.__module.flightmode) - - @mode.setter - def mode(self, v): - self.wait_init() # We must know vehicle type before this operation can work - self.__master.set_mode(self.__mode_mapping[v.name]) - - @property - def location(self): - # For backward compatibility, this is (itself) a LocationLocal object. - ret = LocationGlobal(self.__module.lat, self.__module.lon, self.__module.alt, is_relative=False) - ret.local_frame = LocationLocal(self.__module.north, self.__module.east, self.__module.down) - ret.global_frame = LocationGlobal(self.__module.lat, self.__module.lon, self.__module.alt, is_relative=False) - return ret - - @property - def battery(self): - return Battery(self.__module.voltage, self.__module.current, self.__module.level) - - @property - def rangefinder(self): - return Rangefinder(self.__module.rngfnd_distance, self.__module.rngfnd_voltage) - - @property - def velocity(self): - return [ self.__module.vx, self.__module.vy, self.__module.vz ] - - @property - def attitude(self): - return Attitude(self.__module.pitch, self.__module.yaw, self.__module.roll) - - @property - def gps_0(self): - return GPSInfo(self.__module.eph, self.__module.epv, self.__module.fix_type, self.__module.satellites_visible) - - @property - def armed(self): - return self.__module.armed - - @armed.setter - def armed(self, value): - if value: - self.__master.arducopter_arm() - else: - self.__master.arducopter_disarm() - - @property - def system_status(self): - return self.__module.system_status - - @property - def groundspeed(self): - return self.__module.groundspeed - - @property - def airspeed(self): - return self.__module.airspeed - - @property - def mount_status(self): - return [ self.__module.mount_pitch, self.__module.mount_yaw, self.__module.mount_roll ] - - @property - def ekf_ok(self): - return self.__module.ekf_ok - - @property - def channel_override(self): - overrides = self.__rc.override - # Only return entries that have a non zero override - return dict((str(num + 1), overrides[num]) for num in range(8) if overrides[num] != 0) - - @channel_override.setter - def channel_override(self, newch): - overrides = self.__rc.override - for k, v in newch.iteritems(): - overrides[int(k) - 1] = v - self.__rc.set_override(overrides) - - @property - def channel_readback(self): - return self.__module.rc_readback - - @property - def commands(self): - """ - Gets the editable waypoints for this vehicle (the current "mission"). - - This can be used to get, create, and modify a mission. It can also be used for direct control of vehicle position - (outside missions) using the :py:func:`goto ` method. - - :returns: A :py:class:`CommandSequence` containing the waypoints for this vehicle. - """ - if(self._waypoints is None): # We create the wpts lazily (because this will start a fetch) - self._waypoints = CommandSequence(self.__module) - return self._waypoints - - @property - def parameters(self): - """ - The (editable) parameters for this vehicle (:py:class:`Parameters `). - """ - return self._parameters - - def unset_mavlink_callback(self): - """ - Clears the asynchronous notification added by :py:func:`set_mavlink_callback `. - - The code snippet below shows how to set, then clear, a MAVLink callback function. - - .. code:: python - - # Set MAVLink callback handler (after getting Vehicle instance) - vehicle.set_mavlink_callback(mavrx_debug_handler) - - # Remove the MAVLink callback handler. Callback will not be - # called after this point. - vehicle.unset_mavlink_callback() - """ - self.mavrx_callback = None - - def set_mavlink_callback(self, callback): - """ - Provides asynchronous notification when any MAVLink packet is received by this vehicle. - - Only a single callback can be set. :py:func:`unset_mavlink_callback ` removes the callback. - - .. tip:: - - This method is implemented - but we hope you don't need it. - - Because of the asynchronous attribute/waypoint/parameter notifications there should be no need for - API clients to see raw MAVLink. Please provide feedback if we missed a use-case. - - The code snippet below shows how to set a "demo" callback function as the callback handler: - - .. code:: python - - # Demo callback handler for raw MAVLink messages - def mavrx_debug_handler(message): - print "Received", message - - # Set MAVLink callback handler (after getting Vehicle instance) - vehicle.set_mavlink_callback(mavrx_debug_handler) - - :param callback: The callback function to be invoked when a raw MAVLink message is received. - - """ - self.mavrx_callback = callback - - def send_mavlink(self, message): - """ - This method is used to send raw MAVLink "custom messages" to the vehicle. - - The function can send arbitrary messages/commands to a vehicle at any time and in any vehicle mode. It is particularly useful for - controlling vehicles outside of missions (for example, in GUIDED mode). - - The :py:func:`message_factory ` is used to create messages in the appropriate format. - Callers do not need to populate sysId/componentId/crc in the packet as the method will take care of that before sending. - - :param message: A ``MAVLink_message`` instance, created using :py:func:`message_factory `. - There is need to specify the system id, component id or sequence number of messages as the API will set these appropriately. - """ - self.__module.fix_targets(message) - self.__module.master.mav.send(message) - - @property - def message_factory(self): - """ - Returns an object that can be used to create 'raw' MAVLink messages that are appropriate for this vehicle. - The message can then be sent using :py:func:`send_mavlink(message) `. - - These message types are defined in the central MAVLink github repository. For example, a Pixhawk understands - the following messages (from `pixhawk.xml `_): - - .. code:: xml - - - 0 to disable, 1 to enable - - - The name of the factory method will always be the lower case version of the message name with *_encode* appended. - Each field in the XML message definition must be listed as arguments to this factory method. So for this example - message, the call would be: - - .. code:: python - - msg = vehicle.message_factory.image_trigger_control_encode(True) - vehicle.send_mavlink(msg) - - There is no need to specify the system id, component id or sequence number of messages (if defined in the message type) as the - API will set these appropriately when the message is sent. - - .. todo:: When I have a custom message guide topic. Link from here to it. - - .. todo:: Check if the standard MAV_CMD messages can be sent this way too, and if so add link. - """ - return self.__module.master.mav - - def wait_init(self): - """Wait for the vehicle to exit the initializing step""" - timeout = 30 - pollinterval = 0.2 - for i in range(0, int(timeout / pollinterval)): - # Don't let the user try to fly while the board is still booting - mode = self.__get_mode().name - # print "mode is", mode - if mode != "INITIALISING" and mode != "MAV": - return - - time.sleep(pollinterval) - raise APIException("Vehicle did not complete initialization") - - def on_message(self, name, fn): - def handler(state, name, m): - return fn(self, name, m) - return self.__module.on_message(name, handler) From 9332f2118afaf9e74889578883f1ed9f4e139452 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 29 Oct 2015 14:51:26 -0700 Subject: [PATCH 086/475] Removes dronekit.__main__ --- dronekit/__main__.py | 107 ------------------------------------------- 1 file changed, 107 deletions(-) delete mode 100644 dronekit/__main__.py diff --git a/dronekit/__main__.py b/dronekit/__main__.py deleted file mode 100644 index c149f0a14..000000000 --- a/dronekit/__main__.py +++ /dev/null @@ -1,107 +0,0 @@ -from dronekit import local_connect - -def demo(local_connect): - # This example shows how to use DroneKit-Python to get and set vehicle state, parameter and channel-override information. - # It also demonstrates how to observe vehicle attribute (state) changes. - # - # Usage: - # * mavproxy.py - # * module load api - # * api start vehicle-state.py - # - from dronekit.lib import VehicleMode - from pymavlink import mavutil - import time - - # First get an instance of the API endpoint - api = local_connect() - # Get the connected vehicle (currently only one vehicle can be returned). - v = api.get_vehicles()[0] - - # Get all vehicle attributes (state) - print "\nGet all vehicle attribute values:" - print " Global Location: %s" % v.location.global_frame - print " Local Location: %s" % v.location.local_frame - print " Attitude: %s" % v.attitude - print " Velocity: %s" % v.velocity - print " GPS: %s" % v.gps_0 - print " Groundspeed: %s" % v.groundspeed - print " Airspeed: %s" % v.airspeed - print " Mount status: %s" % v.mount_status - print " Battery: %s" % v.battery - print " Mode: %s" % v.mode.name # settable - print " Armed: %s" % v.armed # settable - - # Set vehicle mode and armed attributes (the only settable attributes) - print "Set Vehicle.mode=GUIDED (currently: %s)" % v.mode.name - v.mode = VehicleMode("GUIDED") - v.flush() # Flush to guarantee that previous writes to the vehicle have taken place - while not v.mode.name=='GUIDED' and not api.exit: #Wait until mode has changed - print " Waiting for mode change ..." - time.sleep(1) - - print "Set Vehicle.armed=True (currently: %s)" % v.armed - v.armed = True - v.flush() - while not v.armed and not api.exit: - print " Waiting for arming..." - time.sleep(1) - - - # Show how to add and remove and attribute observer callbacks (using mode as example) - def mode_callback(attribute): - print " CALLBACK: Mode changed to: ", v.mode.name - - print "\nAdd mode attribute observer for Vehicle.mode" - v.add_attribute_observer('mode', mode_callback) - - print " Set mode=STABILIZE (currently: %s)" % v.mode.name - v.mode = VehicleMode("STABILIZE") - v.flush() - - print " Wait 2s so callback invoked before observer removed" - time.sleep(2) - - # Remove observer - specifying the attribute and previously registered callback function - v.remove_attribute_observer('mode', mode_callback) - - - # # Get Vehicle Home location ((0 index in Vehicle.commands) - # print "\nGet home location" - # cmds = v.commands - # cmds.download() - # cmds.wait_valid() - # print " Home WP: %s" % cmds[0] - - - # Get/Set Vehicle Parameters - print "\nRead vehicle param 'THR_MIN': %s" % v.parameters['THR_MIN'] - print "Write vehicle param 'THR_MIN' : 10" - v.parameters['THR_MIN']=10 - v.flush() - print "Read new value of param 'THR_MIN': %s" % v.parameters['THR_MIN'] - - - # # Overriding an RC channel - # # NOTE: CHANNEL OVERRIDES may be useful for simulating user input and when implementing certain types of joystick control. - # #DO NOT use unless there is no other choice (there almost always is!) - # print "\nOverriding RC channels for roll and yaw" - # v.channel_override = { "1" : 900, "4" : 1000 } - # v.flush() - # print " Current overrides are:", v.channel_override - # print " Channel default values:", v.channel_readback # All channel values before override - - # # Cancel override by setting channels to 0 - # print " Cancelling override" - # v.channel_override = { "1" : 0, "4" : 0 } - # v.flush() - - - ## Reset variables to sensible values. - print "\nReset vehicle atributes/parameters and exit" - v.mode = VehicleMode("STABILIZE") - v.armed = False - v.parameters['THR_MIN']=130 - v.flush() - -demo(local_connect) From 8a755d9e2921b15db8374c290768cc791909380a Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 29 Oct 2015 14:55:37 -0700 Subject: [PATCH 087/475] Removes dronekit.module installation. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 9b98e22ec..266bad796 100644 --- a/setup.py +++ b/setup.py @@ -26,6 +26,6 @@ ], license='apache', packages=[ - 'dronekit', 'dronekit.module', 'dronekit.lib' + 'dronekit', 'dronekit.lib' ], ext_modules=[]) From ee451a93af4edf42a4bd1fd37c642da37463b261 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 30 Oct 2015 16:19:28 -0700 Subject: [PATCH 088/475] Makes mode-mapping semi-private for Solo. --- dronekit/lib/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 779893823..928315c35 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -586,7 +586,7 @@ def __master(self): return self.__module.master @property - def __mode_mapping(self): + def _mode_mapping(self): return self.__master.mode_mapping() # @@ -606,7 +606,7 @@ def __get_mode(self): @mode.setter def mode(self, v): self.wait_init() # We must know vehicle type before this operation can work - self.__master.set_mode(self.__mode_mapping[v.name]) + self.__master.set_mode(self._mode_mapping[v.name]) @property def location(self): From 7ebdd63d71bc3020374b27a5e112e49b81c64826 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 30 Oct 2015 16:22:18 -0700 Subject: [PATCH 089/475] Exposes heading as a vehicle property. --- dronekit/lib/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 928315c35..9ea88d94d 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -651,6 +651,10 @@ def armed(self, value): def system_status(self): return self.__module.system_status + @property + def heading(self): + return self.__module.heading + @property def groundspeed(self): return self.__module.groundspeed From 894fce47669fdd5c6c6ec4e37281fd3af3abd77a Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 30 Oct 2015 16:25:21 -0700 Subject: [PATCH 090/475] 2.0.0rc3 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 266bad796..44e58487d 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.0.0rc2' +version = '2.0.0rc3' setup(name='dronekit', zip_safe=True, From e7f45fb86bb81670e9f9084450df7b4577707eff Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 2 Nov 2015 13:50:49 -0800 Subject: [PATCH 091/475] Use mavutils' reset logic rather than new connection. --- dronekit/__init__.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 73a6ba128..2b93aad0d 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -431,11 +431,7 @@ def mavlink_thread(): except socket.error as error: if error.errno == ECONNABORTED: errprinter('reestablishing connection after read timeout') - try: - self.master.close() - except: - pass - self.master = mavutil.mavlink_connection(self.master.address) + self.master.reset() continue # If connection reset (closed), stop polling. @@ -452,11 +448,7 @@ def mavlink_thread(): except socket.error as error: if error.errno == ECONNABORTED: errprinter('reestablishing connection after send timeout') - try: - self.master.close() - except: - pass - self.master = mavutil.mavlink_connection(self.master.address) + self.master.reset() continue # If connection reset (closed), stop polling. From 4a81fb4ec4b4cc4af1ed59929af4613e9a1e0bb7 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 2 Nov 2015 13:37:56 -0800 Subject: [PATCH 092/475] Adds baud parameter to connect(). Fixes #393. --- dronekit/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 2b93aad0d..80c58dfca 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -572,8 +572,8 @@ def close(self): time.sleep(0.1) self.master.close() -def connect(ip, await_params=False, status_printer=errprinter, vehicle_class=Vehicle, rate=4): - state = MPFakeState(mavutil.mavlink_connection(ip), vehicle_class=vehicle_class) +def connect(ip, await_params=False, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200): + state = MPFakeState(mavutil.mavlink_connection(ip, baud=baud), vehicle_class=vehicle_class) state.status_printer = status_printer state.prepare(await_params=await_params, rate=rate) return state.vehicle From 4c87222edfc61214b059175930938a91f9ae0e94 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 2 Nov 2015 15:20:54 -0800 Subject: [PATCH 093/475] Fixes reset logic. --- dronekit/__init__.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 80c58dfca..17475ddc5 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -431,7 +431,14 @@ def mavlink_thread(): except socket.error as error: if error.errno == ECONNABORTED: errprinter('reestablishing connection after read timeout') - self.master.reset() + if hasattr(self.master, 'reset'): + self.master.reset() + else: + try: + self.master.close() + except: + pass + self.master = mavutil.mavlink_connection(self.master.address) continue # If connection reset (closed), stop polling. @@ -448,7 +455,14 @@ def mavlink_thread(): except socket.error as error: if error.errno == ECONNABORTED: errprinter('reestablishing connection after send timeout') - self.master.reset() + if hasattr(self.master, 'reset'): + self.master.reset() + else: + try: + self.master.close() + except: + pass + self.master = mavutil.mavlink_connection(self.master.address) continue # If connection reset (closed), stop polling. From 71a132397d9de2c69a235d3e21b9b7e1aa54aae6 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 28 Oct 2015 18:29:13 -0700 Subject: [PATCH 094/475] Moves home_location out of commands array. --- dronekit/lib/__init__.py | 24 +++++++++++++++++------- tests/sitl/test_waypoints.py | 6 +++--- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 9ea88d94d..9a79ef80a 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -688,6 +688,12 @@ def channel_override(self, newch): def channel_readback(self): return self.__module.rc_readback + @property + def home_location(self): + if self._waypoints is None: # We create the wpts lazily (because this will start a fetch) + self._waypoints = CommandSequence(self.__module) + return self.__module.wploader.wp(0) + @property def commands(self): """ @@ -698,7 +704,7 @@ def commands(self): :returns: A :py:class:`CommandSequence` containing the waypoints for this vehicle. """ - if(self._waypoints is None): # We create the wpts lazily (because this will start a fetch) + if self._waypoints is None: # We create the wpts lazily (because this will start a fetch) self._waypoints = CommandSequence(self.__module) return self._waypoints @@ -1051,8 +1057,12 @@ def clear(self): .. todo:: The above note should be removed when https://github.com/dronekit/dronekit-python/issues/132 fixed ''' + + # Add home point again. self.wait_valid() + home = self.__module.wploader.wp(0) self.__module.wploader.clear() + self.__module.wploader.add(home, comment='Added by DroneKit') self.__module.vehicle.wpts_dirty = True def add(self, cmd): @@ -1065,7 +1075,7 @@ def add(self, cmd): ''' self.wait_valid() self.__module.fix_targets(cmd) - self.__module.wploader.add(cmd, comment = 'Added by DroneAPI') + self.__module.wploader.add(cmd, comment='Added by DroneKit') self.__module.vehicle.wpts_dirty = True @property @@ -1075,7 +1085,7 @@ def count(self): :return: The number of waypoints in the sequence. ''' - return self.__module.wploader.count() + return self.__module.wploader.count() - 1 @property def next(self): @@ -1089,7 +1099,7 @@ def next(self, index): """ Set a new ``next`` waypoint for the vehicle. """ - self.__module.master.waypoint_set_current_send(index) + self.__module.master.waypoint_set_current_send(index - 1) def __len__(self): ''' @@ -1097,11 +1107,11 @@ def __len__(self): :return: The number of waypoints in the sequence. ''' - return self.__module.wploader.count() + return self.__module.wploader.count() - 1 def __getitem__(self, index): - return self.__module.wploader.wp(index) + return self.__module.wploader.wp(index - 1) def __setitem__(self, index, value): - self.__module.wploader.set(value, index) + self.__module.wploader.set(value, index - 1) self.__module.vehicle.wpts_dirty = True diff --git a/tests/sitl/test_waypoints.py b/tests/sitl/test_waypoints.py index 1a745e560..29a5d512a 100644 --- a/tests/sitl/test_waypoints.py +++ b/tests/sitl/test_waypoints.py @@ -13,14 +13,14 @@ def test_parameter(connpath): cmds = vehicle.commands cmds.download() cmds.wait_valid() - assert_equals(len(cmds), 1) + assert_equals(len(cmds), 0) # After clearing cmds.clear() vehicle.flush() cmds.download() cmds.wait_valid() - assert_equals(len(cmds), 1) + assert_equals(len(cmds), 0) # Upload for command in [ @@ -39,4 +39,4 @@ def test_parameter(connpath): # After upload cmds.download() cmds.wait_valid() - assert_equals(len(cmds), 9) + assert_equals(len(cmds), 8) From a8a061328b81de7d588e07cea54fe1f03d24af20 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 28 Oct 2015 18:45:57 -0700 Subject: [PATCH 095/475] Adds home checks. Statically creates commands array. --- dronekit/lib/__init__.py | 6 +----- tests/sitl/test_waypoints.py | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 9a79ef80a..9d5619307 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -560,7 +560,7 @@ def __init__(self, module): self.mavrx_callback = None self.__module = module self._parameters = Parameters(module) - self._waypoints = None + self._waypoints = CommandSequence(self.__module) self.wpts_dirty = False def close(self): @@ -690,8 +690,6 @@ def channel_readback(self): @property def home_location(self): - if self._waypoints is None: # We create the wpts lazily (because this will start a fetch) - self._waypoints = CommandSequence(self.__module) return self.__module.wploader.wp(0) @property @@ -704,8 +702,6 @@ def commands(self): :returns: A :py:class:`CommandSequence` containing the waypoints for this vehicle. """ - if self._waypoints is None: # We create the wpts lazily (because this will start a fetch) - self._waypoints = CommandSequence(self.__module) return self._waypoints @property diff --git a/tests/sitl/test_waypoints.py b/tests/sitl/test_waypoints.py index 29a5d512a..0b1b27b74 100644 --- a/tests/sitl/test_waypoints.py +++ b/tests/sitl/test_waypoints.py @@ -8,12 +8,23 @@ def test_parameter(connpath): # Connect to the Vehicle vehicle = connect(connpath, await_params=True) + cmds = vehicle.commands + + # Home should be None at first. + assert_equals(vehicle.home_location, None) + + # Wait for home position to be real and not 0, 0, 0 + # once we request it via cmds.download() + time.sleep(10) # Initial - cmds = vehicle.commands cmds.download() cmds.wait_valid() assert_equals(len(cmds), 0) + assert_not_equals(vehicle.home_location, None) + + # Save home for comparison. + home = vehicle.home_location # After clearing cmds.clear() @@ -40,3 +51,8 @@ def test_parameter(connpath): cmds.download() cmds.wait_valid() assert_equals(len(cmds), 8) + + # Home should be preserved + assert_equals(home.x, vehicle.home_location.x) + assert_equals(home.y, vehicle.home_location.y) + assert_equals(home.z, vehicle.home_location.z) From 44b1c80ee4bdfefbeec6aab7898b0548503b8100 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 29 Oct 2015 14:21:58 -0700 Subject: [PATCH 096/475] Allows clear() on empty commands array. Fixes len < 0 bug. --- dronekit/lib/__init__.py | 7 ++++--- tests/sitl/test_waypoints.py | 11 +++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 9d5619307..b99b7afd4 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1058,7 +1058,8 @@ def clear(self): self.wait_valid() home = self.__module.wploader.wp(0) self.__module.wploader.clear() - self.__module.wploader.add(home, comment='Added by DroneKit') + if home: + self.__module.wploader.add(home, comment='Added by DroneKit') self.__module.vehicle.wpts_dirty = True def add(self, cmd): @@ -1081,7 +1082,7 @@ def count(self): :return: The number of waypoints in the sequence. ''' - return self.__module.wploader.count() - 1 + return max(self.__module.wploader.count() - 1, 0) @property def next(self): @@ -1103,7 +1104,7 @@ def __len__(self): :return: The number of waypoints in the sequence. ''' - return self.__module.wploader.count() - 1 + return max(self.__module.wploader.count() - 1, 0) def __getitem__(self, index): return self.__module.wploader.wp(index - 1) diff --git a/tests/sitl/test_waypoints.py b/tests/sitl/test_waypoints.py index 0b1b27b74..635bdafa9 100644 --- a/tests/sitl/test_waypoints.py +++ b/tests/sitl/test_waypoints.py @@ -4,6 +4,17 @@ from dronekit.tools import with_sitl from nose.tools import assert_not_equals, assert_equals +@with_sitl +def test_empty_clear(connpath): + # Connect to the Vehicle + vehicle = connect(connpath) + + # Calling clear() on an empty object should not crash. + vehicle.commands.clear() + vehicle.flush() + + assert_equals(len(vehicle.commands), 0) + @with_sitl def test_parameter(connpath): # Connect to the Vehicle From a1d425cf32e2687f66e87df7d1511803224a4697 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 29 Oct 2015 14:31:03 -0700 Subject: [PATCH 097/475] Corrects home_location to be LocationGlobal. --- dronekit/lib/__init__.py | 4 +++- tests/sitl/test_waypoints.py | 8 +++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index b99b7afd4..8e196b971 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -690,7 +690,9 @@ def channel_readback(self): @property def home_location(self): - return self.__module.wploader.wp(0) + loc = self.__module.wploader.wp(0) + if loc: + return LocationGlobal(loc.x, loc.y, loc.z, is_relative=False) @property def commands(self): diff --git a/tests/sitl/test_waypoints.py b/tests/sitl/test_waypoints.py index 635bdafa9..0c3d5baef 100644 --- a/tests/sitl/test_waypoints.py +++ b/tests/sitl/test_waypoints.py @@ -6,7 +6,6 @@ @with_sitl def test_empty_clear(connpath): - # Connect to the Vehicle vehicle = connect(connpath) # Calling clear() on an empty object should not crash. @@ -17,7 +16,6 @@ def test_empty_clear(connpath): @with_sitl def test_parameter(connpath): - # Connect to the Vehicle vehicle = connect(connpath, await_params=True) cmds = vehicle.commands @@ -64,6 +62,6 @@ def test_parameter(connpath): assert_equals(len(cmds), 8) # Home should be preserved - assert_equals(home.x, vehicle.home_location.x) - assert_equals(home.y, vehicle.home_location.y) - assert_equals(home.z, vehicle.home_location.z) + assert_equals(home.lat, vehicle.home_location.lat) + assert_equals(home.lon, vehicle.home_location.lon) + assert_equals(home.alt, vehicle.home_location.alt) From 18b092f9d371144a62fedbf6bb7e995c6ba1772d Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 29 Oct 2015 14:33:10 -0700 Subject: [PATCH 098/475] Implements slicing and iteration for commands. --- dronekit/lib/__init__.py | 10 +++++++++- tests/sitl/test_waypoints.py | 12 ++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 8e196b971..c59fa3f80 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1109,7 +1109,15 @@ def __len__(self): return max(self.__module.wploader.count() - 1, 0) def __getitem__(self, index): - return self.__module.wploader.wp(index - 1) + if isinstance(index, slice): + return [self[ii] for ii in xrange(*index.indices(len(self)))] + elif isinstance(index, int): + item = self.__module.wploader.wp(index - 1) + if not item: + raise IndexError('Index %s out of range.' % index) + return item + else: + raise TypeError('Invalid argument type.') def __setitem__(self, index, value): self.__module.wploader.set(value, index - 1) diff --git a/tests/sitl/test_waypoints.py b/tests/sitl/test_waypoints.py index 0c3d5baef..8e826675f 100644 --- a/tests/sitl/test_waypoints.py +++ b/tests/sitl/test_waypoints.py @@ -61,6 +61,18 @@ def test_parameter(connpath): cmds.wait_valid() assert_equals(len(cmds), 8) + # Test iteration. + out = [] + for cmd in vehicle.commands: + assert_not_equals(cmd, None) + + # Test slicing + count = 0 + for cmd in vehicle.commands[2:5]: + assert_not_equals(cmd, None) + count += 1 + assert_equals(count, 3) + # Home should be preserved assert_equals(home.lat, vehicle.home_location.lat) assert_equals(home.lon, vehicle.home_location.lon) From c1f497aad7ddba98fd2a67a00a415d35d2f620f6 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 30 Oct 2015 15:24:51 -0700 Subject: [PATCH 099/475] Fixes indexing logic. --- dronekit/lib/__init__.py | 6 +++--- tests/sitl/test_waypoints.py | 9 ++++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index c59fa3f80..0b0ac8202 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1098,7 +1098,7 @@ def next(self, index): """ Set a new ``next`` waypoint for the vehicle. """ - self.__module.master.waypoint_set_current_send(index - 1) + self.__module.master.waypoint_set_current_send(index + 1) def __len__(self): ''' @@ -1112,7 +1112,7 @@ def __getitem__(self, index): if isinstance(index, slice): return [self[ii] for ii in xrange(*index.indices(len(self)))] elif isinstance(index, int): - item = self.__module.wploader.wp(index - 1) + item = self.__module.wploader.wp(index + 1) if not item: raise IndexError('Index %s out of range.' % index) return item @@ -1120,5 +1120,5 @@ def __getitem__(self, index): raise TypeError('Invalid argument type.') def __setitem__(self, index, value): - self.__module.wploader.set(value, index - 1) + self.__module.wploader.set(value, index + 1) self.__module.vehicle.wpts_dirty = True diff --git a/tests/sitl/test_waypoints.py b/tests/sitl/test_waypoints.py index 8e826675f..39b2e6737 100644 --- a/tests/sitl/test_waypoints.py +++ b/tests/sitl/test_waypoints.py @@ -62,16 +62,19 @@ def test_parameter(connpath): assert_equals(len(cmds), 8) # Test iteration. - out = [] + count = 0 for cmd in vehicle.commands: assert_not_equals(cmd, None) + count += 1 + assert_equals(count, 8) # Test slicing - count = 0 + count = 3 for cmd in vehicle.commands[2:5]: assert_not_equals(cmd, None) + assert_equals(cmd.seq, count) count += 1 - assert_equals(count, 3) + assert_equals(count, 6) # Home should be preserved assert_equals(home.lat, vehicle.home_location.lat) From e4201bb9aff6626b8d43440fc2689927f21224b5 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 30 Oct 2015 15:29:44 -0700 Subject: [PATCH 100/475] Adds upload() command. --- dronekit/lib/__init__.py | 11 +++++++++++ tests/sitl/test_waypoints.py | 29 ++++++++++++++--------------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 0b0ac8202..20d54ee18 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1077,6 +1077,17 @@ def add(self, cmd): self.__module.wploader.add(cmd, comment='Added by DroneKit') self.__module.vehicle.wpts_dirty = True + def upload(self): + """ + Call ``upload()`` after :py:func:`adding ` or :py:func:`clearing ` mission commands. + + After the return from ``upload()`` any writes are guaranteed to have completed (or thrown an + exception) and future reads will see their effects. + """ + if self.__module.vehicle.wpts_dirty: + self.__module.send_all_waypoints() + self.__module.vehicle.wpts_dirty = False + @property def count(self): ''' diff --git a/tests/sitl/test_waypoints.py b/tests/sitl/test_waypoints.py index 39b2e6737..06dbd0565 100644 --- a/tests/sitl/test_waypoints.py +++ b/tests/sitl/test_waypoints.py @@ -10,14 +10,13 @@ def test_empty_clear(connpath): # Calling clear() on an empty object should not crash. vehicle.commands.clear() - vehicle.flush() + vehicle.commands.upload() assert_equals(len(vehicle.commands), 0) @with_sitl def test_parameter(connpath): vehicle = connect(connpath, await_params=True) - cmds = vehicle.commands # Home should be None at first. assert_equals(vehicle.home_location, None) @@ -27,20 +26,20 @@ def test_parameter(connpath): time.sleep(10) # Initial - cmds.download() - cmds.wait_valid() - assert_equals(len(cmds), 0) + vehicle.commands.download() + vehicle.commands.wait_valid() + assert_equals(len(vehicle.commands), 0) assert_not_equals(vehicle.home_location, None) # Save home for comparison. home = vehicle.home_location # After clearing - cmds.clear() - vehicle.flush() - cmds.download() - cmds.wait_valid() - assert_equals(len(cmds), 0) + vehicle.commands.clear() + vehicle.commands.upload() + vehicle.commands.download() + vehicle.commands.wait_valid() + assert_equals(len(vehicle.commands), 0) # Upload for command in [ @@ -53,13 +52,13 @@ def test_parameter(connpath): Command(0, 0, 0, 3, 115, 0, 1, 2.0, 22.0, 1.0, 3.0, 0.0, 0.0, 0.0), Command(0, 0, 0, 3, 16, 0, 1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), ]: - cmds.add(command) - vehicle.flush() + vehicle.commands.add(command) + vehicle.commands.upload() # After upload - cmds.download() - cmds.wait_valid() - assert_equals(len(cmds), 8) + vehicle.commands.download() + vehicle.commands.wait_valid() + assert_equals(len(vehicle.commands), 8) # Test iteration. count = 0 From e4b323428e9db49bf65a08ea9c29eeb8c69e482b Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 2 Nov 2015 16:17:38 +1100 Subject: [PATCH 101/475] Fix up mission examples now that home_location is not the first index. Update home_location in API Ref too --- docs/automodule.rst | 3 +- docs/examples/mission_basic.rst | 147 ++++++++---------- .../mission_basic_example_copter_path.png | Bin 0 -> 32804 bytes docs/examples/mission_import_export.rst | 111 +++++-------- docs/guide/auto_mode.rst | 105 +++++-------- docs/guide/migrating.rst | 14 ++ dronekit/lib/__init__.py | 25 +++ examples/mission_basic/mission_basic.py | 51 +++--- .../mission_import_export.py | 69 +++++--- examples/mission_import_export/mpmission.txt | 15 +- 10 files changed, 255 insertions(+), 285 deletions(-) create mode 100644 docs/examples/mission_basic_example_copter_path.png diff --git a/docs/automodule.rst b/docs/automodule.rst index 5a43bb22f..f79944102 100644 --- a/docs/automodule.rst +++ b/docs/automodule.rst @@ -8,7 +8,7 @@ DroneKit-Python API Reference .. automodule:: dronekit.lib :members: :inherited-members: - :exclude-members: Mission, get_mission, ConnectionInfo, web_connect, AuthInfo, delete, notify_observers, remove_all_observers, local_connect, APIConnection + :exclude-members: Mission, get_mission, ConnectionInfo, web_connect, AuthInfo, delete, notify_observers, remove_all_observers, local_connect, APIConnection, flush @@ -19,5 +19,4 @@ DroneKit-Python API Reference - .. todolist:: \ No newline at end of file diff --git a/docs/examples/mission_basic.rst b/docs/examples/mission_basic.rst index 874d11c49..8c3794ef2 100644 --- a/docs/examples/mission_basic.rst +++ b/docs/examples/mission_basic.rst @@ -12,13 +12,11 @@ command. The guide topic :ref:`auto_mode_vehicle_control` provides more detailed explanation of how the API should be used. -.. warning:: +.. figure:: mission_basic_example_copter_path.png + :width: 50 % + :alt: Basic Mission Path - At time of writing this example fails with an exception in DKYP2: `#355 DKPY2 Can't clear waypoints `_. - -.. todo:: - - Check if `#355 DKPY2 Can't clear waypoints `_ is fixed and re-review example. + Basic Mission Example: Flight path Running the example @@ -47,8 +45,8 @@ In summary, after cloning the repository: .. note:: - The command parameter above is the default, and may be omitted. This - connects to SITL on udp port 127.0.0.1:14550. + The ``--connect`` parameter above specifies the default value, and may be omitted. + This connects to SITL on udp port 127.0.0.1:14550. .. tip:: @@ -64,69 +62,66 @@ On the command prompt you should see (something like): Connecting to vehicle on: 127.0.0.1:14550 >>> APM:Copter V3.4-dev (e0810c2e) >>> Frame: QUAD - Clear the current mission - - Requesting 0 waypoints t=Wed Jul 29 21:27:58 2015 now=Wed Jul 29 21:27:58 2015 Create a new mission - Got MAVLink msg: MISSION_ACK {target_system : 255, target_component : 0, type : 0} - Sent waypoint 0 : MISSION_ITEM {target_system : 1, target_component : 0, seq : 0, frame : 0, command : 16, current : 0, autocontinue : 1, param1 : 0.0, param2 : 0.0, param3 : 0.0, param4 : 0.0, x : -35.3632621765, y : 149.165237427, z : 584.0} - Sent waypoint 1 : MISSION_ITEM {target_system : 1, target_component : 0, seq : 1, frame : 3, command : 22, current : 0, autocontinue : 0, param1 : 0, param2 : 0, param3 : 0, param4 : 0, x : 0, y : 0, z : 10} - Sent waypoint 2 : MISSION_ITEM {target_system : 1, target_component : 0, seq : 2, frame : 3, command : 16, current : 0, autocontinue : 0, param1 : 0, param2 : 0, param3 : 0, param4 : 0, x : -35.3628118424, y : 149.164679124, z : 11} - Sent waypoint 3 : MISSION_ITEM {target_system : 1, target_component : 0, seq : 3, frame : 3, command : 16, current : 0, autocontinue : 0, param1 : 0, param2 : 0, param3 : 0, param4 : 0, x : -35.3628118424, y : 149.165780676, z : 12} - Sent waypoint 4 : MISSION_ITEM {target_system : 1, target_component : 0, seq : 4, frame : 3, command : 16, current : 0, autocontinue : 0, param1 : 0, param2 : 0, param3 : 0, param4 : 0, x : -35.3637101576, y : 149.165780676, z : 13} - Sent waypoint 5 : MISSION_ITEM {target_system : 1, target_component : 0, seq : 5, frame : 3, command : 16, current : 0, autocontinue : 0, param1 : 0, param2 : 0, param3 : 0, param4 : 0, x : -35.3637101576, y : 149.164679124, z : 14} - Sent all 6 waypoints - Got MAVLink msg: MISSION_ACK {target_system : 255, target_component : 0, type : 0} - APM: flight plan received + Clear any existing commands + Define/add new commands. + Upload new commands to vehicle Basic pre-arm checks + MODE: STABILIZE Arming motors Waiting for arming... - Got MAVLink msg: COMMAND_ACK {command : 11, result : 0} + >>> flight plan received Waiting for arming... - APM: ARMING MOTORS - APM: GROUND START Waiting for arming... - GUIDED> Mode GUIDED - APM: Initialising APM... - Got MAVLink msg: COMMAND_ACK {command : 400, result : 0} + >>> ARMING MOTORS + >>> GROUND START Waiting for arming... - ARMED + Waiting for arming... + >>> Initialising APM... Taking off! Altitude: 0.0 - Got MAVLink msg: COMMAND_ACK {command : 22, result : 0} - GPS lock at 0 meters - Altitude: 0.10000000149 + Altitude: 0.170000001788 + Altitude: 1.37000000477 ... - Altitude: 8.84000015259 - Altitude: 9.60999965668 + Altitude: 8.98999977112 + Altitude: 9.64000034332 Reached target altitude Starting mission - Got MAVLink msg: COMMAND_ACK {command : 11, result : 0} - waypoint 1 - waypoint 2 - AUTO> Mode AUTO - Distance to waypoint (2): 79.3138466142 - Distance to waypoint (2): 79.1869592549 - Distance to waypoint (2): 77.8436803794 + Distance to waypoint (0): None + Distance to waypoint (1): 78.8589586333 + Distance to waypoint (1): 78.4539918222 + ... + Distance to waypoint (1): 21.1854880899 + Distance to waypoint (1): 15.9962142785 + >>> Reached Command #1 + Distance to waypoint (2): 114.244008966 + Distance to waypoint (2): 117.552371221 + Distance to waypoint (2): 120.961820592 + ... + Distance to waypoint (2): 25.2782487833 + Distance to waypoint (2): 19.3676312264 + >>> Reached Command #2 + Distance to waypoint (3): 101.094964838 + Skipping to Waypoint 5 when reach waypoint 3 + Distance to waypoint (3): 100.297254801 + Skipping to Waypoint 5 when reach waypoint 3 ... - Distance to waypoint (2): 20.7677087176 - Distance to waypoint (2): 15.4592692026 - APM: Reached Command #2 - waypoint 3 - Distance to waypoint (3): 115.328425048 - Skipping to Waypoint 4 when reach waypoint 3 - waypoint 4 - Distance to waypoint (4): 152.376018911 - Distance to waypoint (4): 154.882233097 + Distance to waypoint (3): 19.3298648648 + Skipping to Waypoint 5 when reach waypoint 3 + Distance to waypoint (3): 14.5179746603 + Skipping to Waypoint 5 when reach waypoint 3 + >>> Reached Command #3 + Distance to waypoint (4): 123.867292399 + Distance to waypoint (4): 123.019536579 + Distance to waypoint (4): 121.278259418 ... - Distance to waypoint (4): 20.4052797291 - Distance to waypoint (4): 15.0592597507 - APM: Reached Command #4 - waypoint 5 - Distance to waypoint (5): 114.450267446 + Distance to waypoint (4): 27.7386666676 + Distance to waypoint (4): 20.3805334778 + >>> Reached Command #4 + Distance to waypoint (5): 14.5141106814 Exit 'standard' mission when start heading to final waypoint (5) Return to launch - APIThread-0 exiting... + Close vehicle object @@ -136,9 +131,11 @@ How does it work? The :ref:`source code ` is relatively self-documenting, and most of its main operations are explained in the guide topic :ref:`auto_mode_vehicle_control` . -In overview, the example first calls ``clear_mission()`` to clear the current mission and then creates and -uploads a new mission using ``adds_square_mission(vehicle.location.global_frame,50)``. This function defines a mission with a takeoff -command and four waypoints arranged in a square around the central position. +In overview, the example calls ``adds_square_mission(vehicle.location.global_frame,50)`` to first +clear the current mission and then define a new mission with a takeoff command and four waypoints arranged +in a square around the central position (two waypoints are added in the last position - +we use :py:func:`next ` to determine when we've reached the final point). +The clear command and new mission items are then uploaded to the vehicle. After taking off (in guided mode using the ``takeoff()`` function) the example starts the mission by setting the mode to AUTO: @@ -160,18 +157,19 @@ We also show how to move to a specified command using .. code:: python while True: - nextwaypoint =vehicle.commands.next - if nextwaypoint > 1: - print 'Distance to waypoint (%s): %s' % (nextwaypoint, distance_to_current_waypoint()) - if nextwaypoint ==3: #Skip to next waypoint - print 'Skipping to Waypoint 4 when reach waypoint 3' - vehicle.commands.next=4 - if nextwaypoint ==5: #Skip to next waypoint + nextwaypoint=vehicle.commands.next + print 'Distance to waypoint (%s): %s' % (nextwaypoint, distance_to_current_waypoint()) + + if nextwaypoint==3: #Skip to next waypoint + print 'Skipping to Waypoint 5 when reach waypoint 3' + vehicle.commands.next=5 + vehicle.commands.upload() + if nextwaypoint==5: #Dummy waypoint - as soon as we reach waypoint 4 this is true and we exit. print "Exit 'standard' mission when start heading to final waypoint (5)" break; time.sleep(1) -When the vehicle starts the 5th command the loop breaks and the mode is set to RTL (return to launch). +When the vehicle starts the 5th command (a dummy waypoint) the loop breaks and the mode is set to RTL (return to launch). .. _example_mission_basic_known_issues: @@ -179,21 +177,10 @@ When the vehicle starts the 5th command the loop breaks and the mode is set to R Known issues ============ -This example fails in DroneKit 2.0.0b6 and earlier releases (see `#355 DKPY2 Can't clear waypoints `_ to see if it has been fixed in the current release). - - -.. todo:: - - This is blocked by https://github.com/dronekit/dronekit-python/issues/355 (vehicle.commands.clear not working). - The code output in "running the example needs to be updated once this runs cleanly. - The above text for the error needs to be replaced with original text: - - > "This example works around the :ref:`known issues in the API `. - > Provided that the vehicle is connected and able to arm, it should run through to completion." - - Need to check all that clearing is still strictly necessary in DKPY2 which handles race conditions more gracefully. - Add image of waypoints /flight for top of page. +This example has the following issues: +* :py:func:`next ` does not appear to be writable, so the example does not skip steps as documented. + This is tracked as `#390 <#https://github.com/dronekit/dronekit-python/issues/390>`_. .. _example_mission_basic_source_code: diff --git a/docs/examples/mission_basic_example_copter_path.png b/docs/examples/mission_basic_example_copter_path.png new file mode 100644 index 0000000000000000000000000000000000000000..d858dd02859297d902a62bfab77567ad9e719e54 GIT binary patch literal 32804 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 KA$ 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 XFnjxXb*%&`_. -.. warning:: - - At time of writing this example fails with an exception in DKYP2: `#355 DKPY2 Can't clear waypoints `_. - -.. todo:: - - Check if `#355 DKPY2 Can't clear waypoints `_ is fixed and re-review example. - The commands are first imported from a file into a list and then uploaded to the vehicle. -Then the current mission is downloaded from the vehicle and put into a list, and finally -saved into (another file). +Then the current mission is downloaded from the vehicle and put into a list, which is then +saved into (another file). Finally, we print out both the original and new files +for comparison The example does not show how missions can be modified, but once the mission is in a list, changing the order and content of commands is straightforward. @@ -32,9 +25,6 @@ Running the example The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle and DroneKit have been set up as described in :ref:`get-started`). -If you're using a simulated vehicle, remember to :ref:`disable arming checks ` so -that the example can run. - In summary, after cloning the repository: #. Navigate to the example folder as shown: @@ -53,10 +43,9 @@ In summary, after cloning the repository: .. note:: - The command parameter above is the default, and may be omitted. This - connects to SITL on udp port 127.0.0.1:14550. + The ``--connect`` parameter above specifies the default value, and may be omitted. + This connects to SITL on udp port 127.0.0.1:14550. - On the command prompt you should see (something like): @@ -64,51 +53,42 @@ On the command prompt you should see (something like): .. code:: bash Connecting to vehicle on: 127.0.0.1:14550 - >>> APM:Copter V3.4-dev (e0810c2e) + >>> APM:Copter V3.3 (d6053245) >>> Frame: QUAD - Link timeout, no heartbeat in last 5 seconds - Upload mission from a file: mpmission.txt Reading mission from file: mpmission.txt - STABILIZE> Import line: 0 1 0 16 0 0 0 0 -35.360500 149.172363 747.000000 1 - - Import line: 1 0 3 22 0.000000 0.000000 0.000000 0.000000 -35.359831 149.166334 100.000000 1 - - - Import line: 2 0 3 16 0.000000 0.000000 0.000000 0.000000 -35.363489 149.167213 100.000000 1 - - Import line: 3 0 3 16 0.000000 0.000000 0.000000 0.000000 -35.355491 149.169595 100.000000 1 - - Import line: 4 0 3 16 0.000000 0.000000 0.000000 0.000000 -35.355071 149.175839 100.000000 1 - - Import line: 5 0 3 113 0.000000 0.000000 0.000000 0.000000 -35.362666 149.178715 22222.000000 1 - Import line: 6 0 3 115 2.000000 22.000000 1.000000 3.000000 0.000000 0.000000 0.000000 1 - - Import line: 7 0 3 16 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1 - - Clear mission - Requesting 9 waypoints t=Wed Jul 29 20:12:17 2015 now=Wed Jul 29 20:12:17 2015 - ClearCount: 0 - Got MAVLink msg: MISSION_ACK {target_system : 255, target_component : 0, type : 0} - Requesting 0 waypoints t=Wed Jul 29 20:12:17 2015 now=Wed Jul 29 20:12:17 2015 - Got MAVLink msg: MISSION_ACK {target_system : 255, target_component : 0, type : 0} - Sent waypoint 0 : MISSION_ITEM {target_system : 1, target_component : 0, seq : 0, frame : 0, command : 16, current : 0, autocontinue : 1, param1 : 0.0, param2 : 0.0, param3 : 0.0, param4 : 0.0, x : -35.3632621765, y : 149.165237427, z : 584.0} - Sent waypoint 1 : MISSION_ITEM {target_system : 1, target_component : 0, seq : 1, frame : 0, command : 16, current : 1, autocontinue : 1, param1 : 0.0, param2 : 0.0, param3 : 0.0, param4 : 0.0, x : -35.3605, y : 149.172363, z : 747.0} - Sent waypoint 2 : MISSION_ITEM {target_system : 1, target_component : 0, seq : 2, frame : 3, command : 22, current : 0, autocontinue : 1, param1 : 0.0, param2 : 0.0, param3 : 0.0, param4 : 0.0, x : -35.359831, y : 149.166334, z : 100.0} - Sent waypoint 3 : MISSION_ITEM {target_system : 1, target_component : 0, seq : 3, frame : 3, command : 16, current : 0, autocontinue : 1, param1 : 0.0, param2 : 0.0, param3 : 0.0, param4 : 0.0, x : -35.363489, y : 149.167213, z : 100.0} - Sent waypoint 4 : MISSION_ITEM {target_system : 1, target_component : 0, seq : 4, frame : 3, command : 16, current : 0, autocontinue : 1, param1 : 0.0, param2 : 0.0, param3 : 0.0, param4 : 0.0, x : -35.355491, y : 149.169595, z : 100.0} - Sent waypoint 5 : MISSION_ITEM {target_system : 1, target_component : 0, seq : 5, frame : 3, command : 16, current : 0, autocontinue : 1, param1 : 0.0, param2 : 0.0, param3 : 0.0, param4 : 0.0, x : -35.355071, y : 149.175839, z : 100.0} - Sent waypoint 6 : MISSION_ITEM {target_system : 1, target_component : 0, seq : 6, frame : 3, command : 113, current : 0, autocontinue : 1, param1 : 0.0, param2 : 0.0, param3 : 0.0, param4 : 0.0, x : -35.362666, y : 149.178715, z : 22222.0} - Sent waypoint 7 : MISSION_ITEM {target_system : 1, target_component : 0, seq : 7, frame : 3, command : 115, current : 0, autocontinue : 1, param1 : 2.0, param2 : 22.0, param3 : 1.0, param4 : 3.0, x : 0.0, y : 0.0, z : 0.0} - Sent waypoint 8 : MISSION_ITEM {target_system : 1, target_component : 0, seq : 8, frame : 3, command : 16, current : 0, autocontinue : 1, param1 : 0.0, param2 : 0.0, param3 : 0.0, param4 : 0.0, x : 0.0,y : 0.0, z : 0.0} - Sent all 9 waypoints - Got MAVLink msg: MISSION_ACK {target_system : 255, target_component : 0, type : 0} - APM: flight plan received + Upload mission from a file: mpmission.txt + Clear mission + Upload mission Save mission from Vehicle to file: exportedmission.txt - Requesting 9 waypoints t=Wed Jul 29 20:12:18 2015 now=Wed Jul 29 20:12:18 2015 - APIThread-1 exiting... + Download mission from vehicle + >>> flight plan received + Write mission to file + Close vehicle object + + Show original and uploaded/downloaded files: + + Mission file: mpmission.txt + QGC WPL 110 + 0 1 0 16 0 0 0 0 -35.363262 149.165237 584.000000 1 + 1 0 0 22 0.000000 0.000000 0.000000 0.000000 -35.361988 149.163753 100.000000 1 + 2 0 0 16 0.000000 0.000000 0.000000 0.000000 -35.361992 149.163593 100.000000 1 + 3 0 0 16 0.000000 0.000000 0.000000 0.000000 -35.363812 149.163609 100.000000 1 + 4 0 0 16 0.000000 0.000000 0.000000 0.000000 -35.363768 149.166055 100.000000 1 + 5 0 0 16 0.000000 0.000000 0.000000 0.000000 -35.361835 149.166012 100.000000 1 + 6 0 0 16 0.000000 0.000000 0.000000 0.000000 -35.362150 149.165046 100.000000 1 + + Mission file: exportedmission.txt + QGC WPL 110 + 0 1 0 16 0 0 0 0 0.0 0.0 0.0 1 + 1 0 0 22 0.0 0.0 0.0 0.0 -35.3619880676 149.163757324 100.0 1 + 2 0 0 16 0.0 0.0 0.0 0.0 -35.3619918823 149.163589478 100.0 1 + 3 0 0 16 0.0 0.0 0.0 0.0 -35.3638114929 149.163604736 100.0 1 + 4 0 0 16 0.0 0.0 0.0 0.0 -35.3637695312 149.166061401 100.0 1 + 5 0 0 16 0.0 0.0 0.0 0.0 -35.3618354797 149.166015625 100.0 1 + 6 0 0 16 0.0 0.0 0.0 0.0 -35.3621482849 149.165039062 100.0 1 @@ -125,26 +105,7 @@ More information about the functions can be found in the guide at Known issues ============ -* This example fails in DroneKit 2.0.0b6 and earlier - (see `#355 DKPY2 Can't clear waypoints `_ to see if it has been fixed). -* A ``time.sleep(1)`` has been placed between uploading the mission to the vehicle (from the file) and downloading the mission. - This is to avoid the race condition where the mission being downloaded has not yet successfully uploaded to the vehicle. - This race condition (probably) shouldn't exist because the mission is flushed to the Vehicle - - see `Race condition when updating and fetching commands `_ - - - -.. todo:: - - This is blocked by https://github.com/dronekit/dronekit-python/issues/355 (vehicle.commands.clear not working). - The code output in "running the example"" needs to be updated once this runs cleanly. - The above text for the error needs to be replaced with original text - - > "This example works around known issues in the API:." - - Need to check all that clearing is still strictly necessary in DKPY2 which handles race conditions more gracefully. - - +There are no known issues with this example. diff --git a/docs/guide/auto_mode.rst b/docs/guide/auto_mode.rst index 6cbeb4426..f5dbe7fee 100644 --- a/docs/guide/auto_mode.rst +++ b/docs/guide/auto_mode.rst @@ -80,13 +80,9 @@ use :py:func:`wait_valid() ` to block y .. note:: - The commands downloaded from the vehicle will include a waypoint for the :ref:`home location ` in the first position (0 index). - This waypoint is not editable - it cannot be removed or modified. + In DroneKit-Python 2 :py:attr:`Vehicle.commands ` contains just the editable waypoints (in version 1.x, the + commands included the non-editable home location as the first item). -.. todo:: - - The information about home location will change with - `#207 WIP:Adds separate .home_location from .commands array `_. .. _auto_mode_clear_mission: @@ -95,33 +91,25 @@ Clearing current mission ======================== To clear a mission you call :py:func:`clear() ` and then -:py:func:`flush() ` (to upload the changes to the vehicle): +:py:func:`Vehicle.commands.upload() ` (to upload the changes to the vehicle): .. code:: python # Connect to the Vehicle (in this case a simulated vehicle at 127.0.0.1:14550) vehicle = connect('127.0.0.1:14550', await_params=True) - # Get commands from Vehicle object. + # Get commands object from Vehicle. cmds = vehicle.commands - # Clear Vehicle.commands and flush. + # Call clear() on Vehicle.commands and upload the command to the vehicle. cmds.clear() - vehicle.flush() - - # Reset the Vehicle.commands from the vehicle. - cmds.download() - cmds.wait_valid() - -.. warning:: + cmds.upload() - You must re-download the mission from the vehicle after clearing (as shown above) or the first command you add - will be lost when you upload the new mission. +.. note:: - This happens because :py:attr:`Vehicle.commands ` removes the :ref:`home location ` - (see `#132 `_). Downloading adds it back again. + If a mission that is underway is cleared, the mission will continue to the next waypoint. If you don't add a new command + before the waypoint is reached then the vehicle mode will change to RTL (return to launch) mode. -If the current command completes before you add a new mission, then the vehicle mode will change to RTL (return to launch). .. _auto_mode_adding_command: @@ -131,7 +119,7 @@ Creating/adding mission commands After :ref:`downloading ` or :ref:`clearing ` a mission new commands can be added and uploaded to the vehicle. Commands are added to the mission using :py:func:`add() ` -and are sent to the vehicle (either individually or in batches) using :py:func:`flush() `. +and are sent to the vehicle (either individually or in batches) using :py:func:`upload() `. Each command is packaged in a :py:class:`Command ` object (see that class for the order/meaning of the parameters). The supported commands for each vehicle are :ref:`linked above `. @@ -152,7 +140,7 @@ The supported commands for each vehicle are :ref:`linked above ` after :ref:`downloading a mission ` it is not possible to directly modify and upload existing commands in ``Vehicle.commands`` (you can modify the commands but -changes do not propagate to the vehicle). +changes do not propagate to the vehicle). + +.. todo:: test above statement. Might not be true in DKPY2. Also check if we can flush items in a cycle. Instead you copy all the commands into another container (e.g. a list), modify them as needed, then clear ``Vehicle.commands`` and upload the list as a new mission: @@ -180,27 +170,24 @@ modify them as needed, then clear ``Vehicle.commands`` and upload the list as a # Save the vehicle commands to a list missionlist=[] - for cmd in cmds[1:]: #skip first item as it is home waypoint. + for cmd in cmds: missionlist.append(cmd) # Modify the mission as needed. For example, here we change the # first waypoint into a MAV_CMD_NAV_TAKEOFF command. missionlist[0].command=mavutil.mavlink.MAV_CMD_NAV_TAKEOFF - # Clear the current mission + # Clear the current mission (command is sent when we call upload()) cmds.clear() - vehicle.flush() - cmds.download() - cmds.wait_valid() #Write the modified mission and flush to the vehicle for cmd in missionlist: cmds.add(cmd) - vehicle.flush() + cmds.upload() The changes are not guaranteed to be complete until -:py:func:`flush() ` is called on the parent ``Vehicle`` object. +:py:func:`upload() ` is called on the parent ``Vehicle.commands`` object. .. _auto_mode_monitoring_controlling: @@ -208,7 +195,7 @@ The changes are not guaranteed to be complete until Running and monitoring missions =============================== -To start a mission change the mode to AUTO: +To start a mission, change the mode to AUTO: .. code:: python @@ -242,8 +229,8 @@ to get the current command number. You can also change the current command by se vehicle.commands.next=4 print "Current Waypoint: %s" % vehicle.commands.next -There is no need to ``flush()`` changes to ``next`` to the vehicle (and as with other attributes, if you fetch a value, it is updated -from the vehicle). +There is no need to ``upload()`` changes to send an update to the ``next`` attribute to the vehicle +(and as with other attributes, if you fetch a value, it is updated from the vehicle). .. _auto_mode_handle_mission_end: @@ -260,7 +247,7 @@ to perform some other operation) then you can either: * Add a dummy mission command and poll :py:func:`Vehicle.commands.next ` for the transition to the final command, or -* Compare the current position to the position in the last command. +* Compare the current position to the target position in the final waypoint. @@ -287,24 +274,22 @@ Adding mission commands is discussed :ref:`here in the guide ` objects. @@ -331,7 +316,6 @@ The commands are added to a list which is returned by the function. if not line.startswith('QGC WPL 110'): raise Exception('File is not supported WP version') else: - print ' Import line: %s' % line linearray=line.split('\t') ln_index=int(linearray[0]) ln_currentwp=int(linearray[1]) @@ -410,9 +394,9 @@ Get distance to waypoint It returns None for the first waypoint (Home location). """ nextwaypoint=vehicle.commands.next - if nextwaypoint==1: + if nextwaypoint ==0: return None - missionitem=vehicle.commands[nextwaypoint] + missionitem=vehicle.commands[nextwaypoint-1] #commands are zero indexed lat=missionitem.x lon=missionitem.y alt=missionitem.z @@ -425,8 +409,6 @@ and uses it to index the commands to get the latitude, longitude and altitude of (see :ref:`guided_mode_copter_useful_conversion_functions`) is then used to calculate and return the (horizontal) distance from the current vehicle location. -The implementation ignores the first waypoint (which will be the "home location"). - .. tip:: This implementation is very basic. It assumes that the next command number is for a valid NAV command (it might not be) @@ -449,9 +431,4 @@ Known Issues AUTO Mode/mission control has the following known issues (at time of writing): -* `#230 vehicle.commands must be reset after clearing `_ -* `#132 Vehicle.commands is throwing away the first command sent `_ -* `#252 Expose home location as separate from .commands array `_ -* `#207 WIP:Adds separate .home_location from .commands array `_ -* `#105 Implement Vehicle.waypoint_home `_ -* `#227 Race condition when updating and fetching commands `_ \ No newline at end of file +* `#390 Vehicle.commands.next is not writeable <#https://github.com/dronekit/dronekit-python/issues/390>`_. \ No newline at end of file diff --git a/docs/guide/migrating.rst b/docs/guide/migrating.rst index cd3724ccd..14dbfd621 100644 --- a/docs/guide/migrating.rst +++ b/docs/guide/migrating.rst @@ -161,3 +161,17 @@ Instead, use normal Python methods for getting file system information: full_directory_path_of_current_script = os.path.dirname(os.path.abspath(__file__)) +Home location +------------- + +DroneKit-Python 1.x code retrieved the home location from the first element in :py:attr:`Vehicle.commands `. +This code must be replaced with the DroneKit-Python 2.x :py:attr:`Vehicle.home_location ` attribute. + +.. tip:: + + Even though the home location is no longer returned as the first waypoint in :py:attr:`Vehicle.commands `, + you will still need to download the commands in order to populate the value of + :py:attr:`Vehicle.home_location `. + + + diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 20d54ee18..f2481f5dd 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -572,6 +572,8 @@ def flush(self): After the return from ``flush()`` any writes are guaranteed to have completed (or thrown an exception) and future reads will see their effects. + + .. deprecated: In 2.x. """ if self.wpts_dirty: self.__module.send_all_waypoints() @@ -690,6 +692,29 @@ def channel_readback(self): @property def home_location(self): + """ + The current home location in a :py:class:`LocationGlobal`. This value is typically the + GPS location of the vehicle at the point it is armed. + + .. code-block:: python + + #Connect to a vehicle object (for example, on com14) + vehicle = connect('com14', await_params=True) + + # Download the vehicle waypoints (commands). Wait until download is complete. + cmds = vehicle.commands + cmds.download() + cmds.wait_valid() + + # Get the home location + home = vehicle.home_location + + .. warning:: + + The home location will have a value of ``None`` until :py:func:`Vehicle.commands` has been + downloaded. If no home position has been set the returned location will have + zero values for its member attributes. + """ loc = self.__module.wploader.wp(0) if loc: return LocationGlobal(loc.x, loc.y, loc.z, is_relative=False) diff --git a/examples/mission_basic/mission_basic.py b/examples/mission_basic/mission_basic.py index 56a4ad2f3..835e890e7 100644 --- a/examples/mission_basic/mission_basic.py +++ b/examples/mission_basic/mission_basic.py @@ -67,31 +67,15 @@ def distance_to_current_waypoint(): It returns None for the first waypoint (Home location). """ nextwaypoint=vehicle.commands.next - if nextwaypoint ==1: + if nextwaypoint ==0: return None - missionitem=vehicle.commands[nextwaypoint] + missionitem=vehicle.commands[nextwaypoint-1] #commands are zero indexed lat=missionitem.x lon=missionitem.y alt=missionitem.z targetWaypointLocation=LocationGlobal(lat,lon,alt,is_relative=True) distancetopoint = get_distance_metres(vehicle.location.global_frame, targetWaypointLocation) return distancetopoint - - -def clear_mission(): - """ - Clear the current mission. - """ - cmds = vehicle.commands - vehicle.commands.clear() - vehicle.flush() - - # After clearing the mission you MUST re-download the mission from the vehicle - # before vehicle.commands can be used again - # (see https://github.com/dronekit/dronekit-python/issues/230) - cmds = vehicle.commands - cmds.download() - cmds.wait_valid() def download_mission(): @@ -112,8 +96,15 @@ def adds_square_mission(aLocation, aSize): The function assumes vehicle.commands matches the vehicle mission state (you must have called download at least once in the session and after clearing the mission) """ - # Add the commands. The meaning/order of the parameters is documented in the Command class. + cmds = vehicle.commands + + print " Clear any existing commands" + cmds.clear() + + print " Define/add new commands." + # Add new commands. The meaning/order of the parameters is documented in the Command class. + #Add MAV_CMD_NAV_TAKEOFF command. This is ignored if the vehicle is already in the air. cmds.add(Command( 0, 0, 0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_TAKEOFF, 0, 0, 0, 0, 0, 0, 0, 0, 10)) @@ -126,9 +117,11 @@ def adds_square_mission(aLocation, aSize): cmds.add(Command( 0, 0, 0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0, point2.lat, point2.lon, 12)) cmds.add(Command( 0, 0, 0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0, point3.lat, point3.lon, 13)) cmds.add(Command( 0, 0, 0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0, point4.lat, point4.lon, 14)) + #add dummy waypoint "5" at point 4 (lets us know when have reached destination) + cmds.add(Command( 0, 0, 0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0, point4.lat, point4.lon, 14)) - # Send commands to vehicle. - vehicle.flush() + print " Upload new commands to vehicle" + cmds.upload() def arm_and_takeoff(aTargetAltitude): @@ -169,13 +162,8 @@ def arm_and_takeoff(aTargetAltitude): time.sleep(1) - -print 'Clear the current mission' -clear_mission() - print 'Create a new mission' adds_square_mission(vehicle.location.global_frame,50) -time.sleep(2) # This is here so that mission being sent is displayed on console # From Copter 3.3 you will be able to take off using a mission item. Plane must take off using a mission item (currently). @@ -190,15 +178,14 @@ def arm_and_takeoff(aTargetAltitude): # Demonstrates getting and setting the command number # Uses distance_to_current_waypoint(), a convenience function for finding the # distance to the next waypoint. - while True: nextwaypoint=vehicle.commands.next - if nextwaypoint > 1: - print 'Distance to waypoint (%s): %s' % (nextwaypoint, distance_to_current_waypoint()) + print 'Distance to waypoint (%s): %s' % (nextwaypoint, distance_to_current_waypoint()) + if nextwaypoint==3: #Skip to next waypoint - print 'Skipping to Waypoint 4 when reach waypoint 3' - vehicle.commands.next=4 - if nextwaypoint==5: #Skip to next waypoint + print 'Skipping to Waypoint 5 when reach waypoint 3' + vehicle.commands.next=5 + if nextwaypoint==5: #Dummy waypoint - as soon as we reach waypoint 4 this is true and we exit. print "Exit 'standard' mission when start heading to final waypoint (5)" break; time.sleep(1) diff --git a/examples/mission_import_export/mission_import_export.py b/examples/mission_import_export/mission_import_export.py index dd22fe2cc..ce150c60f 100644 --- a/examples/mission_import_export/mission_import_export.py +++ b/examples/mission_import_export/mission_import_export.py @@ -10,10 +10,7 @@ from dronekit import connect -import time -import math from dronekit.lib import Command -from pymavlink import mavutil #Set up option parsing to get connection string @@ -24,7 +21,7 @@ args = parser.parse_args() -# Connect to the Vehicle +#Connect to the Vehicle print 'Connecting to vehicle on: %s' % args.connect vehicle = connect(args.connect, await_params=True) @@ -36,7 +33,7 @@ def readmission(aFileName): This function is used by upload_mission(). """ - print "Reading mission from file: %s\n" % aFileName + print "\nReading mission from file: %s" % aFileName cmds = vehicle.commands missionlist=[] with open(aFileName) as f: @@ -45,7 +42,6 @@ def readmission(aFileName): if not line.startswith('QGC WPL 110'): raise Exception('File is not supported WP version') else: - print ' Import line: %s' % line linearray=line.split('\t') ln_index=int(linearray[0]) ln_currentwp=int(linearray[1]) @@ -68,21 +64,19 @@ def upload_mission(aFileName): """ Upload a mission from a file. """ + #Read mission from file missionlist = readmission(aFileName) - #clear existing mission - print 'Clear mission' + + print "\nUpload mission from a file: %s" % import_mission_filename + #Clear existing mission from vehicle + print ' Clear mission' cmds = vehicle.commands - cmds.download() - cmds.wait_valid() cmds.clear() - vehicle.flush() - print 'ClearCount: %s' % cmds.count - #add new mission - cmds.download() - cmds.wait_valid() + #Add new mission to vehicle for command in missionlist: cmds.add(command) - vehicle.flush() + print ' Upload mission' + vehicle.commands.upload() def download_mission(): @@ -90,38 +84,65 @@ def download_mission(): Downloads the current mission and returns it in a list. It is used in save_mission() to get the file information to save. """ + print " Download mission from vehicle" missionlist=[] cmds = vehicle.commands cmds.download() cmds.wait_valid() - for cmd in cmds[1:]: #skip first item as it is home waypoint. + for cmd in cmds: missionlist.append(cmd) return missionlist def save_mission(aFileName): """ - Save a mission in the Waypoint file format (http://qgroundcontrol.org/mavlink/waypoint_protocol#waypoint_file_format). + Save a mission in the Waypoint file format + (http://qgroundcontrol.org/mavlink/waypoint_protocol#waypoint_file_format). """ + print "\nSave mission from Vehicle to file: %s" % export_mission_filename + #Download mission from vehicle missionlist = download_mission() + #Add file-format information output='QGC WPL 110\n' + #Add home location as 0th waypoint + home = vehicle.home_location + output+="%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" % (0,1,0,16,0,0,0,0,home.lat,home.lon,home.alt,1) + #Add commands for cmd in missionlist: commandline="%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" % (cmd.seq,cmd.current,cmd.frame,cmd.command,cmd.param1,cmd.param2,cmd.param3,cmd.param4,cmd.x,cmd.y,cmd.z,cmd.autocontinue) output+=commandline with open(aFileName, 'w') as file_: - file_.write(output) + print " Write mission to file" + file_.write(output) + + +def printfile(aFileName): + """ + Print a mission file to demonstrate "round trip" + """ + print "\nMission file: %s" % aFileName + with open(aFileName) as f: + for line in f: + print ' %s' % line.strip() import_mission_filename = 'mpmission.txt' export_mission_filename = 'exportedmission.txt' -print "\nUpload mission from a file: %s" % import_mission_filename +#Upload mission from file upload_mission(import_mission_filename) -time.sleep(1) - -print "\nSave mission from Vehicle to file: %s" % export_mission_filename +#Download mission we just uploaded and save to a file save_mission(export_mission_filename) #Close vehicle object before exiting script print "Close vehicle object" -vehicle.close() \ No newline at end of file +vehicle.close() + + + +print "\nShow original and uploaded/downloaded files:" +#Print original file (for demo purposes only) +printfile(import_mission_filename) +#Print exported file (for demo purposes only) +printfile(export_mission_filename) + diff --git a/examples/mission_import_export/mpmission.txt b/examples/mission_import_export/mpmission.txt index bd331abdd..2ca281d09 100644 --- a/examples/mission_import_export/mpmission.txt +++ b/examples/mission_import_export/mpmission.txt @@ -1,9 +1,8 @@ QGC WPL 110 -0 1 0 16 0 0 0 0 -35.360500 149.172363 747.000000 1 -1 0 3 22 0.000000 0.000000 0.000000 0.000000 -35.359831 149.166334 100.000000 1 -2 0 3 16 0.000000 0.000000 0.000000 0.000000 -35.363489 149.167213 100.000000 1 -3 0 3 16 0.000000 0.000000 0.000000 0.000000 -35.355491 149.169595 100.000000 1 -4 0 3 16 0.000000 0.000000 0.000000 0.000000 -35.355071 149.175839 100.000000 1 -5 0 3 113 0.000000 0.000000 0.000000 0.000000 -35.362666 149.178715 22222.000000 1 -6 0 3 115 2.000000 22.000000 1.000000 3.000000 0.000000 0.000000 0.000000 1 -7 0 3 16 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1 +0 1 0 16 0 0 0 0 -35.363262 149.165237 584.000000 1 +1 0 0 22 0.000000 0.000000 0.000000 0.000000 -35.361988 149.163753 100.000000 1 +2 0 0 16 0.000000 0.000000 0.000000 0.000000 -35.361992 149.163593 100.000000 1 +3 0 0 16 0.000000 0.000000 0.000000 0.000000 -35.363812 149.163609 100.000000 1 +4 0 0 16 0.000000 0.000000 0.000000 0.000000 -35.363768 149.166055 100.000000 1 +5 0 0 16 0.000000 0.000000 0.000000 0.000000 -35.361835 149.166012 100.000000 1 +6 0 0 16 0.000000 0.000000 0.000000 0.000000 -35.362150 149.165046 100.000000 1 From cc408fa04b62990846d4f37c0f33ca01f38eaeeb Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 2 Nov 2015 21:12:04 +1100 Subject: [PATCH 102/475] Further fixes to correct use vehicle.home_location and other minor changes --- docs/examples/channel_overrides.rst | 4 +- docs/examples/create_attribute.rst | 4 +- docs/examples/drone_delivery.rst | 4 +- docs/examples/flight_replay.rst | 39 +++++------- docs/examples/guided-set-speed-yaw-demo.rst | 29 +++++---- docs/examples/mission_basic.rst | 4 +- docs/examples/mission_import_export.rst | 4 +- docs/examples/simple_goto.rst | 4 +- docs/examples/vehicle_state.rst | 30 +++++----- docs/guide/copter/guided_mode.rst | 22 +++++-- docs/guide/vehicle_state_and_parameters.rst | 60 +++++++++++-------- dronekit/lib/__init__.py | 22 +++---- examples/flight_replay/flight_replay.py | 8 ++- .../guided_set_speed_yaw.py | 2 +- examples/vehicle_state/vehicle_state.py | 19 +++--- 15 files changed, 140 insertions(+), 115 deletions(-) diff --git a/docs/examples/channel_overrides.rst b/docs/examples/channel_overrides.rst index abd09fba3..827b6fda1 100644 --- a/docs/examples/channel_overrides.rst +++ b/docs/examples/channel_overrides.rst @@ -43,8 +43,8 @@ In summary, after cloning the repository: .. note:: - The examples uses the ``--connect`` parameter to pass the :ref:`connection string ` into the script. - The command above would be used to connect to :ref:`SITL ` running on the local machine via UDP port 14550. + The ``--connect`` parameter above connects to SITL on udp port 127.0.0.1:14550. + This is the default value for the parameter, and may be omitted. diff --git a/docs/examples/create_attribute.rst b/docs/examples/create_attribute.rst index 91657a2b0..1c35d2408 100644 --- a/docs/examples/create_attribute.rst +++ b/docs/examples/create_attribute.rst @@ -42,8 +42,8 @@ In summary, after cloning the repository: .. note:: - The command parameter above is the default, and may be omitted. This - connects to SITL on udp port 127.0.0.1:14550. + The ``--connect`` parameter above connects to SITL on udp port 127.0.0.1:14550. + This is the default value for the parameter, and may be omitted. diff --git a/docs/examples/drone_delivery.rst b/docs/examples/drone_delivery.rst index 581021f35..88f781287 100644 --- a/docs/examples/drone_delivery.rst +++ b/docs/examples/drone_delivery.rst @@ -53,8 +53,8 @@ In summary, after cloning the repository: .. note:: - The command parameter above is the default, and may be omitted. This - connects to SITL on udp port 127.0.0.1:14550. + The ``--connect`` parameter above connects to SITL on udp port 127.0.0.1:14550. + This is the default value for the parameter, and may be omitted. #. After a short while you should be able to reach your new webserver at http://localhost:8080. diff --git a/docs/examples/flight_replay.rst b/docs/examples/flight_replay.rst index 942dde5a7..5ce47375c 100644 --- a/docs/examples/flight_replay.rst +++ b/docs/examples/flight_replay.rst @@ -2,17 +2,17 @@ Example: Flight Replay ========================= -This example requests a past flight from Droneshare, and then "replays" the mission -by sending waypoints to a vehicle. For safety reasons, the vehicle is replayed at a height of 30 meters. +This example requests a past flight from Droneshare, and then writes the recorded path to the vehicle as mission waypoints. +For safety reasons, the altitude for the waypoints is set to 30 meters (irrespective of the recorded height). -.. warning:: +.. note:: - At time of writing this example fails with an exception in DKYP2: `#355 DKPY2 Can't clear waypoints `_. + The mission is not actually run by this code - though it easily could be by taking off and putting the vehicle into + AUTO mode. -.. todo:: Check if `#355 DKPY2 Can't clear waypoints `_ is fixed and re-review example. You can specify which mission to replay using a parameter when starting the script (for example, to replay your own local flights). -By default the code gets (and replays) the public `Droneshare mission with ID 101 `_. +By default the code gets the public `Droneshare mission with ID 101 `_. .. figure:: flight_replay_example.png @@ -47,8 +47,9 @@ In summary, after cloning the repository: .. note:: - The command parameters above are the defaults, and may be omitted. These - connect to SITL on udp port 127.0.0.1:14550 and replay the mission with id 101. + The ``--connect`` parameter above connects to SITL on udp port 127.0.0.1:14550, while + ``--mission_id`` specifies we're replaying mission 101. Both of these are the default + values for the parameters, and may be omitted. .. tip:: @@ -60,22 +61,20 @@ On the command prompt you should see (something like): .. code-block:: bash - - \dronekit-python\examples\flight_replay>flight_replay.py Connecting to vehicle on: 127.0.0.1:14550 - >>> APM:Copter V3.4-dev (e0810c2e) + >>> APM:Copter V3.3 (d6053245) >>> Frame: QUAD JSON downloaded... Generating 95 waypoints from replay... - ... + Close vehicle object + Completed... How it works ============ The example requests the web server for representative points from the flight, parses the JSON response -and uses that data to generate 100 waypoints. These are then sent to the vehicle. - +and uses that data to generate 100 waypoints. These are then sent to the vehicle. Getting the points @@ -111,7 +110,6 @@ shown in :ref:`example_mission_basic`): print "Generating %s waypoints from replay..." % len(messages) cmds = vehicle.commands cmds.clear() - vehicle.flush() for i in xrange(0, len(messages)): pt = messages[i] lat = pt['lat'] @@ -127,19 +125,14 @@ shown in :ref:`example_mission_basic`): 0, 0, 0, 0, 0, 0, lat, lon, altitude) cmds.add(cmd) - vehicle.flush() + #Upload clear message and command messages to vehicle. + cmds.upload() Known issues ============ -At time of writing this example fails with an exception. See `#355 DKPY2 Can't clear waypoints `_ for more information. - -.. todo:: - - When example is fixed replace above text with - "This example works around the :ref:`known issues in the API `. - Provided that the vehicle is connected and able to arm, it should run through to completion." +There are no known issues with this example. diff --git a/docs/examples/guided-set-speed-yaw-demo.rst b/docs/examples/guided-set-speed-yaw-demo.rst index f76961d8c..dff4cd12a 100644 --- a/docs/examples/guided-set-speed-yaw-demo.rst +++ b/docs/examples/guided-set-speed-yaw-demo.rst @@ -4,9 +4,14 @@ Example: Guided Mode Movement and Commands (Copter) =================================================== -This example shows how to control Copter movement and send immediate commands in :ref:`GUIDED mode `. It demonstrates three methods for explicitly specifying a target position and two commands for controlling movement by setting the vehicle's velocity vectors. It also shows how to send commands to control the yaw (direction that the front of the vehicle is pointing), region of interest, speed and home position, along with some useful functions for converting between frames of reference. +This example shows how to control Copter movement and send immediate commands in :ref:`GUIDED mode `. +It demonstrates three methods for explicitly specifying a target position and two commands for controlling movement by +setting the vehicle's velocity vectors. It also shows how to send commands to control the yaw (direction that the front +of the vehicle is pointing), region of interest, speed and home location, along with some useful functions for +converting between frames of reference. -The example is :ref:`documented in the source code `. More detailed information about using GUIDED mode can be found in the guide: :ref:`guided_mode_copter`. +The example is :ref:`documented in the source code `. +More detailed information about using GUIDED mode can be found in the guide: :ref:`guided_mode_copter`. .. figure:: GuidedModeExample_FlyByPosition.png @@ -50,8 +55,8 @@ In summary, after cloning the repository: .. note:: - The command parameter above is the default, and may be omitted. This - connects to SITL on udp port 127.0.0.1:14550. + The ``--connect`` parameter above connects to SITL on udp port 127.0.0.1:14550. + This is the default value for the parameter, and may be omitted. .. tip:: @@ -152,8 +157,7 @@ On the command prompt you should see (something like): Yaw 90 relative (to previous yaw heading) Set new Home location to current location Get new home location - Home WP: MISSION_ITEM {target_system : 255, target_component : 0, seq : 0, frame : 0, command : 16, current : 0, autocontinue : 1, param1 : 0.0, param2 : 0.0, param3 : 0.0, param4 : 0.0, x : - -35.3632583618, y : 149.164352417, z : 593.91998291} + Home Location: LocationGlobal:lat=-35.3639335632,lon=149.165328979,alt=628.679992676,is_relative=False Velocity South and West Yaw 90 relative (to previous yaw heading) Velocity North and West @@ -266,8 +270,9 @@ which is used to directly specify the speed components of the vehicle. The funct goto_position_target_global_int() --------------------------------- -The function ``goto_position_target_global_int()`` generates a `SET_POSITION_TARGET_GLOBAL_INT `_ MAVLink message -which is used to directly specify the target location of the vehicle. When used with ``MAV_FRAME_GLOBAL_RELATIVE_ALT_INT`` as shown below, this method is effectively the same as :ref:`Vehicle.commands.goto `. +The function ``goto_position_target_global_int()`` generates a `SET_POSITION_TARGET_GLOBAL_INT `_ +MAVLink message which is used to directly specify the target location of the vehicle. When used with ``MAV_FRAME_GLOBAL_RELATIVE_ALT_INT`` as shown below, +this method is effectively the same as :ref:`Vehicle.commands.goto `. .. code-block:: python @@ -310,7 +315,8 @@ which is used to directly specify the target location in the North, East, Down f .. note:: - The `documentation `_ lists a number of possible frames of reference. At time of writing experimentation indicates that the actual frame use is always relative to the home location (not the vehicle, as indicated by MAV_FRAME_BODY_NED). + The `documentation `_ lists a number of possible frames of reference. + Up until Copter 3.2.1 the actual frame use is always relative to the home location (not the vehicle, as indicated by MAV_FRAME_BODY_NED). .. code-block:: python @@ -333,7 +339,7 @@ which is used to directly specify the target location in the North, East, Down f vehicle.send_mavlink(msg) -At time of writing, acceleration and yaw bits are ignored. +At time of writing, acceleration and yaw bits are ignored. Testbed settings @@ -359,7 +365,8 @@ ArduPilot version: Source code =========== -The full source code at documentation build-time is listed below (`current version on github `_): +The full source code at documentation build-time is listed below +(`current version on github `_): .. literalinclude:: ../../examples/guided_set_speed_yaw/guided_set_speed_yaw.py :language: python diff --git a/docs/examples/mission_basic.rst b/docs/examples/mission_basic.rst index 8c3794ef2..ee29857c4 100644 --- a/docs/examples/mission_basic.rst +++ b/docs/examples/mission_basic.rst @@ -45,8 +45,8 @@ In summary, after cloning the repository: .. note:: - The ``--connect`` parameter above specifies the default value, and may be omitted. - This connects to SITL on udp port 127.0.0.1:14550. + The ``--connect`` parameter above connects to SITL on udp port 127.0.0.1:14550. + This is the default value for the parameter, and may be omitted. .. tip:: diff --git a/docs/examples/mission_import_export.rst b/docs/examples/mission_import_export.rst index bf2bc8be0..760b0eae3 100644 --- a/docs/examples/mission_import_export.rst +++ b/docs/examples/mission_import_export.rst @@ -43,8 +43,8 @@ In summary, after cloning the repository: .. note:: - The ``--connect`` parameter above specifies the default value, and may be omitted. - This connects to SITL on udp port 127.0.0.1:14550. + The ``--connect`` parameter above connects to SITL on udp port 127.0.0.1:14550. + This is the default value for the parameter, and may be omitted. On the command prompt you should see (something like): diff --git a/docs/examples/simple_goto.rst b/docs/examples/simple_goto.rst index 0440eef39..1b72ce8b3 100644 --- a/docs/examples/simple_goto.rst +++ b/docs/examples/simple_goto.rst @@ -53,8 +53,8 @@ In summary, after cloning the repository: .. note:: - The command parameter above is the default, and may be omitted. This - connects to SITL on udp port 127.0.0.1:14550. + The ``--connect`` parameter above connects to SITL on udp port 127.0.0.1:14550. + This is the default value for this example, and may be omitted. .. tip:: diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index 6f4c5bacf..07a513ee3 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -40,8 +40,8 @@ In summary, after cloning the repository: .. note:: - The examples uses the ``--connect`` parameter to pass the :ref:`connection string ` into the script. - The command above would be used to connect to :ref:`SITL ` running on the local machine via UDP port 14550. + The ``--connect`` parameter above connects to SITL on udp port 127.0.0.1:14550. + This is the default value for the parameter, and may be omitted. @@ -50,35 +50,37 @@ On the command prompt you should see (something like): .. code:: bash Connecting to vehicle on: 127.0.0.1:14550 - >>> APM:Copter V3.3-rc1 (d66eec53) + >>> APM:Copter V3.3 (d6053245) >>> Frame: QUAD - Accumulating vehicle attribute messages (2s) + Accumulating vehicle attribute messages Get all vehicle attribute values: - Global Location: LocationGlobal:lat=-35.363261,lon=149.1652299,alt=0.0,is_relative=False + Global Location: LocationGlobal:lat=-35.3632615,lon=149.1652301,alt=0.0,is_relative=False Local Location: LocationLocal:north=None,east=None,down=None - Attitude: Attitude:pitch=0.00486609805375,yaw=0.489637970924,roll=0.00645932834595 - Velocity: [-0.12, 0.06, 0.0] + Attitude: Attitude:pitch=0.00589594058692,yaw=-0.0884591862559,roll=0.000426373298978 + Velocity: [-0.02, 0.02, 0.0] GPS: GPSInfo:fix=3,num_sat=10 Groundspeed: 0.0 Airspeed: 0.0 Mount status: [None, None, None] - Battery: Battery:voltage=0.0,current=None,level=None + Battery: Battery:voltage=12.587,current=0.0,level=99 Rangefinder: Rangefinder: distance=None, voltage=None Rangefinder distance: None Rangefinder voltage: None Mode: STABILIZE Armed: False + Home Location (before downloading waypoints): None + Home Location (after downloading waypoints): LocationGlobal:lat=-35.3632621765,lon=149.165237427,alt=583.989990234,is_relative=False + Set Vehicle.mode=GUIDED (currently: STABILIZE) Waiting for mode change ... Set Vehicle.armed=True (currently: False) Waiting for arming... - >>> ☺ARMING MOTORS - >>> ☺Initialising APM... - Waiting for arming... + >>> ARMING MOTORS + >>> Initialising APM... Add mode attribute observer for Vehicle.mode Set mode=STABILIZE (currently: GUIDED) @@ -86,17 +88,15 @@ On the command prompt you should see (something like): CALLBACK: Mode changed to: STABILIZE CALLBACK: Mode changed to: STABILIZE - Get home location - Home WP: MISSION_ITEM {target_system : 255, target_component : 0, seq : 0, frame : 0, command : 16, current : 0, autocontinue : 1, param1 : 0.0, param2 : 0.0, param3 : 0.0, param4 : 0.0, x : -35.3632583618, y : 149.165222168, z : 583.729980469} - Read vehicle param 'THR_MIN': 130.0 Write vehicle param 'THR_MIN' : 10 Read new value of param 'THR_MIN': 10.0 Reset vehicle attributes/parameters and exit - >>> ☺DISARMING MOTORS + >>> DISARMING MOTORS Close vehicle object + Completed diff --git a/docs/guide/copter/guided_mode.rst b/docs/guide/copter/guided_mode.rst index 861d4950b..335e1dab2 100644 --- a/docs/guide/copter/guided_mode.rst +++ b/docs/guide/copter/guided_mode.rst @@ -37,7 +37,10 @@ Position control Controlling the vehicle by explicitly setting the target position is useful when the final position is known/fixed. -The recommended method for position control is :py:func:`Vehicle.commands.goto() `. This takes a :py:class:`LocationGlobal ` argument for the target position in the global `WGS84 coordinate system `_, but with altitude relative to the home location (home altitude = 0). +The recommended method for position control is :py:func:`Vehicle.commands.goto() `. +This takes a :py:class:`LocationGlobal ` argument for the target position in the +global `WGS84 coordinate system `_, but with altitude +relative to the home location (home altitude = 0). The method is used as shown below: @@ -51,13 +54,23 @@ The method is used as shown below: vehicle.commands.goto(a_location) -``Vehicle.commands.goto()`` can be interrupted by a later command, and does not provide any functionality to indicate when the vehicle has reached its destination. Developers can use either a time delay or :ref:`measure proximity to the target ` to give the vehicle an opportunity to reach its destination. The :ref:`example-guided-mode-setting-speed-yaw` shows both approaches. +``Vehicle.commands.goto()`` can be interrupted by a later command, and does not provide any functionality +to indicate when the vehicle has reached its destination. Developers can use either a time delay or +:ref:`measure proximity to the target ` to give the vehicle an +opportunity to reach its destination. The :ref:`example-guided-mode-setting-speed-yaw` shows both approaches. When moving the vehicle you can send a separate command to :ref:`control the speed ` (and other vehicle behaviour). .. tip:: - You can also set the position by sending the MAVLink commands `SET_POSITION_TARGET_GLOBAL_INT `_ or `SET_POSITION_TARGET_LOCAL_NED `_, specifying a ``type_mask`` bitmask that enables the position parameters. The main difference between these commands is that the former allows you to specify the location relative to the "global" frames (like ``Vehicle.commands.goto()``), while the later lets you specify the location in NED co-ordinates relative to the home location. For more information on these options see the example code: :ref:`example_guided_mode_goto_position_target_global_int` and :ref:`example_guided_mode_goto_position_target_local_ned`. + You can also set the position by sending the MAVLink commands + `SET_POSITION_TARGET_GLOBAL_INT `_ or + `SET_POSITION_TARGET_LOCAL_NED `_, specifying + a ``type_mask`` bitmask that enables the position parameters. The main difference between these commands is + that the former allows you to specify the location relative to the "global" frames (like + ``Vehicle.commands.goto()``), while the later lets you specify the location in NED co-ordinates relative + to the home location. For more information on these options see the example code: + :ref:`example_guided_mode_goto_position_target_global_int` and :ref:`example_guided_mode_goto_position_target_local_ned`. @@ -313,7 +326,8 @@ The ROI (and yaw) is also reset when the mode, or the command used to control mo Setting the home location ------------------------- -Send the `MAV_CMD_DO_SET_HOME `_ command to set the *home location* to either the current location or a specified location. +Send the `MAV_CMD_DO_SET_HOME `_ +command to set the *home location* to either the current location or a specified location. .. code-block:: python diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index d5e08606e..74cee15d6 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -30,6 +30,7 @@ Vehicle state information is exposed through vehicle *attributes*. DroneKit-Pyth :py:attr:`Vehicle.mount_status `, :py:attr:`Vehicle.battery `, :py:attr:`Vehicle.rangefinder `, +:py:attr:`Vehicle.home_location ` :py:attr:`Vehicle.armed `, :py:attr:`Vehicle.mode `. @@ -44,7 +45,7 @@ status can be :ref:`written `. Getting attributes ------------------ -The code fragment below shows how to read and print all the attributes. The values are retrieved from the remote device +The code fragment below shows how to read and print almost the attributes. The values are retrieved from the remote device (not cached). .. code:: python @@ -72,6 +73,9 @@ If an attribute cannot be retrieved then the returned object will contain with ``None`` values for ``eph``, ``satellites_visible`` etc.) Attributes will also return ``None`` if the associated hardware is not present on the connected device. +The behaviour of :py:attr:`Vehicle.home_location ` is different, +:ref:`as discussed below `. + .. tip:: If you're using a :ref:`simulated vehicle ` you can add support for optional hardware including @@ -79,7 +83,7 @@ Attributes will also return ``None`` if the associated hardware is not present and `optical flow sensors `_. - + .. todo:: we need to be able to verify mount_status works/setup. @@ -127,7 +131,7 @@ to confirm they have changed before proceeding. Observing attribute changes --------------------------- -You can observe any of the attributes and will receive notification every time a value is received from the connected vehicle. +You can observe any of the attributes (except the ``home_location``) and will receive notification every time a value is received from the connected vehicle. This allows you to monitor changes to velocity and other vehicle state without the need for polling. Observers are added using :py:func:`Vehicle.add_attribute_observer() `, @@ -175,6 +179,33 @@ For example, the following code can be used in the callback to only print output +.. _vehicle_state_home_location: + +Home location +------------- + +The *Home location* is set when a vehicle is armed and first gets a good location fix from the GPS. The location is used +as the target when the vehicle does a "return to launch". In Copter missions (and often Plane) missions, the altitude of +waypoints is set relative to this position. + +The behaviour of :py:attr:`Vehicle.home_location ` is slightly different than other attributes: + +* In order to get the current value you must first download :py:attr:`Vehicle.commands `, as shown: + + .. code:: python + + cmds = vehicle.commands + cmds.download() + cmds.wait_valid() + print " Home Location: %s" % vehicle.home_location + + The returned value is a :py:class:`LocationGlobal ` object + (or ``None`` before you download the commands). +* The attribute is not observable. +* While you cannot directly set the attribute it can be :ref:`set using a message `. + + + .. _vehicle_state_parameters: Parameters @@ -235,28 +266,6 @@ At time of writing :py:class:`Parameters ` does `not su -.. _vehicle_state_home_location: - -Home location -============= - -The *Home location* is set when a vehicle is armed and first gets a good location fix from the GPS. The location is used -as the target when the vehicle does a "return to launch". In Copter missions (and most Plane) missions, the altitude of -waypoints is set relative to this position. - -Unlike other vehicle state information, the home location is accessed as the 0 index value of -:py:attr:`Vehicle.commands `: - -.. code:: python - - cmds = vehicle.commands - cmds.download() - cmds.wait_valid() - print " Home WP: %s" % cmds[0] - -The returned value is a :py:class:`Command ` object. - - .. _api-information-known-issues: @@ -268,6 +277,7 @@ Below are a number of bugs and known issues related to vehicle state and setting * `#60 Attribute observer callbacks are called with heartbeat until disabled - after first called `_ * `#107 Add implementation for observer methods in Parameter class `_ * `#114 DroneKit has no method for detecting command failure `_ +* `#392 vehicle.home_location should be settable `_ Other API issues and improvement suggestions can viewed on `github here `_. \ No newline at end of file diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index f2481f5dd..451d4daab 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -573,7 +573,7 @@ def flush(self): After the return from ``flush()`` any writes are guaranteed to have completed (or thrown an exception) and future reads will see their effects. - .. deprecated: In 2.x. + .. deprecated: This has been replaced by :py:func:`Vehicle.commands.upload() `. """ if self.wpts_dirty: self.__module.send_all_waypoints() @@ -708,6 +708,8 @@ def home_location(self): # Get the home location home = vehicle.home_location + + The attribute is not writeable or observable. .. warning:: @@ -969,13 +971,12 @@ class CommandSequence(object): cmds.wait_valid() The set of commands can be changed and uploaded to the client. The changes are not guaranteed to be complete until - :py:func:`flush() ` is called on the parent :py:class:`Vehicle` object. + :py:func:`upload() ` is called. .. code:: python cmds = vehicle.commands cmds.clear() - vehicle.flush() lat = -34.364114, lon = 149.166022 altitude = 30.0 @@ -983,7 +984,7 @@ class CommandSequence(object): 0, 0, 0, 0, 0, 0, lat, lon, altitude) cmds.add(cmd) - vehicle.flush() + cmds.upload() .. py:function:: takeoff(altitude) @@ -1071,14 +1072,9 @@ def goto(self, l): def clear(self): ''' - Clear the command list. - - .. warning:: - - Call ``flush()`` immediately after clearing the commands/before adding new commands (see - `#132 for more information `_). - - .. todo:: The above note should be removed when https://github.com/dronekit/dronekit-python/issues/132 fixed + Clear the command list. + + This command will be sent to the vehicleonly after you call :py:func:`upload() `. ''' # Add home point again. @@ -1093,7 +1089,7 @@ def add(self, cmd): ''' Add a new command (waypoint) at the end of the command list. - .. note:: Commands are sent to the vehicle only after you call :py:func:`Vehicle.flush`. + .. note:: Commands are sent to the vehicle only after you call ::py:func:`upload() `. :param Command cmd: The command to be added. ''' diff --git a/examples/flight_replay/flight_replay.py b/examples/flight_replay/flight_replay.py index c48c73607..e4ce156b6 100644 --- a/examples/flight_replay/flight_replay.py +++ b/examples/flight_replay/flight_replay.py @@ -90,7 +90,6 @@ def replay_mission(payload): print "Generating %s waypoints from replay..." % len(messages) cmds = vehicle.commands cmds.clear() - vehicle.flush() for i in xrange(0, len(messages)): pt = messages[i] lat = pt['lat'] @@ -106,7 +105,8 @@ def replay_mission(payload): 0, 0, 0, 0, 0, 0, lat, lon, altitude) cmds.add(cmd) - vehicle.flush() + #Upload clear message and command messages to vehicle. + cmds.upload() # Now download the vehicle waypoints @@ -119,6 +119,10 @@ def replay_mission(payload): replay_mission(json) +#Here you could actually replay the mission by +#taking off and changing to AUTO mode. + + #Close vehicle object before exiting script print "Close vehicle object" vehicle.close() diff --git a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py index f658dd275..87534979b 100644 --- a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py +++ b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py @@ -612,7 +612,7 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z): cmds = vehicle.commands cmds.download() cmds.wait_valid() -print " Home WP: %s" % cmds[0] +print " Home Location: %s" % vehicle.home_location print("Velocity South and West") send_global_velocity(NORTH,EAST,0) diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index f0cba15ae..1dc987aba 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -50,6 +50,15 @@ print " Armed: %s" % vehicle.armed # settable +# Get Vehicle Home location +print "\n Home Location (before downloading waypoints): %s" % vehicle.home_location + +cmds = vehicle.commands +cmds.download() +cmds.wait_valid() +print " Home Location (after downloading waypoints): %s" % vehicle.home_location + + # Set vehicle mode and armed attributes (the only settable attributes) print "\nSet Vehicle.mode=GUIDED (currently: %s)" % vehicle.mode.name vehicle.mode = VehicleMode("GUIDED") @@ -76,7 +85,7 @@ def mode_callback(attribute): print " CALLBACK: Mode changed to: ", vehicle.mode.name print "\nAdd mode attribute observer for Vehicle.mode" -vehicle.add_attribute_observer('mode', mode_callback) +vehicle.add_attribute_observer('mode', mode_callback) print " Set mode=STABILIZE (currently: %s)" % vehicle.mode.name vehicle.mode = VehicleMode("STABILIZE") @@ -88,14 +97,6 @@ def mode_callback(attribute): vehicle.remove_attribute_observer('mode', mode_callback) -# Get Vehicle Home location ((0 index in Vehicle.commands) -print "\nGet home location" -cmds = vehicle.commands -cmds.download() -cmds.wait_valid() -print " Home WP: %s" % cmds[0] - - # Get/Set Vehicle Parameters print "\nRead vehicle param 'THR_MIN': %s" % vehicle.parameters['THR_MIN'] print "Write vehicle param 'THR_MIN' : 10" From 45ec6deaf2d9dc0769e78c0c73dc69810a9beff1 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 2 Nov 2015 12:39:28 -0800 Subject: [PATCH 103/475] Corrects last_waypoint and .next setting. Closes #390. --- dronekit/__init__.py | 2 +- tests/sitl/test_waypoints.py | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 17475ddc5..bebee0537 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -195,7 +195,7 @@ def listener(self, name, m): @message_default(['WAYPOINT_CURRENT', 'MISSION_CURRENT']) def listener(self, name, m): - self.last_waypoint = m.seq + self.last_waypoint = max(m.seq - 1, 0) self.rc_readback = {} diff --git a/tests/sitl/test_waypoints.py b/tests/sitl/test_waypoints.py index 06dbd0565..8bd8919ef 100644 --- a/tests/sitl/test_waypoints.py +++ b/tests/sitl/test_waypoints.py @@ -75,6 +75,13 @@ def test_parameter(connpath): count += 1 assert_equals(count, 6) + # Test next property + assert_equals(vehicle.commands.next, 0) + vehicle.commands.next = 3 + while vehicle.commands.next != 3: + time.sleep(0.1) + assert_equals(vehicle.commands.next, 3) + # Home should be preserved assert_equals(home.lat, vehicle.home_location.lat) assert_equals(home.lon, vehicle.home_location.lon) From 3f355175f893693ce3369f0b6a6b33cb0ea2a5fd Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 2 Nov 2015 14:18:49 -0800 Subject: [PATCH 104/475] Adds ability to set home_location. --- dronekit/lib/__init__.py | 18 ++++++++++++++++++ tests/sitl/test_waypoints.py | 22 ++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 451d4daab..f9437c22e 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -720,6 +720,24 @@ def home_location(self): loc = self.__module.wploader.wp(0) if loc: return LocationGlobal(loc.x, loc.y, loc.z, is_relative=False) + + @home_location.setter + def home_location(self, pos): + """ + Sets the home location to that of a LocationGlobal object. + + .. note:: If the GPS values differ heavily from EKF values, setting this value will fail silently. + """ + self.send_mavlink(self.message_factory.command_long_encode( + 0, 0, # target system, target component + mavutil.mavlink.MAV_CMD_DO_SET_HOME, # command + 0, # confirmation + 2, # param 1: 1 to use current position, 2 to use the entered values. + 0, 0, 0, # params 2-4 + pos.lat, + pos.lon, + pos.alt + )) @property def commands(self): diff --git a/tests/sitl/test_waypoints.py b/tests/sitl/test_waypoints.py index 8bd8919ef..a3d4cf044 100644 --- a/tests/sitl/test_waypoints.py +++ b/tests/sitl/test_waypoints.py @@ -14,6 +14,28 @@ def test_empty_clear(connpath): assert_equals(len(vehicle.commands), 0) +@with_sitl +def test_set_home(connpath): + vehicle = connect(connpath, await_params=True) + + # Wait for home position to be real and not 0, 0, 0 + # once we request it via cmds.download() + time.sleep(10) + vehicle.commands.download() + vehicle.commands.wait_valid() + assert_not_equals(vehicle.home_location, None) + + # Note: If the GPS values differ heavily from EKF values, this command + # will basically fail silently. This GPS coordinate is tailored for that + # the with_sitl initializer uses to not fail. + vehicle.home_location = LocationGlobal(-35, 149, 600) + vehicle.commands.download() + vehicle.commands.wait_valid() + + assert_equals(vehicle.home_location.lat, -35) + assert_equals(vehicle.home_location.lon, 149) + assert_equals(vehicle.home_location.alt, 600) + @with_sitl def test_parameter(connpath): vehicle = connect(connpath, await_params=True) From 3497ac1d884707774b127d2199a4a3adb4cf0e5e Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 3 Nov 2015 11:03:48 +1100 Subject: [PATCH 105/475] Add note about rounding errors in returned values --- docs/examples/mission_import_export.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/examples/mission_import_export.rst b/docs/examples/mission_import_export.rst index 760b0eae3..cd00b68c7 100644 --- a/docs/examples/mission_import_export.rst +++ b/docs/examples/mission_import_export.rst @@ -91,6 +91,15 @@ On the command prompt you should see (something like): 6 0 0 16 0.0 0.0 0.0 0.0 -35.3621482849 149.165039062 100.0 1 +.. note:: + + The position values uploaded and then downloaded above do not match exactly. This rounding error can be ignored + because the difference is much smaller than the precision provided by GPS. + + The error occurs because all the params are encoded as 32-bit floats rather than 64-bit doubles (Python's native datatype). + + + How does it work? ================= From 1c7f4852d0d0f5f3952569680e159ad94f269fb2 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 3 Nov 2015 11:04:42 +1100 Subject: [PATCH 106/475] Add doc for clear(). Fix up warning/deprecated for flush() --- dronekit/lib/__init__.py | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index f9437c22e..3b5b85aeb 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -564,6 +564,14 @@ def __init__(self, module): self.wpts_dirty = False def close(self): + """ + Call ``Vehicle.close()`` before exiting scripts to ensure that all messages have been uploaded/sent: + + .. code:: python + + # About to exit script + vehicle.close() + """ return self.__module.close() def flush(self): @@ -573,7 +581,9 @@ def flush(self): After the return from ``flush()`` any writes are guaranteed to have completed (or thrown an exception) and future reads will see their effects. - .. deprecated: This has been replaced by :py:func:`Vehicle.commands.upload() `. + .. warning:: + + This has been replaced by :py:func:`Vehicle.commands.upload() `. """ if self.wpts_dirty: self.__module.send_all_waypoints() @@ -693,8 +703,12 @@ def channel_readback(self): @property def home_location(self): """ - The current home location in a :py:class:`LocationGlobal`. This value is typically the - GPS location of the vehicle at the point it is armed. + The current home location in a :py:class:`LocationGlobal`. + + This value is initially set by the autopilot as the location of first GPS Lock. + The attribute has a value of ``None`` until :py:func:`Vehicle.commands` has been downloaded. + If the attribute is queried before the home location is set the returned `LocationGlobal` + will have zero values for its member attributes. .. code-block:: python @@ -711,11 +725,6 @@ def home_location(self): The attribute is not writeable or observable. - .. warning:: - - The home location will have a value of ``None`` until :py:func:`Vehicle.commands` has been - downloaded. If no home position has been set the returned location will have - zero values for its member attributes. """ loc = self.__module.wploader.wp(0) if loc: @@ -724,9 +733,11 @@ def home_location(self): @home_location.setter def home_location(self, pos): """ - Sets the home location to that of a LocationGlobal object. + Sets the home location to that of a ``LocationGlobal`` object. - .. note:: If the GPS values differ heavily from EKF values, setting this value will fail silently. + .. note:: + + If the GPS values differ heavily from EKF values, setting this value will fail silently. """ self.send_mavlink(self.message_factory.command_long_encode( 0, 0, # target system, target component From 92976f299478834d40ea686f00f70b1a29d32df7 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 2 Nov 2015 15:20:54 -0800 Subject: [PATCH 107/475] Fixes reset logic. --- dronekit/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index bebee0537..27353936d 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -431,7 +431,7 @@ def mavlink_thread(): except socket.error as error: if error.errno == ECONNABORTED: errprinter('reestablishing connection after read timeout') - if hasattr(self.master, 'reset'): + if self.master.reset: self.master.reset() else: try: @@ -455,7 +455,7 @@ def mavlink_thread(): except socket.error as error: if error.errno == ECONNABORTED: errprinter('reestablishing connection after send timeout') - if hasattr(self.master, 'reset'): + if self.master.reset: self.master.reset() else: try: From 72d6eff4916cedbf630f6c63ef2e2b8c4a55c2b1 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 2 Nov 2015 15:40:13 -0800 Subject: [PATCH 108/475] Directly adds message listeners to Vehicle object. --- dronekit/__init__.py | 7 +++++-- dronekit/lib/__init__.py | 28 +++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 27353936d..9ab0885d5 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -348,8 +348,11 @@ def mavlink_packet(self, m): for fn in self.message_listeners.get('*', []): fn(self, typ, m) - if self.vehicle.mavrx_callback: - self.vehicle.mavrx_callback(m) + # Downstream. + for fn in self.vehicle.message_listeners.get(typ, []): + fn(self.vehicle, typ, m) + for fn in self.vehicle.message_listeners.get('*', []): + fn(self.vehicle, typ, m) def prepare(self, await_params=False, rate=None): # errprinter('Await heartbeat.') diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 3b5b85aeb..3708a1de6 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -563,6 +563,29 @@ def __init__(self, module): self._waypoints = CommandSequence(self.__module) self.wpts_dirty = False + # Attaches message listeners. + self.message_listeners = dict() + + def on_message(self, name, fn): + """ + Adds a message listener. + """ + name = str(name) + if name not in self.message_listeners: + self.message_listeners[name] = [] + if fn not in self.message_listeners[name]: + self.message_listeners[name].append(fn) + + def remove_message_listener(self, name, fn): + """ + Removes a message listener. + """ + name = str(name) + if name in self.message_listeners: + self.message_listeners[name].remove(fn) + if len(self.message_listeners[name]) == 0: + del self.message_listeners[name] + def close(self): """ Call ``Vehicle.close()`` before exiting scripts to ensure that all messages have been uploaded/sent: @@ -878,11 +901,6 @@ def wait_init(self): time.sleep(pollinterval) raise APIException("Vehicle did not complete initialization") - def on_message(self, name, fn): - def handler(state, name, m): - return fn(self, name, m) - return self.__module.on_message(name, handler) - class Parameters(HasObservers): """ This object is used to get and set the values of named parameters for a vehicle. See the following links for information about From ed3c469f5178b5510624c889aa73de166fc1270f Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 2 Nov 2015 15:42:24 -0800 Subject: [PATCH 109/475] Removes mavlinkrx callback. --- dronekit/lib/__init__.py | 46 ---------------------------------------- tests/sitl/test_115.py | 4 ++-- 2 files changed, 2 insertions(+), 48 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 3708a1de6..bc9758a72 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -792,52 +792,6 @@ def parameters(self): """ return self._parameters - def unset_mavlink_callback(self): - """ - Clears the asynchronous notification added by :py:func:`set_mavlink_callback `. - - The code snippet below shows how to set, then clear, a MAVLink callback function. - - .. code:: python - - # Set MAVLink callback handler (after getting Vehicle instance) - vehicle.set_mavlink_callback(mavrx_debug_handler) - - # Remove the MAVLink callback handler. Callback will not be - # called after this point. - vehicle.unset_mavlink_callback() - """ - self.mavrx_callback = None - - def set_mavlink_callback(self, callback): - """ - Provides asynchronous notification when any MAVLink packet is received by this vehicle. - - Only a single callback can be set. :py:func:`unset_mavlink_callback ` removes the callback. - - .. tip:: - - This method is implemented - but we hope you don't need it. - - Because of the asynchronous attribute/waypoint/parameter notifications there should be no need for - API clients to see raw MAVLink. Please provide feedback if we missed a use-case. - - The code snippet below shows how to set a "demo" callback function as the callback handler: - - .. code:: python - - # Demo callback handler for raw MAVLink messages - def mavrx_debug_handler(message): - print "Received", message - - # Set MAVLink callback handler (after getting Vehicle instance) - vehicle.set_mavlink_callback(mavrx_debug_handler) - - :param callback: The callback function to be invoked when a raw MAVLink message is received. - - """ - self.mavrx_callback = callback - def send_mavlink(self, message): """ This method is used to send raw MAVLink "custom messages" to the vehicle. diff --git a/tests/sitl/test_115.py b/tests/sitl/test_115.py index 7437b2d6e..ed5b0b1f9 100644 --- a/tests/sitl/test_115.py +++ b/tests/sitl/test_115.py @@ -15,7 +15,7 @@ def mavlink_callback(*args): mavlink_callback.count = 0 # Set the callback. - v.set_mavlink_callback(mavlink_callback) + v.on_message('*', mavlink_callback) # Change the vehicle into STABILIZE mode v.mode = VehicleMode("STABILIZE") @@ -26,7 +26,7 @@ def mavlink_callback(*args): assert mavlink_callback.count > 0 # Unset the callback. - v.unset_mavlink_callback() + v.remove_message_listener('*', mavlink_callback) savecount = mavlink_callback.count # Disarm. A callback of None should not throw errors From 66c4e34612de54dd18a586c26adc3db0c232f8ff Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 2 Nov 2015 16:34:31 -0800 Subject: [PATCH 110/475] Adds all non-trivial values to Vehicle directly. --- dronekit/__init__.py | 145 +++------------------------------- dronekit/lib/__init__.py | 164 +++++++++++++++++++++++++++++++++++---- 2 files changed, 160 insertions(+), 149 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 9ab0885d5..e4c17ead6 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -87,99 +87,6 @@ def decorator(fn): self.on_message(name, fn) return decorator - self.status_printer = None - - @message_default('STATUSTEXT') - def listener(self, name, m): - if self.status_printer: - self.status_printer(re.sub(r'(^|\n)', '>>> ', m.text.rstrip())) - - self.lat = None - self.lon = None - self.alt = None - self.vx = None - self.vy = None - self.vz = None - - @message_default('GLOBAL_POSITION_INT') - def listener(self, name, m): - (self.lat, self.lon) = (m.lat / 1.0e7, m.lon / 1.0e7) - (self.vx, self.vy, self.vz) = (m.vx / 100.0, m.vy / 100.0, m.vz / 100.0) - self._notify_attribute_listeners('location', 'velocity') - - self.north = None - self.east = None - self.down = None - - @message_default('LOCAL_POSITION_NED') - def listener(self, name, m): - self.north = m.x - self.east = m.y - self.down = m.z - self._notify_attribute_listeners('local_position') - - @message_default('GPS_RAW') - def listener(self, name, m): - # (self.lat, self.lon) = (m.lat, m.lon) - # self.__on_change('location') - # better to just use global position int - pass - - self.eph = None - self.epv = None - self.satellites_visible = None - self.fix_type = None # FIXME support multiple GPSs per vehicle - possibly by using componentId - - @message_default('GPS_RAW_INT') - def listener(self, name, m): - # (self.lat, self.lon) = (m.lat / 1.0e7, m.lon / 1.0e7) - self.eph = m.eph - self.epv = m.epv - self.satellites_visible = m.satellites_visible - self.fix_type = m.fix_type - self._notify_attribute_listeners('gps_0') - - self.heading = None - # self.alt = None - self.airspeed = None - self.groundspeed = None - - @message_default('VFR_HUD') - def listener(self, name, m): - self.heading = m.heading - self.alt = m.alt - self.airspeed = m.airspeed - self.groundspeed = m.groundspeed - self._notify_attribute_listeners('location', 'airspeed', 'groundspeed') - - self.pitch = None - self.yaw = None - self.roll = None - self.pitchspeed = None - self.yawspeed = None - self.rollspeed = None - - @message_default('ATTITUDE') - def listener(self, name, m): - self.pitch = m.pitch - self.yaw = m.yaw - self.roll = m.roll - self.pitchspeed = m.pitchspeed - self.yawspeed = m.yawspeed - self.rollspeed = m.rollspeed - self._notify_attribute_listeners('attitude') - - self.voltage = -1 - self.current = -1 - self.level = -1 - - @message_default('SYS_STATUS') - def listener(self, name, m): - self.voltage = m.voltage_battery - self.current = m.current_battery - self.level = m.battery_remaining - self._notify_attribute_listeners('battery') - self.flightmode = 'AUTO' self.armed = False self.system_status = None @@ -197,44 +104,6 @@ def listener(self, name, m): def listener(self, name, m): self.last_waypoint = max(m.seq - 1, 0) - self.rc_readback = {} - - @message_default('RC_CHANNELS_RAW') - def listener(self, name, m): - def set(chnum, v): - '''Private utility for handling rc channel messages''' - # use port to allow ch nums greater than 8 - self.rc_readback[str(m.port * 8 + chnum)] = v - - set(1, m.chan1_raw) - set(2, m.chan2_raw) - set(3, m.chan3_raw) - set(4, m.chan4_raw) - set(5, m.chan5_raw) - set(6, m.chan6_raw) - set(7, m.chan7_raw) - set(8, m.chan8_raw) - - self.mount_pitch = None - self.mount_yaw = None - self.mount_roll = None - - @message_default('MOUNT_STATUS') - def listener(self, name, m): - self.mount_pitch = m.pointing_a / 100 - self.mount_roll = m.pointing_b / 100 - self.mount_yaw = m.pointing_c / 100 - self._notify_attribute_listeners('mount') - - self.rngfnd_distance = None - self.rngfnd_voltage = None - - @message_default('RANGEFINDER') - def listener(self, name, m): - self.rngfnd_distance = m.distance - self.rngfnd_voltage = m.voltage - self._notify_attribute_listeners('rangefinder') - self.ekf_ok = False @message_default('EKF_STATUS_REPORT') @@ -256,6 +125,8 @@ def listener(self, name, m): self._notify_attribute_listeners('ekf_ok') + self.vehicle = self.vehicle_class(self) + def fetch(self): """ Fetch waypoints. @@ -360,8 +231,6 @@ def prepare(self, await_params=False, rate=None): # invalid MAVLink prefix '73' # invalid MAVLink prefix '13' - self.vehicle = self.vehicle_class(self) - params = type('PState',(object,),{ "mav_param_count": -1, "mav_param_set": [], @@ -579,7 +448,7 @@ def mavlink_thread(): time.sleep(0.1) # Await GPS lock - while self.fix_type == None: + while self.vehicle._fix_type == None: time.sleep(0.1) def close(self): @@ -591,6 +460,12 @@ def close(self): def connect(ip, await_params=False, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200): state = MPFakeState(mavutil.mavlink_connection(ip, baud=baud), vehicle_class=vehicle_class) - state.status_printer = status_printer + + if status_printer: + print('ok') + @state.vehicle.message_listener('STATUSTEXT') + def listener(self, name, m): + status_printer(re.sub(r'(^|\n)', '>>> ', m.text.rstrip())) + state.prepare(await_params=await_params, rate=rate) return state.vehicle diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index bc9758a72..b3b28746b 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1,6 +1,6 @@ # DroneAPI module -import threading, time, math +import threading, time, math, copy import CloudClient from pymavlink import mavutil @@ -566,6 +566,142 @@ def __init__(self, module): # Attaches message listeners. self.message_listeners = dict() + self._lat = None + self._lon = None + self._vx = None + self._vy = None + self._vz = None + + @self.message_listener('GLOBAL_POSITION_INT') + def listener(self, name, m): + (self._lat, self._lon) = (m.lat / 1.0e7, m.lon / 1.0e7) + self.notify_observers('location') + (self._vx, self._vy, self._vz) = (m.vx / 100.0, m.vy / 100.0, m.vz / 100.0) + self.notify_observers('velocity') + + self._north = None + self._east = None + self._down = None + + @self.message_listener('LOCAL_POSITION_NED') + def listener(self, name, m): + self._north = m.x + self._east = m.y + self._down = m.z + self.notify_observers('local_position') + + self._pitch = None + self._yaw = None + self._roll = None + self._pitchspeed = None + self._yawspeed = None + self._rollspeed = None + + @self.message_listener('ATTITUDE') + def listener(self, name, m): + self._pitch = m.pitch + self._yaw = m.yaw + self._roll = m.roll + self._pitchspeed = m.pitchspeed + self._yawspeed = m.yawspeed + self._rollspeed = m.rollspeed + self.notify_observers('attitude') + + self._heading = None + self._alt = None + self._airspeed = None + self._groundspeed = None + + @self.message_listener('VFR_HUD') + def listener(self, name, m): + self._heading = m.heading + self.notify_observers('heading') + self._alt = m.alt + self.notify_observers('location') + self._airspeed = m.airspeed + self.notify_observers('airspeed') + self._groundspeed = m.groundspeed + self.notify_observers('groundspeed') + + self._rngfnd_distance = None + self._rngfnd_voltage = None + + @self.message_listener('RANGEFINDER') + def listener(self, name, m): + self._rngfnd_distance = m.distance + self._rngfnd_voltage = m.voltage + self.notify_observers('rangefinder') + + self._mount_pitch = None + self._mount_yaw = None + self._mount_roll = None + + @self.message_listener('MOUNT_STATUS') + def listener(self, name, m): + self._mount_pitch = m.pointing_a / 100 + self._mount_roll = m.pointing_b / 100 + self._mount_yaw = m.pointing_c / 100 + self.notify_observers('mount') + + self._rc_readback = {} + + @self.message_listener('RC_CHANNELS_RAW') + def listener(self, name, m): + def set_rc(chnum, v): + '''Private utility for handling rc channel messages''' + # use port to allow ch nums greater than 8 + self._rc_readback[str(m.port * 8 + chnum)] = v + + set_rc(1, m.chan1_raw) + set_rc(2, m.chan2_raw) + set_rc(3, m.chan3_raw) + set_rc(4, m.chan4_raw) + set_rc(5, m.chan5_raw) + set_rc(6, m.chan6_raw) + set_rc(7, m.chan7_raw) + set_rc(8, m.chan8_raw) + + self._voltage = None + self._current = None + self._level = None + + @self.message_listener('SYS_STATUS') + def listener(self, name, m): + self._voltage = m.voltage_battery + self._current = m.current_battery + self._level = m.battery_remaining + self.notify_observers('battery') + + self._eph = None + self._epv = None + self._satellites_visible = None + self._fix_type = None # FIXME support multiple GPSs per vehicle - possibly by using componentId + + @self.message_listener('GPS_RAW_INT') + def listener(self, name, m): + self._eph = m.eph + self._epv = m.epv + self._satellites_visible = m.satellites_visible + self._fix_type = m.fix_type + self.notify_observers('gps_0') + + def message_listener(self, name): + """ + Decorator for default message handlers. + + .. code:: python + @vehicle.message_listener('HEARTBEAT') + def my_method(self, name, msg): + pass + """ + def decorator(fn): + if isinstance(name, list): + for n in name: + self.on_message(n, fn) + else: + self.on_message(name, fn) + return decorator + def on_message(self, name, fn): """ Adds a message listener. @@ -646,30 +782,30 @@ def mode(self, v): @property def location(self): # For backward compatibility, this is (itself) a LocationLocal object. - ret = LocationGlobal(self.__module.lat, self.__module.lon, self.__module.alt, is_relative=False) - ret.local_frame = LocationLocal(self.__module.north, self.__module.east, self.__module.down) - ret.global_frame = LocationGlobal(self.__module.lat, self.__module.lon, self.__module.alt, is_relative=False) + ret = LocationGlobal(self._lat, self._lon, self._alt, is_relative=False) + ret.local_frame = LocationLocal(self._north, self._east, self._down) + ret.global_frame = LocationGlobal(self._lat, self._lon, self._alt, is_relative=False) return ret @property def battery(self): - return Battery(self.__module.voltage, self.__module.current, self.__module.level) + return Battery(self._voltage, self._current, self._level) @property def rangefinder(self): - return Rangefinder(self.__module.rngfnd_distance, self.__module.rngfnd_voltage) + return Rangefinder(self._rngfnd_distance, self._rngfnd_voltage) @property def velocity(self): - return [ self.__module.vx, self.__module.vy, self.__module.vz ] + return [ self._vx, self._vy, self._vz ] @property def attitude(self): - return Attitude(self.__module.pitch, self.__module.yaw, self.__module.roll) + return Attitude(self._pitch, self._yaw, self._roll) @property def gps_0(self): - return GPSInfo(self.__module.eph, self.__module.epv, self.__module.fix_type, self.__module.satellites_visible) + return GPSInfo(self._eph, self._epv, self._fix_type, self._satellites_visible) @property def armed(self): @@ -688,19 +824,19 @@ def system_status(self): @property def heading(self): - return self.__module.heading + return self._heading @property def groundspeed(self): - return self.__module.groundspeed + return self._groundspeed @property def airspeed(self): - return self.__module.airspeed + return self._airspeed @property def mount_status(self): - return [ self.__module.mount_pitch, self.__module.mount_yaw, self.__module.mount_roll ] + return [ self._mount_pitch, self._mount_yaw, self._mount_roll ] @property def ekf_ok(self): @@ -721,7 +857,7 @@ def channel_override(self, newch): @property def channel_readback(self): - return self.__module.rc_readback + return copy.copy(self._rc_readback) @property def home_location(self): From a55b9b0ca3d5eb3ebed751adb31e21763b098ce5 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 2 Nov 2015 17:20:15 -0800 Subject: [PATCH 111/475] Moves over all message listeners. --- dronekit/__init__.py | 85 +--------------------------------------- dronekit/lib/__init__.py | 50 ++++++++++++++++++++--- 2 files changed, 45 insertions(+), 90 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index e4c17ead6..24f452abc 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -7,9 +7,7 @@ import re import dronekit.lib from pymavlink import mavutil, mavwp -from Queue import Empty -from pymavlink.dialects.v10 import ardupilotmega -from Queue import Queue +from Queue import Queue, Empty from threading import Thread import types @@ -72,59 +70,6 @@ def __init__(self, master, vehicle_class=Vehicle): self.wp_loaded = True self.wp_uploaded = None - # Attaches message listeners. - self.message_listeners = dict() - - def message_default(name): - """ - Decorator for default message handlers. - """ - def decorator(fn): - if isinstance(name, list): - for n in name: - self.on_message(n, fn) - else: - self.on_message(name, fn) - return decorator - - self.flightmode = 'AUTO' - self.armed = False - self.system_status = None - - @message_default('HEARTBEAT') - def listener(self, name, m): - self.armed = (m.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED) != 0 - self.flightmode = {v: k for k, v in self.master.mode_mapping().items()}[m.custom_mode] - self.system_status = m.system_status - self._notify_attribute_listeners('mode', 'armed') - - self.last_waypoint = 0 - - @message_default(['WAYPOINT_CURRENT', 'MISSION_CURRENT']) - def listener(self, name, m): - self.last_waypoint = max(m.seq - 1, 0) - - self.ekf_ok = False - - @message_default('EKF_STATUS_REPORT') - def listener(self, name, m): - # legacy check for dronekit-python for solo - # use same check that ArduCopter::system.pde::position_ok() is using - - # boolean: EKF's horizontal position (absolute) estimate is good - status_poshorizabs = (m.flags & ardupilotmega.EKF_POS_HORIZ_ABS) > 0 - # boolean: EKF is in constant position mode and does not know it's absolute or relative position - status_constposmode = m.flags & ardupilotmega.EKF_CONST_POS_MODE > 0 - # boolean: EKF's predicted horizontal position (absolute) estimate is good - status_predposhorizabs = (m.flags & ardupilotmega.EKF_PRED_POS_HORIZ_ABS) > 0 - - if self.armed: - self.ekf_ok = status_poshorizabs and not status_constposmode - else: - self.ekf_ok = status_poshorizabs or status_predposhorizabs - - self._notify_attribute_listeners('ekf_ok') - self.vehicle = self.vehicle_class(self) def fetch(self): @@ -190,35 +135,9 @@ def __on_change(self, *args): def _notify_attribute_listeners(self, *args): return self.__on_change(*args) - def on_message(self, name, fn): - """ - Adds a message listener. - """ - name = str(name) - if name not in self.message_listeners: - self.message_listeners[name] = [] - if fn not in self.message_listeners[name]: - self.message_listeners[name].append(fn) - - def remove_message_listener(self, name, fn): - """ - Removes a message listener. - """ - name = str(name) - if name in self.message_listeners: - self.message_listeners[name].remove(fn) - if len(self.message_listeners[name]) == 0: - del self.message_listeners[name] - def mavlink_packet(self, m): typ = m.get_type() - # Call message listeners. - for fn in self.message_listeners.get(typ, []): - fn(self, typ, m) - for fn in self.message_listeners.get('*', []): - fn(self, typ, m) - # Downstream. for fn in self.vehicle.message_listeners.get(typ, []): fn(self.vehicle, typ, m) @@ -390,8 +309,6 @@ def mavlink_thread(): self.master.waypoint_request_send(msg.seq + 1) else: self.wp_loaded = True - if msg.get_type() in ["WAYPOINT_CURRENT", "MISSION_CURRENT"]: - self.last_waypoint = msg.seq # Waypoint send to master if self.wp_uploaded != None and msg.get_type() in ["WAYPOINT_REQUEST", "MISSION_REQUEST"]: diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index b3b28746b..98a481765 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -2,7 +2,7 @@ import threading, time, math, copy import CloudClient - +from pymavlink.dialects.v10 import ardupilotmega from pymavlink import mavutil """ @@ -685,6 +685,39 @@ def listener(self, name, m): self._fix_type = m.fix_type self.notify_observers('gps_0') + self._last_waypoint = 0 + + @self.message_listener(['WAYPOINT_CURRENT', 'MISSION_CURRENT']) + def listener(self, name, m): + self._last_waypoint = m.seq + + self._ekf_poshorizabs = False + self._ekf_constposmode = False + self._ekf_predposhorizabs = False + + @self.message_listener('EKF_STATUS_REPORT') + def listener(self, name, m): + # boolean: EKF's horizontal position (absolute) estimate is good + self._ekf_poshorizabs = (m.flags & ardupilotmega.EKF_POS_HORIZ_ABS) > 0 + # boolean: EKF is in constant position mode and does not know it's absolute or relative position + self._ekf_constposmode = (m.flags & ardupilotmega.EKF_CONST_POS_MODE) > 0 + # boolean: EKF's predicted horizontal position (absolute) estimate is good + self._ekf_predposhorizabs = (m.flags & ardupilotmega.EKF_PRED_POS_HORIZ_ABS) > 0 + + self.notify_observers('ekf_ok') + + self._flightmode = 'AUTO' + self._armed = False + self._system_status = None + + @self.message_listener('HEARTBEAT') + def listener(self, name, m): + self._armed = (m.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED) != 0 + self.notify_observers('armed') + self._flightmode = {v: k for k, v in self.__module.master.mode_mapping().items()}[m.custom_mode] + self._system_status = m.system_status + self.notify_observers('mode') + def message_listener(self, name): """ Decorator for default message handlers. @@ -772,7 +805,7 @@ def mode(self): def __get_mode(self): """Private method to read current vehicle mode without polling""" - return VehicleMode(self.__module.flightmode) + return VehicleMode(self._flightmode) @mode.setter def mode(self, v): @@ -809,7 +842,7 @@ def gps_0(self): @property def armed(self): - return self.__module.armed + return self._armed @armed.setter def armed(self, value): @@ -820,7 +853,7 @@ def armed(self, value): @property def system_status(self): - return self.__module.system_status + return self._system_status @property def heading(self): @@ -840,7 +873,12 @@ def mount_status(self): @property def ekf_ok(self): - return self.__module.ekf_ok + # legacy check for dronekit-python for solo + # use same check that ArduCopter::system.pde::position_ok() is using + if self.armed: + return self._ekf_poshorizabs and not self._ekf_constposmode + else: + return self._ekf_poshorizabs or self._ekf_predposhorizabs @property def channel_override(self): @@ -1260,7 +1298,7 @@ def next(self): """ Get the currently active waypoint number. """ - return self.__module.last_waypoint + return self._last_waypoint @next.setter def next(self, index): From 76b14be8353199295d7503bb11ec3b19f25d1ded Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 2 Nov 2015 18:00:09 -0800 Subject: [PATCH 112/475] Reimplements waypoint tracking on Vehicle. --- dronekit/__init__.py | 53 ---------------------- dronekit/lib/__init__.py | 95 +++++++++++++++++++++++++++------------- 2 files changed, 65 insertions(+), 83 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 24f452abc..837c77518 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -65,32 +65,8 @@ def __init__(self, master, vehicle_class=Vehicle): # Parameters self.mav_param = {} - # waypoints - self.wploader = mavwp.MAVWPLoader() - self.wp_loaded = True - self.wp_uploaded = None - self.vehicle = self.vehicle_class(self) - def fetch(self): - """ - Fetch waypoints. - """ - self.wp_loaded = False - self.master.waypoint_request_list_send() - - def send_all_waypoints(self): - """ - Send waypoints to master. - """ - self.master.waypoint_clear_all_send() - if self.wploader.count() > 0: - self.wp_uploaded = [False]*self.wploader.count() - self.master.waypoint_count_send(self.wploader.count()) - while False in self.wp_uploaded: - time.sleep(0.1) - self.wp_uploaded = None - def fix_targets(self, message): pass # """Set correct target IDs for our vehicle""" @@ -289,35 +265,6 @@ def mavlink_thread(): import traceback traceback.print_exc() - # Waypoint receive - if not self.wp_loaded: - if msg.get_type() in ['WAYPOINT_COUNT','MISSION_COUNT']: - self.wploader.clear() - self.wploader.expected_count = msg.count - self.master.waypoint_request_send(0) - if msg.get_type() in ['WAYPOINT', 'MISSION_ITEM']: - if msg.seq > self.wploader.count(): - # Unexpected waypoint - pass - elif msg.seq < self.wploader.count(): - # Waypoint duplicate - pass - else: - self.wploader.add(msg) - - if msg.seq + 1 < self.wploader.expected_count: - self.master.waypoint_request_send(msg.seq + 1) - else: - self.wp_loaded = True - - # Waypoint send to master - if self.wp_uploaded != None and msg.get_type() in ["WAYPOINT_REQUEST", "MISSION_REQUEST"]: - wp = self.wploader.wp(msg.seq) - wp.target_system = self.target_system - wp.target_component = self.target_component - self.master.mav.send(wp) - self.wp_uploaded[msg.seq] = True - # Heartbeat: armed + mode update if msg.get_type() == 'HEARTBEAT': last_heartbeat_received = time.time() diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 98a481765..5b8619bc4 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -3,7 +3,7 @@ import threading, time, math, copy import CloudClient from pymavlink.dialects.v10 import ardupilotmega -from pymavlink import mavutil +from pymavlink import mavutil, mavwp """ This is the API Reference for the DroneKit-Python API. @@ -560,8 +560,6 @@ def __init__(self, module): self.mavrx_callback = None self.__module = module self._parameters = Parameters(module) - self._waypoints = CommandSequence(self.__module) - self.wpts_dirty = False # Attaches message listeners. self.message_listeners = dict() @@ -718,6 +716,47 @@ def listener(self, name, m): self._system_status = m.system_status self.notify_observers('mode') + # waypoints + self._wploader = mavwp.MAVWPLoader() + self._wp_loaded = True + self._wp_uploaded = None + self._wpts_dirty = False + self._commands = CommandSequence(self.__module) + + @self.message_listener(['WAYPOINT_COUNT','MISSION_COUNT']) + def listener(self, name, msg): + if not self._wp_loaded: + self._wploader.clear() + self._wploader.expected_count = msg.count + module.master.waypoint_request_send(0) + + @self.message_listener(['WAYPOINT', 'MISSION_ITEM']) + def listener(self, name, msg): + if not self._wp_loaded: + if msg.seq > self._wploader.count(): + # Unexpected waypoint + pass + elif msg.seq < self._wploader.count(): + # Waypoint duplicate + pass + else: + self._wploader.add(msg) + + if msg.seq + 1 < self._wploader.expected_count: + module.master.waypoint_request_send(msg.seq + 1) + else: + self._wp_loaded = True + + # Waypoint send to master + @self.message_listener(['WAYPOINT_REQUEST', 'MISSION_REQUEST']) + def listener(self, name, msg): + if self._wp_uploaded != None: + wp = self._wploader.wp(msg.seq) + wp.target_system = module.target_system + wp.target_component = module.target_component + module.master.mav.send(wp) + self._wp_uploaded[msg.seq] = True + def message_listener(self, name): """ Decorator for default message handlers. @@ -777,9 +816,15 @@ def flush(self): This has been replaced by :py:func:`Vehicle.commands.upload() `. """ - if self.wpts_dirty: - self.__module.send_all_waypoints() - self.wpts_dirty = False + if self._wpts_dirty: + self.__module.master.waypoint_clear_all_send() + if self._wploader.count() > 0: + self._wp_uploaded = [False]*self._wploader.count() + self.__module.master.waypoint_count_send(self._wploader.count()) + while False in self._wp_uploaded: + time.sleep(0.1) + self._wp_uploaded = None + self._wpts_dirty = False # # Private sugar methods @@ -957,7 +1002,7 @@ def commands(self): :returns: A :py:class:`CommandSequence` containing the waypoints for this vehicle. """ - return self._waypoints + return self._commands @property def parameters(self): @@ -1192,7 +1237,8 @@ def download(self): The download is asynchronous. Use :py:func:`wait_valid()` to block your thread until the download is complete. ''' self.wait_valid() - self.__module.fetch() + self.__module.vehicle._wp_loaded = False + self.__module.master.waypoint_request_list_send() # BIG FIXME - wait for full wpt download before allowing any of the accessors to work def wait_valid(self): @@ -1202,7 +1248,7 @@ def wait_valid(self): This can be called after :py:func:`download()` to block the thread until the asynchronous download is complete. ''' # FIXME this is a super crufty spin-wait, also we should give the user the option of specifying a timeout - while not self.__module.wp_loaded: + while not self.__module.vehicle._wp_loaded: time.sleep(0.1) def takeoff(self, alt=None): @@ -1254,11 +1300,8 @@ def clear(self): # Add home point again. self.wait_valid() - home = self.__module.wploader.wp(0) - self.__module.wploader.clear() - if home: - self.__module.wploader.add(home, comment='Added by DroneKit') - self.__module.vehicle.wpts_dirty = True + self.__module.vehicle._wploader.clear() + self.__module.vehicle._wpts_dirty = True def add(self, cmd): ''' @@ -1270,8 +1313,8 @@ def add(self, cmd): ''' self.wait_valid() self.__module.fix_targets(cmd) - self.__module.wploader.add(cmd, comment='Added by DroneKit') - self.__module.vehicle.wpts_dirty = True + self.__module.vehicle._wploader.add(cmd, comment = 'Added by DroneAPI') + self.__module.vehicle._wpts_dirty = True def upload(self): """ @@ -1291,14 +1334,14 @@ def count(self): :return: The number of waypoints in the sequence. ''' - return max(self.__module.wploader.count() - 1, 0) + return self.__module.vehicle._wploader.count() @property def next(self): """ Get the currently active waypoint number. """ - return self._last_waypoint + return self.__module.vehicle._last_waypoint @next.setter def next(self, index): @@ -1313,19 +1356,11 @@ def __len__(self): :return: The number of waypoints in the sequence. ''' - return max(self.__module.wploader.count() - 1, 0) + return self.__module.vehicle._wploader.count() def __getitem__(self, index): - if isinstance(index, slice): - return [self[ii] for ii in xrange(*index.indices(len(self)))] - elif isinstance(index, int): - item = self.__module.wploader.wp(index + 1) - if not item: - raise IndexError('Index %s out of range.' % index) - return item - else: - raise TypeError('Invalid argument type.') + return self.__module.vehicle._wploader.wp(index) def __setitem__(self, index, value): - self.__module.wploader.set(value, index + 1) - self.__module.vehicle.wpts_dirty = True + self.__module.vehicle._wploader.set(value, index) + self.__module.vehicle._wpts_dirty = True From 4a170ecf2a79ea8ec1831bd432720dbcd420223e Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 2 Nov 2015 18:47:15 -0800 Subject: [PATCH 113/475] Reimplements heartbeats and waypoints as event loop listeners. --- dronekit/__init__.py | 127 +++++------------------------------- dronekit/lib/__init__.py | 130 ++++++++++++++++++++++++++++++++++--- dronekit/tools/__init__.py | 15 +++-- 3 files changed, 146 insertions(+), 126 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 837c77518..84a0de308 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -6,6 +6,7 @@ import platform import re import dronekit.lib +from dronekit.tools import errprinter from pymavlink import mavutil, mavwp from Queue import Queue, Empty from threading import Thread @@ -25,9 +26,6 @@ LocationLocal = dronekit.lib.LocationLocal CloudClient = dronekit.lib.CloudClient -def errprinter(*args): - print(*args, file=sys.stderr) - class MavWriter(): def __init__(self, queue): self.queue = queue @@ -39,9 +37,6 @@ def read(self): errprinter('writer should not have had a read request') os._exit(43) -def send_heartbeat(master): - master.mav.heartbeat_send(mavutil.mavlink.MAV_TYPE_GCS, mavutil.mavlink.MAV_AUTOPILOT_INVALID, 0, 0, 0) - def request_data_stream_send(master, rate=1): master.mav.request_data_stream_send(master.target_system, master.target_component, mavutil.mavlink.MAV_DATA_STREAM_ALL, rate, 1) @@ -65,6 +60,9 @@ def __init__(self, master, vehicle_class=Vehicle): # Parameters self.mav_param = {} + # Event loop listeners. + self.loop_listeners = [] + self.vehicle = self.vehicle_class(self) def fix_targets(self, message): @@ -79,31 +77,6 @@ def module(self, which): # psyche return self - def param_set(self, name, value, retries=3): - # TODO dumbly reimplement this using timeout loops - # because we should actually be awaiting an ACK of PARAM_VALUE - # changed, but we don't have a proper ack structure, we'll - # instead just wait until the value itself was changed - - name = name.upper() - value = float(value) - success = False - remaining = retries - while True: - self.master.param_set_send(name.upper(), value) - tstart = time.time() - if remaining == 0: - break - remaining -= 1 - while time.time() - tstart < 1: - if name in self.mav_param and self.mav_param[name] == value: - return True - time.sleep(0.1) - - if retries > 0: - errprinter("timeout setting parameter %s to %f" % (name, value)) - return False - def __on_change(self, *args): for a in args: self.vehicle.notify_observers(a) @@ -120,76 +93,34 @@ def mavlink_packet(self, m): for fn in self.vehicle.message_listeners.get('*', []): fn(self.vehicle, typ, m) + def loop_listener(self, fn): + """ + Decorator for event loop. + """ + self.loop_listeners.append(fn) + def prepare(self, await_params=False, rate=None): # errprinter('Await heartbeat.') # TODO this should be more rigious. How to avoid # invalid MAVLink prefix '73' # invalid MAVLink prefix '13' - params = type('PState',(object,),{ - "mav_param_count": -1, - "mav_param_set": [], - "loaded": False, - "start": False, - })() - self.mav_param = {} - self.pstate = params - import atexit self.exiting = False def onexit(): self.exiting = True atexit.register(onexit) - heartbeat_started = False - def mavlink_thread(): # Huge try catch in case we see http://bugs.python.org/issue1856 try: - # Record the time we received the last "new" param. - last_new_param = time.time() - last_heartbeat_sent = 0 - last_heartbeat_received = 0 - - start_duration = 0.2 - repeat_duration = 1 - duration = start_duration - while True: # Downtime time.sleep(0.05) - # Parameter watchdog. - # Check the time duration for last "new" params exceeds watchdog. - if params.start: - if None not in params.mav_param_set: - params.loaded = True - - if not params.loaded and time.time() - last_new_param > duration: - c = 0 - for i, v in enumerate(params.mav_param_set): - if v == None: - self.master.mav.param_request_read_send(self.master.target_system, self.master.target_component, "", i) - c += 1 - if c > 50: - break - duration = repeat_duration - last_new_param = time.time() - - # TODO: Waypoint watching / re-requesting - - # Send 1 heartbeat per second - if time.time() - last_heartbeat_sent > 1: - send_heartbeat(self.master) - last_heartbeat_sent = time.time() - # Timeout after 5 - if heartbeat_started: - if last_heartbeat_received == 0: - last_heartbeat_received = time.time() - elif time.time() - last_heartbeat_received > 5: - # raise Exception('Link timeout, no heartbeat in last 5 seconds') - errprinter('Link timeout, no heartbeat in last 5 seconds') - last_heartbeat_received = time.time() + # Loop listeners. + for fn in self.loop_listeners: + fn(self) while True: try: @@ -241,34 +172,6 @@ def mavlink_thread(): if not msg: break - # Parmater: receive values - if msg.get_type() == 'PARAM_VALUE': - # If we discover a new param count, assume we - # are receiving a new param set. - if params.mav_param_count != msg.param_count: - params.loaded = False - params.start = True - params.mav_param_count = msg.param_count - params.mav_param_set = [None]*msg.param_count - - # Attempt to set the params. We throw an error - # if the index is out of range of the count or - # we lack a param_id. - try: - if msg.param_index < msg.param_count and msg: - if params.mav_param_set[msg.param_index] == None: - last_new_param = time.time() - duration = start_duration - params.mav_param_set[msg.param_index] = msg - self.mav_param[msg.param_id] = msg.param_value - except: - import traceback - traceback.print_exc() - - # Heartbeat: armed + mode update - if msg.get_type() == 'HEARTBEAT': - last_heartbeat_received = time.time() - self.mavlink_packet(msg) except Exception as e: @@ -301,14 +204,14 @@ def mavlink_thread(): # Just retry with persistence to get our first param stream. self.master.param_fetch_all() time.sleep(0.1) - if params.mav_param_count > -1: + if self.vehicle._params_count > -1: break # We now should get parameters streaming in. # We may not get the full set; we leave the logic to mavlink_thread # to determine what params we yet need. Wait if await_params is True. if await_params: - while not params.loaded: + while not self.vehicle._params_loaded: time.sleep(0.1) # Await GPS lock diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 5b8619bc4..9a7c2b10d 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -4,6 +4,7 @@ import CloudClient from pymavlink.dialects.v10 import ardupilotmega from pymavlink import mavutil, mavwp +from dronekit.tools import errprinter """ This is the API Reference for the DroneKit-Python API. @@ -559,7 +560,7 @@ def __init__(self, module): super(Vehicle, self).__init__() self.mavrx_callback = None self.__module = module - self._parameters = Parameters(module) + self._master = module.master # Attaches message listeners. self.message_listeners = dict() @@ -716,7 +717,8 @@ def listener(self, name, m): self._system_status = m.system_status self.notify_observers('mode') - # waypoints + # Waypoints. + self._wploader = mavwp.MAVWPLoader() self._wp_loaded = True self._wp_uploaded = None @@ -756,6 +758,90 @@ def listener(self, name, msg): wp.target_component = module.target_component module.master.mav.send(wp) self._wp_uploaded[msg.seq] = True + + # TODO: Waypoint loop listeners + + # Parameters. + + start_duration = 0.2 + repeat_duration = 1 + + self._params_count = -1 + self._params_set = [] + self._params_loaded = False + self._params_start = False + self._params_map = {} + self._params_last = time.time() # Last new param. + self._params_duration = start_duration + self._parameters = Parameters(self) + + @module.loop_listener + def listener(_): + # Check the time duration for last "new" params exceeds watchdog. + if self._params_start: + if None not in self._params_set: + self._params_loaded = True + + if not self._params_loaded and time.time() - self._params_last > self._params_duration: + c = 0 + for i, v in enumerate(self._params_set): + if v == None: + module.master.mav.param_request_read_send(module.master.target_system, module.master.target_component, '', i) + c += 1 + if c > 50: + break + self._params_duration = repeat_duration + self._params_last = time.time() + + @self.message_listener(['PARAM_VALUE']) + def listener(self, name, msg): + # If we discover a new param count, assume we + # are receiving a new param set. + if self._params_count != msg.param_count: + self._params_loaded = False + self._params_start = True + self._params_count = msg.param_count + self._params_set = [None]*msg.param_count + + # Attempt to set the params. We throw an error + # if the index is out of range of the count or + # we lack a param_id. + try: + if msg.param_index < msg.param_count and msg: + if self._params_set[msg.param_index] == None: + self._params_last = time.time() + self._params_duration = start_duration + self._params_set[msg.param_index] = msg + self._params_map[msg.param_id] = msg.param_value + except: + import traceback + traceback.print_exc() + + # Heartbeats. + + self._heartbeat_started = False + self._heartbeat_lastsent = 0 + self._heartbeat_lastreceived = 0 + + @module.loop_listener + def listener(_): + # Send 1 heartbeat per second + if time.time() - self._heartbeat_lastsent > 1: + module.master.mav.heartbeat_send(mavutil.mavlink.MAV_TYPE_GCS, mavutil.mavlink.MAV_AUTOPILOT_INVALID, 0, 0, 0) + self._heartbeat_lastsent = time.time() + + # And timeout after 5. + if self._heartbeat_started: + if self._heartbeat_lastreceived == 0: + self._heartbeat_lastreceived = time.time() + elif time.time() - self._heartbeat_lastreceived > 5: + # raise Exception('Link timeout, no heartbeat in last 5 seconds') + errprinter('Link timeout, no heartbeat in last 5 seconds') + self._heartbeat_lastreceived = time.time() + + @self.message_listener(['HEARTBEAT']) + def listener(self, name, msg): + self._heartbeat_lastreceived = time.time() def message_listener(self, name): """ @@ -1102,27 +1188,51 @@ class Parameters(HasObservers): https://github.com/dronekit/dronekit-python/issues/107 """ - def __init__(self, module): - self.__module = module + def __init__(self, vehicle): + self._vehicle = vehicle def __getitem__(self, name): self.wait_valid() - return self.__module.mav_param[name] + return self._vehicle._params_map[name] def __setitem__(self, name, value): self.wait_valid() - self.__module.param_set(name, value) + self.set(name, value) def set(self, name, value, retries=3, await_valid=False): if await_valid: self.wait_valid() - return self.__module.param_set(name, value, retries=retries) + + # TODO dumbly reimplement this using timeout loops + # because we should actually be awaiting an ACK of PARAM_VALUE + # changed, but we don't have a proper ack structure, we'll + # instead just wait until the value itself was changed + + name = name.upper() + value = float(value) + success = False + remaining = retries + while True: + self._vehicle._master.param_set_send(name.upper(), value) + tstart = time.time() + if remaining == 0: + break + remaining -= 1 + while time.time() - tstart < 1: + if name in self._vehicle._params_map and self._vehicle._params_map[name] == value: + return True + time.sleep(0.1) + + if retries > 0: + errprinter("timeout setting parameter %s to %f" % (name, value)) + return False def wait_valid(self): - '''Block the calling thread until parameters have been downloaded''' + """ + Block the calling thread until parameters have been downloaded + """ # FIXME this is a super crufty spin-wait, also we should give the user the option of specifying a timeout - pstate = self.__module.pstate - while (pstate.mav_param_count == 0 or len(pstate.mav_param_set) != pstate.mav_param_count) and not self.__module.api.exit: + while self._vehicle._params_count == 0 or len(self._vehicle._params_set) != self._vehicle._params_count: time.sleep(0.200) class Command(mavutil.mavlink.MAVLink_mission_item_message): diff --git a/dronekit/tools/__init__.py b/dronekit/tools/__init__.py index b8088dc00..8b0d9e9c4 100644 --- a/dronekit/tools/__init__.py +++ b/dronekit/tools/__init__.py @@ -1,23 +1,30 @@ +from __future__ import print_function import os -from nose.tools import assert_equals, with_setup +import sys from dronekit_sitl import SITL -sitl = SITL('copter', '3.3-rc5') +sitl = None sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] if 'SITL_SPEEDUP' in os.environ: - sitl_args += ['--speedup', str(os.environ['SITL_SPEEDUP'])] + sitl_args += ['--speedup', str(os.environ['SITL_SPEEDUP'])] if 'SITL_RATE' in os.environ: - sitl_args += ['-r', str(os.environ['SITL_RATE'])] + sitl_args += ['-r', str(os.environ['SITL_RATE'])] def setup_sitl(): + global sitl + sitl = SITL('copter', '3.3-rc5') sitl.launch(sitl_args, await_ready=True, restart=True) def teardown_sitl(): sitl.stop() def with_sitl(fn): + from nose.tools import assert_equals, with_setup @with_setup(setup_sitl, teardown_sitl) def test(*args, **kargs): return fn('tcp:127.0.0.1:5760', *args, **kargs) return test + +def errprinter(*args): + print(*args, file=sys.stderr) From 01b7183d768d349ed06772642eee222bf393634f Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 2 Nov 2015 19:25:54 -0800 Subject: [PATCH 114/475] Merges all handling code into Vehicle. --- dronekit/__init__.py | 125 ++++++++++++--------------------------- dronekit/lib/__init__.py | 113 +++++++++++++++++++++++------------ 2 files changed, 111 insertions(+), 127 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 84a0de308..57c763aa3 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -37,16 +37,11 @@ def read(self): errprinter('writer should not have had a read request') os._exit(43) -def request_data_stream_send(master, rate=1): - master.mav.request_data_stream_send(master.target_system, master.target_component, - mavutil.mavlink.MAV_DATA_STREAM_ALL, rate, 1) - -class MPFakeState: +class MAVHandler: def __init__(self, master, vehicle_class=Vehicle): self.vehicle_class = vehicle_class self.master = master - self.vehicle = None # TODO get rid of "master" object as exposed, # keep it private, expose something smaller for dronekit @@ -57,53 +52,9 @@ def __init__(self, master, vehicle_class=Vehicle): self.target_system = 0 self.target_component = 0 - # Parameters - self.mav_param = {} - - # Event loop listeners. + # Listeners. self.loop_listeners = [] - - self.vehicle = self.vehicle_class(self) - - def fix_targets(self, message): - pass - # """Set correct target IDs for our vehicle""" - # if hasattr(message, 'target_system'): - # message.target_system = self.target_system - # if hasattr(message, 'target_component'): - # message.target_component = self.target_component - - def module(self, which): - # psyche - return self - - def __on_change(self, *args): - for a in args: - self.vehicle.notify_observers(a) - - def _notify_attribute_listeners(self, *args): - return self.__on_change(*args) - - def mavlink_packet(self, m): - typ = m.get_type() - - # Downstream. - for fn in self.vehicle.message_listeners.get(typ, []): - fn(self.vehicle, typ, m) - for fn in self.vehicle.message_listeners.get('*', []): - fn(self.vehicle, typ, m) - - def loop_listener(self, fn): - """ - Decorator for event loop. - """ - self.loop_listeners.append(fn) - - def prepare(self, await_params=False, rate=None): - # errprinter('Await heartbeat.') - # TODO this should be more rigious. How to avoid - # invalid MAVLink prefix '73' - # invalid MAVLink prefix '13' + self.message_listeners = [] import atexit self.exiting = False @@ -125,6 +76,7 @@ def mavlink_thread(): while True: try: msg = self.out_queue.get_nowait() + self.fix_targets(msg) self.master.write(msg) except socket.error as error: if error.errno == ECONNABORTED: @@ -166,13 +118,17 @@ def mavlink_thread(): # If connection reset (closed), stop polling. return except Exception as e: - # TODO debug these. + # TODO this should be more rigious. How to avoid + # invalid MAVLink prefix '73' + # invalid MAVLink prefix '13' # errprinter('mav recv error:', e) msg = None if not msg: break - self.mavlink_packet(msg) + # Message listeners. + for fn in self.message_listeners: + fn(self, msg) except Exception as e: # http://bugs.python.org/issue1856 @@ -181,42 +137,33 @@ def mavlink_thread(): else: raise - t = Thread(target=mavlink_thread) t.daemon = True - t.start() self.mavlink_thread = t - # Wait for first heartbeat. - while True: - try: - self.master.wait_heartbeat() - break - except mavutil.mavlink.MAVError: - continue - heartbeat_started = True - - # Request a list of all parameters. - if rate != None: - request_data_stream_send(self.master, rate=rate) - while True: - # This fn actually rate limits itself to every 2s. - # Just retry with persistence to get our first param stream. - self.master.param_fetch_all() - time.sleep(0.1) - if self.vehicle._params_count > -1: - break + def fix_targets(self, message): + pass + # """Set correct target IDs for our vehicle""" + # if hasattr(message, 'target_system'): + # message.target_system = self.target_system + # if hasattr(message, 'target_component'): + # message.target_component = self.target_component + + def loop_listener(self, fn): + """ + Decorator for event loop. + """ + self.loop_listeners.append(fn) - # We now should get parameters streaming in. - # We may not get the full set; we leave the logic to mavlink_thread - # to determine what params we yet need. Wait if await_params is True. - if await_params: - while not self.vehicle._params_loaded: - time.sleep(0.1) + def message_listener(self, fn): + """ + Decorator for message inputs. + """ + self.message_listeners.append(fn) - # Await GPS lock - while self.vehicle._fix_type == None: - time.sleep(0.1) + def start(self): + if not self.mavlink_thread.is_alive(): + self.mavlink_thread.start() def close(self): # TODO this can block forever if parameters continue to be added @@ -226,13 +173,15 @@ def close(self): self.master.close() def connect(ip, await_params=False, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200): - state = MPFakeState(mavutil.mavlink_connection(ip, baud=baud), vehicle_class=vehicle_class) + socket = mavutil.mavlink_connection(ip, baud=baud) + handler = MAVHandler(socket) + vehicle = vehicle_class(handler) if status_printer: print('ok') - @state.vehicle.message_listener('STATUSTEXT') + @vehicle.message_listener('STATUSTEXT') def listener(self, name, m): status_printer(re.sub(r'(^|\n)', '>>> ', m.text.rstrip())) - state.prepare(await_params=await_params, rate=rate) - return state.vehicle + vehicle.initialize(await_params=await_params, rate=rate) + return vehicle diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 9a7c2b10d..c8dba70fe 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -565,6 +565,14 @@ def __init__(self, module): # Attaches message listeners. self.message_listeners = dict() + @module.message_listener + def listener(_, msg): + typ = msg.get_type() + for fn in self.message_listeners.get(typ, []): + fn(self, typ, msg) + for fn in self.message_listeners.get('*', []): + fn(self, typ, msg) + self._lat = None self._lon = None self._vx = None @@ -723,7 +731,7 @@ def listener(self, name, m): self._wp_loaded = True self._wp_uploaded = None self._wpts_dirty = False - self._commands = CommandSequence(self.__module) + self._commands = CommandSequence(self) @self.message_listener(['WAYPOINT_COUNT','MISSION_COUNT']) def listener(self, name, msg): @@ -916,13 +924,9 @@ def flush(self): # Private sugar methods # - @property - def __master(self): - return self.__module.master - @property def _mode_mapping(self): - return self.__master.mode_mapping() + return self._master.mode_mapping() # # Operations to support the standard API (FIXME - possibly/probably this @@ -941,7 +945,7 @@ def __get_mode(self): @mode.setter def mode(self, v): self.wait_init() # We must know vehicle type before this operation can work - self.__master.set_mode(self._mode_mapping[v.name]) + self._master.set_mode(self._mode_mapping[v.name]) @property def location(self): @@ -978,9 +982,9 @@ def armed(self): @armed.setter def armed(self, value): if value: - self.__master.arducopter_arm() + self._master.arducopter_arm() else: - self.__master.arducopter_disarm() + self._master.arducopter_disarm() @property def system_status(self): @@ -1110,7 +1114,6 @@ def send_mavlink(self, message): :param message: A ``MAVLink_message`` instance, created using :py:func:`message_factory `. There is need to specify the system id, component id or sequence number of messages as the API will set these appropriately. """ - self.__module.fix_targets(message) self.__module.master.mav.send(message) @property @@ -1160,6 +1163,42 @@ def wait_init(self): time.sleep(pollinterval) raise APIException("Vehicle did not complete initialization") + def initialize(self, await_params=False, rate=None): + self.__module.start() + + # Wait for first heartbeat. + while True: + try: + self._master.wait_heartbeat() + break + except mavutil.mavlink.MAVError: + continue + self._heartbeat_started = True + + # Request a list of all parameters. + if rate != None: + self._master.mav.request_data_stream_send(self.__module.target_system, + self.__module.target_component, + mavutil.mavlink.MAV_DATA_STREAM_ALL, rate, 1) + while True: + # This fn actually rate limits itself to every 2s. + # Just retry with persistence to get our first param stream. + self._master.param_fetch_all() + time.sleep(0.1) + if self._params_count > -1: + break + + # We now should get parameters streaming in. + # We may not get the full set; we leave the logic to mavlink_thread + # to determine what params we yet need. Wait if await_params is True. + if await_params: + while not self._params_loaded: + time.sleep(0.1) + + # Await GPS lock + while self._fix_type == None: + time.sleep(0.1) + class Parameters(HasObservers): """ This object is used to get and set the values of named parameters for a vehicle. See the following links for information about @@ -1337,8 +1376,8 @@ class CommandSequence(object): .. todo:: This is a hack. The actual function should be defined here. See https://github.com/dronekit/dronekit-python/issues/64 """ - def __init__(self, module): - self.__module = module + def __init__(self, vehicle): + self._vehicle = vehicle def download(self): ''' @@ -1347,8 +1386,8 @@ def download(self): The download is asynchronous. Use :py:func:`wait_valid()` to block your thread until the download is complete. ''' self.wait_valid() - self.__module.vehicle._wp_loaded = False - self.__module.master.waypoint_request_list_send() + self._vehicle._wp_loaded = False + self._vehicle._master.waypoint_request_list_send() # BIG FIXME - wait for full wpt download before allowing any of the accessors to work def wait_valid(self): @@ -1358,7 +1397,7 @@ def wait_valid(self): This can be called after :py:func:`download()` to block the thread until the asynchronous download is complete. ''' # FIXME this is a super crufty spin-wait, also we should give the user the option of specifying a timeout - while not self.__module.vehicle._wp_loaded: + while not self._vehicle._wp_loaded: time.sleep(0.1) def takeoff(self, alt=None): @@ -1366,11 +1405,10 @@ def takeoff(self, alt=None): altitude = float(alt) if math.isnan(alt) or math.isinf(alt): raise ValueError("Altitude was NaN or Infinity. Please provide a real number") - self.__module.master.mav.command_long_send(self.__module.target_system, - self.__module.target_component, - mavutil.mavlink.MAV_CMD_NAV_TAKEOFF, - 0, 0, 0, 0, 0, 0, 0, - altitude) + self._vehicle._master.mav.command_long_send(0, 0, + mavutil.mavlink.MAV_CMD_NAV_TAKEOFF, + 0, 0, 0, 0, 0, 0, 0, + altitude) def goto(self, l): ''' @@ -1393,13 +1431,11 @@ def goto(self, l): frame = mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT else: frame = mavutil.mavlink.MAV_FRAME_GLOBAL - self.__module.master.mav.mission_item_send(self.__module.target_system, - self.__module.target_component, - 0, - frame, - mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, - 2, 0, 0, 0, 0, 0, - l.lat, l.lon, l.alt) + self._vehicle._master.mav.mission_item_send(0, 0, 0, + frame, + mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, + 2, 0, 0, 0, 0, 0, + l.lat, l.lon, l.alt) def clear(self): ''' @@ -1410,8 +1446,8 @@ def clear(self): # Add home point again. self.wait_valid() - self.__module.vehicle._wploader.clear() - self.__module.vehicle._wpts_dirty = True + self._vehicle._wploader.clear() + self._vehicle._wpts_dirty = True def add(self, cmd): ''' @@ -1422,9 +1458,8 @@ def add(self, cmd): :param Command cmd: The command to be added. ''' self.wait_valid() - self.__module.fix_targets(cmd) - self.__module.vehicle._wploader.add(cmd, comment = 'Added by DroneAPI') - self.__module.vehicle._wpts_dirty = True + self._vehicle._wploader.add(cmd, comment = 'Added by DroneAPI') + self._vehicle._wpts_dirty = True def upload(self): """ @@ -1444,21 +1479,21 @@ def count(self): :return: The number of waypoints in the sequence. ''' - return self.__module.vehicle._wploader.count() + return self._vehicle._wploader.count() @property def next(self): """ Get the currently active waypoint number. """ - return self.__module.vehicle._last_waypoint + return self._vehicle._last_waypoint @next.setter def next(self, index): """ Set a new ``next`` waypoint for the vehicle. """ - self.__module.master.waypoint_set_current_send(index + 1) + self._vehicle._master.waypoint_set_current_send(index) def __len__(self): ''' @@ -1466,11 +1501,11 @@ def __len__(self): :return: The number of waypoints in the sequence. ''' - return self.__module.vehicle._wploader.count() + return self._vehicle._wploader.count() def __getitem__(self, index): - return self.__module.vehicle._wploader.wp(index) + return self._vehicle._wploader.wp(index) def __setitem__(self, index, value): - self.__module.vehicle._wploader.set(value, index) - self.__module.vehicle._wpts_dirty = True + self._vehicle._wploader.set(value, index) + self._vehicle._wpts_dirty = True From be1b45a0ca7d6204f93bf01558bff186b1f8498b Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 2 Nov 2015 19:36:05 -0800 Subject: [PATCH 115/475] Reconfigures await_params and handler logic. --- dronekit/__init__.py | 19 ++++--- dronekit/lib/__init__.py | 104 +++++++++++++++++++-------------------- 2 files changed, 60 insertions(+), 63 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 57c763aa3..36c68935a 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -142,12 +142,11 @@ def mavlink_thread(): self.mavlink_thread = t def fix_targets(self, message): - pass - # """Set correct target IDs for our vehicle""" - # if hasattr(message, 'target_system'): - # message.target_system = self.target_system - # if hasattr(message, 'target_component'): - # message.target_component = self.target_component + """Set correct target IDs for our vehicle""" + if hasattr(message, 'target_system'): + message.target_system = self.target_system + if hasattr(message, 'target_component'): + message.target_component = self.target_component def loop_listener(self, fn): """ @@ -173,15 +172,15 @@ def close(self): self.master.close() def connect(ip, await_params=False, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200): - socket = mavutil.mavlink_connection(ip, baud=baud) - handler = MAVHandler(socket) + handler = MAVHandler(mavutil.mavlink_connection(ip, baud=baud)) vehicle = vehicle_class(handler) if status_printer: - print('ok') @vehicle.message_listener('STATUSTEXT') def listener(self, name, m): status_printer(re.sub(r'(^|\n)', '>>> ', m.text.rstrip())) - vehicle.initialize(await_params=await_params, rate=rate) + vehicle.initialize(rate=rate) + if await_params: + vehicle.wait_ready() return vehicle diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index c8dba70fe..0bf992441 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -556,21 +556,21 @@ class Vehicle(HasObservers): """ - def __init__(self, module): + def __init__(self, handler): super(Vehicle, self).__init__() - self.mavrx_callback = None - self.__module = module - self._master = module.master + + self._handler = handler + self._master = handler.master # Attaches message listeners. - self.message_listeners = dict() + self._message_listeners = dict() - @module.message_listener + @handler.message_listener def listener(_, msg): typ = msg.get_type() - for fn in self.message_listeners.get(typ, []): + for fn in self._message_listeners.get(typ, []): fn(self, typ, msg) - for fn in self.message_listeners.get('*', []): + for fn in self._message_listeners.get('*', []): fn(self, typ, msg) self._lat = None @@ -721,7 +721,7 @@ def listener(self, name, m): def listener(self, name, m): self._armed = (m.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED) != 0 self.notify_observers('armed') - self._flightmode = {v: k for k, v in self.__module.master.mode_mapping().items()}[m.custom_mode] + self._flightmode = {v: k for k, v in self._master.mode_mapping().items()}[m.custom_mode] self._system_status = m.system_status self.notify_observers('mode') @@ -738,7 +738,7 @@ def listener(self, name, msg): if not self._wp_loaded: self._wploader.clear() self._wploader.expected_count = msg.count - module.master.waypoint_request_send(0) + self._master.waypoint_request_send(0) @self.message_listener(['WAYPOINT', 'MISSION_ITEM']) def listener(self, name, msg): @@ -753,7 +753,7 @@ def listener(self, name, msg): self._wploader.add(msg) if msg.seq + 1 < self._wploader.expected_count: - module.master.waypoint_request_send(msg.seq + 1) + self._master.waypoint_request_send(msg.seq + 1) else: self._wp_loaded = True @@ -762,9 +762,8 @@ def listener(self, name, msg): def listener(self, name, msg): if self._wp_uploaded != None: wp = self._wploader.wp(msg.seq) - wp.target_system = module.target_system - wp.target_component = module.target_component - module.master.mav.send(wp) + handler.fix_targets(wp) + self._master.mav.send(wp) self._wp_uploaded[msg.seq] = True # TODO: Waypoint loop listeners @@ -783,7 +782,7 @@ def listener(self, name, msg): self._params_duration = start_duration self._parameters = Parameters(self) - @module.loop_listener + @handler.loop_listener def listener(_): # Check the time duration for last "new" params exceeds watchdog. if self._params_start: @@ -794,7 +793,7 @@ def listener(_): c = 0 for i, v in enumerate(self._params_set): if v == None: - module.master.mav.param_request_read_send(module.master.target_system, module.master.target_component, '', i) + self._master.mav.param_request_read_send(0, 0, '', i) c += 1 if c > 50: break @@ -831,11 +830,11 @@ def listener(self, name, msg): self._heartbeat_lastsent = 0 self._heartbeat_lastreceived = 0 - @module.loop_listener + @handler.loop_listener def listener(_): # Send 1 heartbeat per second if time.time() - self._heartbeat_lastsent > 1: - module.master.mav.heartbeat_send(mavutil.mavlink.MAV_TYPE_GCS, mavutil.mavlink.MAV_AUTOPILOT_INVALID, 0, 0, 0) + self._master.mav.heartbeat_send(mavutil.mavlink.MAV_TYPE_GCS, mavutil.mavlink.MAV_AUTOPILOT_INVALID, 0, 0, 0) self._heartbeat_lastsent = time.time() # And timeout after 5. @@ -873,31 +872,23 @@ def on_message(self, name, fn): Adds a message listener. """ name = str(name) - if name not in self.message_listeners: - self.message_listeners[name] = [] - if fn not in self.message_listeners[name]: - self.message_listeners[name].append(fn) + if name not in self._message_listeners: + self._message_listeners[name] = [] + if fn not in self._message_listeners[name]: + self._message_listeners[name].append(fn) def remove_message_listener(self, name, fn): """ Removes a message listener. """ name = str(name) - if name in self.message_listeners: - self.message_listeners[name].remove(fn) - if len(self.message_listeners[name]) == 0: - del self.message_listeners[name] + if name in self._message_listeners: + self._message_listeners[name].remove(fn) + if len(self._message_listeners[name]) == 0: + del self._message_listeners[name] def close(self): - """ - Call ``Vehicle.close()`` before exiting scripts to ensure that all messages have been uploaded/sent: - - .. code:: python - - # About to exit script - vehicle.close() - """ - return self.__module.close() + return self._handler.close() def flush(self): """ @@ -911,10 +902,10 @@ def flush(self): This has been replaced by :py:func:`Vehicle.commands.upload() `. """ if self._wpts_dirty: - self.__module.master.waypoint_clear_all_send() + self._master.waypoint_clear_all_send() if self._wploader.count() > 0: self._wp_uploaded = [False]*self._wploader.count() - self.__module.master.waypoint_count_send(self._wploader.count()) + self._master.waypoint_count_send(self._wploader.count()) while False in self._wp_uploaded: time.sleep(0.1) self._wp_uploaded = None @@ -939,7 +930,9 @@ def mode(self): return self.__get_mode() def __get_mode(self): - """Private method to read current vehicle mode without polling""" + """ + Private method to read current vehicle mode without polling + """ return VehicleMode(self._flightmode) @mode.setter @@ -1114,7 +1107,7 @@ def send_mavlink(self, message): :param message: A ``MAVLink_message`` instance, created using :py:func:`message_factory `. There is need to specify the system id, component id or sequence number of messages as the API will set these appropriately. """ - self.__module.master.mav.send(message) + self._master.mav.send(message) @property def message_factory(self): @@ -1147,7 +1140,7 @@ def message_factory(self): .. todo:: Check if the standard MAV_CMD messages can be sent this way too, and if so add link. """ - return self.__module.master.mav + return self._master.mav def wait_init(self): """Wait for the vehicle to exit the initializing step""" @@ -1164,7 +1157,7 @@ def wait_init(self): raise APIException("Vehicle did not complete initialization") def initialize(self, await_params=False, rate=None): - self.__module.start() + self._handler.start() # Wait for first heartbeat. while True: @@ -1175,11 +1168,18 @@ def initialize(self, await_params=False, rate=None): continue self._heartbeat_started = True - # Request a list of all parameters. + # Wait until board has booted. + while True: + if self._flightmode not in [None, 'INITIALISING', 'MAV']: + break + time.sleep(0.1) + + # Initialize data stream. if rate != None: - self._master.mav.request_data_stream_send(self.__module.target_system, - self.__module.target_component, + self._master.mav.request_data_stream_send(0, 0, mavutil.mavlink.MAV_DATA_STREAM_ALL, rate, 1) + + # Ensure initial parameter download has started. while True: # This fn actually rate limits itself to every 2s. # Just retry with persistence to get our first param stream. @@ -1188,16 +1188,14 @@ def initialize(self, await_params=False, rate=None): if self._params_count > -1: break - # We now should get parameters streaming in. - # We may not get the full set; we leave the logic to mavlink_thread - # to determine what params we yet need. Wait if await_params is True. - if await_params: - while not self._params_loaded: - time.sleep(0.1) + def wait_ready(self, *types): + # We now should get parameters streaming in. The loop listener sets _params_loaded. + while not self._params_loaded: + time.sleep(0.1) - # Await GPS lock - while self._fix_type == None: - time.sleep(0.1) + # Await GPS lock. + while self._fix_type == None: + time.sleep(0.1) class Parameters(HasObservers): """ From fa915e804071d207b71692a1bdf585bbeb6e3e6d Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 2 Nov 2015 19:48:38 -0800 Subject: [PATCH 116/475] Removes wait_init. --- dronekit/lib/__init__.py | 27 +++------------------------ 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 0bf992441..8a28c5b7b 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -920,24 +920,17 @@ def _mode_mapping(self): return self._master.mode_mapping() # - # Operations to support the standard API (FIXME - possibly/probably this - # will move into a private dict of getter/setter tuples (invisible to the API consumer). + # Operations to support the standard API. # @property def mode(self): - self.wait_init() # We must know vehicle type before this operation can work - return self.__get_mode() - - def __get_mode(self): - """ - Private method to read current vehicle mode without polling - """ + if not self._flightmode: + return None return VehicleMode(self._flightmode) @mode.setter def mode(self, v): - self.wait_init() # We must know vehicle type before this operation can work self._master.set_mode(self._mode_mapping[v.name]) @property @@ -1142,20 +1135,6 @@ def message_factory(self): """ return self._master.mav - def wait_init(self): - """Wait for the vehicle to exit the initializing step""" - timeout = 30 - pollinterval = 0.2 - for i in range(0, int(timeout / pollinterval)): - # Don't let the user try to fly while the board is still booting - mode = self.__get_mode().name - # print "mode is", mode - if mode != "INITIALISING" and mode != "MAV": - return - - time.sleep(pollinterval) - raise APIException("Vehicle did not complete initialization") - def initialize(self, await_params=False, rate=None): self._handler.start() From ecf83fa70a1dcc98767b4ebb81129c736d95b882 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 2 Nov 2015 20:15:51 -0800 Subject: [PATCH 117/475] Implements await_params in terms of wait_ready. --- dronekit/__init__.py | 2 +- dronekit/lib/__init__.py | 136 +++++++++++++++++++++++---------------- tests/sitl/test_110.py | 22 +++---- 3 files changed, 91 insertions(+), 69 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 36c68935a..ec3ece1f9 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -182,5 +182,5 @@ def listener(self, name, m): vehicle.initialize(rate=rate) if await_params: - vehicle.wait_ready() + vehicle.wait_ready('parameters', 'gps_0') return vehicle diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 8a28c5b7b..f55143912 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -238,7 +238,7 @@ class VehicleMode(object): def mode_callback(self, mode): print "Vehicle Mode", vehicle.mode - vehicle.add_attribute_observer('mode', mode_callback) + vehicle.on_attribute('mode', mode_callback) The code snippet below shows how to change the vehicle mode to AUTO: @@ -274,13 +274,13 @@ def __init__(self): """ Provides callback based notification on attribute changes. - The argument list for observer is ``observer(attr_name)``. + The argument list for observer is ``observer(object, attr_name)``. """ - def add_attribute_observer(self, attr_name, observer): + def on_attribute(self, attr_name, observer): """ - Add an attribute observer. + Add an attribute listener. - The observer callback function is called with the ``attr_name`` argument. + The listener callback function is called with the ``vehicle`` and ``attr_name`` arguments. This can be used to infer the related attribute if the same callback is used for watching several attributes. @@ -289,12 +289,12 @@ def add_attribute_observer(self, attr_name, observer): .. code:: python #Callback to print the location in global and local frames - def location_callback(location): + def location_callback(vehicle, location): print "Location (Global): ", vehicle.location.global_frame print "Location (Local): ", vehicle.location.local_frame #Add observer for the vehicle's current location - vehicle.add_attribute_observer('location', location_callback) + vehicle.on_attribute('location', location_callback) .. note:: Attribute changes will only be published for changes due to some other entity. @@ -313,15 +313,15 @@ def location_callback(location): if not observer in l: l.append(observer) - def remove_attribute_observer(self, attr_name, observer): + def remove_attribute_listener(self, attr_name, observer): """ - Remove an observer. + Remove an attribute listener. For example, the following line would remove a previously added vehicle 'global_frame' observer called location_callback: .. code:: python - vehicle.remove_attribute_observer('global_frame', location_callback) + vehicle.remove_attribute_listener('global_frame', location_callback) :param attr_name: The attribute name that is to have an observer removed. @@ -335,7 +335,7 @@ def remove_attribute_observer(self, attr_name, observer): if len(l) == 0: del self.__observers[attr_name] - def notify_observers(self, attr_name): + def _notify_attribute_listeners(self, attr_name): """ Internal function. Do not use. @@ -343,27 +343,27 @@ def notify_observers(self, attr_name): .. INTERNAL NOTE: (For subclass use only) """ - # print "Notify: " + attr_name - l = self.__observers.get(attr_name) - if l is not None: - for o in l: - try: - o(attr_name) - except TypeError as e: - # This is commonly called by a bad argument list - print("TypeError calling observer: ", e) - except Exception as e: - print("Error calling observer: ", e) - - def remove_all_observers(self): - """ - Internal function. Do not use. + for fn in self.__observers.get(attr_name, []): + fn(self, attr_name) + for fn in self.__observers.get('*', []): + fn(self, attr_name) - This method removes all attached observers. + def attribute_listener(self, name): + """ + Decorator for attribute listeners. - .. INTERNAL NOTE: (For subclass use only) + .. code:: python + @vehicle.attribute_listener('attitude') + def attitude_listener(self, name, msg): + pass """ - self.__observers = {} + def decorator(fn): + if isinstance(name, list): + for n in name: + self.on_attribute(n, fn) + else: + self.on_attribute(name, fn) + return decorator class Vehicle(HasObservers): """ @@ -562,16 +562,19 @@ def __init__(self, handler): self._handler = handler self._master = handler.master + # Cache all updated attributes for wait_ready. + self._ready_attrs = set() + + @self.attribute_listener('*') + def listener(_, name): + self._ready_attrs.add(name) + # Attaches message listeners. self._message_listeners = dict() @handler.message_listener def listener(_, msg): - typ = msg.get_type() - for fn in self._message_listeners.get(typ, []): - fn(self, typ, msg) - for fn in self._message_listeners.get('*', []): - fn(self, typ, msg) + self._notify_message_listeners(msg.get_type(), msg) self._lat = None self._lon = None @@ -582,9 +585,9 @@ def listener(_, msg): @self.message_listener('GLOBAL_POSITION_INT') def listener(self, name, m): (self._lat, self._lon) = (m.lat / 1.0e7, m.lon / 1.0e7) - self.notify_observers('location') + self._notify_attribute_listeners('location') (self._vx, self._vy, self._vz) = (m.vx / 100.0, m.vy / 100.0, m.vz / 100.0) - self.notify_observers('velocity') + self._notify_attribute_listeners('velocity') self._north = None self._east = None @@ -595,7 +598,7 @@ def listener(self, name, m): self._north = m.x self._east = m.y self._down = m.z - self.notify_observers('local_position') + self._notify_attribute_listeners('local_position') self._pitch = None self._yaw = None @@ -612,7 +615,7 @@ def listener(self, name, m): self._pitchspeed = m.pitchspeed self._yawspeed = m.yawspeed self._rollspeed = m.rollspeed - self.notify_observers('attitude') + self._notify_attribute_listeners('attitude') self._heading = None self._alt = None @@ -622,13 +625,13 @@ def listener(self, name, m): @self.message_listener('VFR_HUD') def listener(self, name, m): self._heading = m.heading - self.notify_observers('heading') + self._notify_attribute_listeners('heading') self._alt = m.alt - self.notify_observers('location') + self._notify_attribute_listeners('location') self._airspeed = m.airspeed - self.notify_observers('airspeed') + self._notify_attribute_listeners('airspeed') self._groundspeed = m.groundspeed - self.notify_observers('groundspeed') + self._notify_attribute_listeners('groundspeed') self._rngfnd_distance = None self._rngfnd_voltage = None @@ -637,7 +640,7 @@ def listener(self, name, m): def listener(self, name, m): self._rngfnd_distance = m.distance self._rngfnd_voltage = m.voltage - self.notify_observers('rangefinder') + self._notify_attribute_listeners('rangefinder') self._mount_pitch = None self._mount_yaw = None @@ -648,7 +651,7 @@ def listener(self, name, m): self._mount_pitch = m.pointing_a / 100 self._mount_roll = m.pointing_b / 100 self._mount_yaw = m.pointing_c / 100 - self.notify_observers('mount') + self._notify_attribute_listeners('mount') self._rc_readback = {} @@ -677,7 +680,7 @@ def listener(self, name, m): self._voltage = m.voltage_battery self._current = m.current_battery self._level = m.battery_remaining - self.notify_observers('battery') + self._notify_attribute_listeners('battery') self._eph = None self._epv = None @@ -690,7 +693,7 @@ def listener(self, name, m): self._epv = m.epv self._satellites_visible = m.satellites_visible self._fix_type = m.fix_type - self.notify_observers('gps_0') + self._notify_attribute_listeners('gps_0') self._last_waypoint = 0 @@ -711,7 +714,7 @@ def listener(self, name, m): # boolean: EKF's predicted horizontal position (absolute) estimate is good self._ekf_predposhorizabs = (m.flags & ardupilotmega.EKF_PRED_POS_HORIZ_ABS) > 0 - self.notify_observers('ekf_ok') + self._notify_attribute_listeners('ekf_ok') self._flightmode = 'AUTO' self._armed = False @@ -720,10 +723,10 @@ def listener(self, name, m): @self.message_listener('HEARTBEAT') def listener(self, name, m): self._armed = (m.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED) != 0 - self.notify_observers('armed') + self._notify_attribute_listeners('armed') self._flightmode = {v: k for k, v in self._master.mode_mapping().items()}[m.custom_mode] self._system_status = m.system_status - self.notify_observers('mode') + self._notify_attribute_listeners('mode') # Waypoints. @@ -756,6 +759,7 @@ def listener(self, name, msg): self._master.waypoint_request_send(msg.seq + 1) else: self._wp_loaded = True + self._notify_attribute_listeners('commands') # Waypoint send to master @self.message_listener(['WAYPOINT_REQUEST', 'MISSION_REQUEST']) @@ -786,8 +790,9 @@ def listener(self, name, msg): def listener(_): # Check the time duration for last "new" params exceeds watchdog. if self._params_start: - if None not in self._params_set: + if None not in self._params_set and not self._params_loaded: self._params_loaded = True + self._notify_attribute_listeners('parameters') if not self._params_loaded and time.time() - self._params_last > self._params_duration: c = 0 @@ -852,7 +857,7 @@ def listener(self, name, msg): def message_listener(self, name): """ - Decorator for default message handlers. + Decorator for message listeners. .. code:: python @vehicle.message_listener('HEARTBEAT') @@ -887,6 +892,12 @@ def remove_message_listener(self, name, fn): if len(self._message_listeners[name]) == 0: del self._message_listeners[name] + def _notify_message_listeners(self, name, msg): + for fn in self._message_listeners.get(name, []): + fn(self, name, msg) + for fn in self._message_listeners.get('*', []): + fn(self, name, msg) + def close(self): return self._handler.close() @@ -1167,14 +1178,25 @@ def initialize(self, await_params=False, rate=None): if self._params_count > -1: break - def wait_ready(self, *types): - # We now should get parameters streaming in. The loop listener sets _params_loaded. - while not self._params_loaded: - time.sleep(0.1) + def wait_ready(self, *types, **kwargs): + timeout = kwargs.get('timeout', 30) + raise_exception = kwargs.get('raise_exception', True) + + if not all(isinstance(item, basestring) for item in types): + raise APIException('wait_ready expects one or more string arguments.') - # Await GPS lock. - while self._fix_type == None: + # Wait for these attributes to have been set. + await = set(types) + start = time.time() + while not await.issubset(self._ready_attrs): time.sleep(0.1) + if time.time() - start > timeout: + if raise_exception: + raise APIException('wait_ready experienced a timeout after %s seconds.' % timeout) + else: + return False + + return True class Parameters(HasObservers): """ diff --git a/tests/sitl/test_110.py b/tests/sitl/test_110.py index 62d400d6b..e759815ba 100644 --- a/tests/sitl/test_110.py +++ b/tests/sitl/test_110.py @@ -24,17 +24,17 @@ def test_110(connpath): time.sleep(3) # Define example callback for mode - def armed_callback(attribute): + def armed_callback(vehicle, attribute): armed_callback.called += 1 armed_callback.called = 0 - # When the same (event, callback) pair is passed to add_attribute_observer, + # When the same (event, callback) pair is passed to on_attribute, # only one instance of the observer callback should be added. - v.add_attribute_observer('armed', armed_callback) - v.add_attribute_observer('armed', armed_callback) - v.add_attribute_observer('armed', armed_callback) - v.add_attribute_observer('armed', armed_callback) - v.add_attribute_observer('armed', armed_callback) + v.on_attribute('armed', armed_callback) + v.on_attribute('armed', armed_callback) + v.on_attribute('armed', armed_callback) + v.on_attribute('armed', armed_callback) + v.on_attribute('armed', armed_callback) # Disarm and see update. v.armed = False @@ -44,13 +44,13 @@ def armed_callback(attribute): # Ensure the callback was called. assert armed_callback.called > 0, "Callback should have been called." - # Rmove all observers. The first call should remove all listeners + # Rmove all listeners. The first call should remove all listeners # we've added; the second call should be ignored and not throw. # NOTE: We test if armed_callback were treating adding each additional callback - # and remove_attribute_observer were removing them one at a time; in this + # and remove_attribute_listener were removing them one at a time; in this # case, there would be three callbacks still attached. - v.remove_attribute_observer('armed', armed_callback) - v.remove_attribute_observer('armed', armed_callback) + v.remove_attribute_listener('armed', armed_callback) + v.remove_attribute_listener('armed', armed_callback) callcount = armed_callback.called # Re-arm and see update. From 26df8fb35ce3f38af3f9416d509c60ca5b0241da Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 2 Nov 2015 20:19:51 -0800 Subject: [PATCH 118/475] Replaces wait_valid with wait_ready. --- docs/guide/auto_mode.rst | 55 +++++++++++-------- docs/guide/copter/guided_mode.rst | 2 +- docs/guide/vehicle_state_and_parameters.rst | 22 ++++++++ dronekit/lib/__init__.py | 44 +++++++-------- examples/flight_replay/flight_replay.py | 2 +- .../guided_set_speed_yaw.py | 4 +- examples/mission_basic/mission_basic.py | 18 +++++- .../mission_import_export.py | 12 +++- examples/perf/perf_test.py | 2 +- examples/vehicle_state/vehicle_state.py | 8 +++ tests/sitl/test_waypoints.py | 54 ++++-------------- 11 files changed, 126 insertions(+), 97 deletions(-) diff --git a/docs/guide/auto_mode.rst b/docs/guide/auto_mode.rst index f5dbe7fee..4b3b7b0e5 100644 --- a/docs/guide/auto_mode.rst +++ b/docs/guide/auto_mode.rst @@ -66,7 +66,7 @@ attribute. The attribute is of type :py:class:`CommandSequence ` is called. The download is asynchronous; -use :py:func:`wait_valid() ` to block your thread until the download is complete: +use :py:func:`wait_ready() ` to block your thread until the download is complete: .. code:: python @@ -76,7 +76,7 @@ use :py:func:`wait_valid() ` to block y # Download the vehicle waypoints (commands). Wait until download is complete. cmds = vehicle.commands cmds.download() - cmds.wait_valid() + cmds.wait_ready() .. note:: @@ -103,7 +103,13 @@ To clear a mission you call :py:func:`clear() ` objects. @@ -370,7 +381,7 @@ adds them to a list. Downloading mission is discussed :ref:`in the guide ` does `not su +.. _vehicle_state_home_location: + +Home location +============= + +The *Home location* is set when a vehicle is armed and first gets a good location fix from the GPS. The location is used +as the target when the vehicle does a "return to launch". In Copter missions (and most Plane) missions, the altitude of +waypoints is set relative to this position. + +Unlike other vehicle state information, the home location is accessed as the 0 index value of +:py:attr:`Vehicle.commands `: + +.. code:: python + + cmds = vehicle.commands + cmds.download() + cmds.wait_ready() + print " Home WP: %s" % cmds[0] + +The returned value is a :py:class:`Command ` object. + + .. _api-information-known-issues: diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index f55143912..fa825b7c9 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -563,7 +563,8 @@ def __init__(self, handler): self._master = handler.master # Cache all updated attributes for wait_ready. - self._ready_attrs = set() + # By default, we presume all "commands" are loaded. + self._ready_attrs = set(['commands']) @self.attribute_listener('*') def listener(_, name): @@ -1230,16 +1231,16 @@ def __init__(self, vehicle): self._vehicle = vehicle def __getitem__(self, name): - self.wait_valid() + self.wait_ready() return self._vehicle._params_map[name] def __setitem__(self, name, value): - self.wait_valid() + self.wait_ready() self.set(name, value) - def set(self, name, value, retries=3, await_valid=False): - if await_valid: - self.wait_valid() + def set(self, name, value, retries=3, wait_ready=False): + if wait_ready: + self.wait_ready() # TODO dumbly reimplement this using timeout loops # because we should actually be awaiting an ACK of PARAM_VALUE @@ -1265,13 +1266,11 @@ def set(self, name, value, retries=3, await_valid=False): errprinter("timeout setting parameter %s to %f" % (name, value)) return False - def wait_valid(self): + def wait_ready(self, **kwargs): """ Block the calling thread until parameters have been downloaded """ - # FIXME this is a super crufty spin-wait, also we should give the user the option of specifying a timeout - while self._vehicle._params_count == 0 or len(self._vehicle._params_set) != self._vehicle._params_count: - time.sleep(0.200) + self._vehicle.wait_ready('parameters', **kwargs) class Command(mavutil.mavlink.MAVLink_mission_item_message): """ @@ -1323,7 +1322,7 @@ class CommandSequence(object): The current commands/mission for a vehicle are accessed using the :py:attr:`Vehicle.commands ` attribute. Waypoints are not downloaded from vehicle until :py:func:`download()` is called. The download is asynchronous; - use :py:func:`wait_valid()` to block your thread until the download is complete. + use :py:func:`wait_ready()` to block your thread until the download is complete. The code to download the commands from a vehicle is shown below: @@ -1336,7 +1335,7 @@ class CommandSequence(object): # Download the vehicle waypoints (commands). Wait until download is complete. cmds = vehicle.commands cmds.download() - cmds.wait_valid() + cmds.wait_ready() The set of commands can be changed and uploaded to the client. The changes are not guaranteed to be complete until :py:func:`upload() ` is called. @@ -1382,22 +1381,21 @@ def download(self): ''' Download all waypoints from the vehicle. - The download is asynchronous. Use :py:func:`wait_valid()` to block your thread until the download is complete. + The download is asynchronous. Use :py:func:`wait_ready()` to block your thread until the download is complete. ''' - self.wait_valid() + self.wait_ready() + self._vehicle._ready_attrs.remove('commands') self._vehicle._wp_loaded = False self._vehicle._master.waypoint_request_list_send() # BIG FIXME - wait for full wpt download before allowing any of the accessors to work - def wait_valid(self): - ''' + def wait_ready(self, **kwargs): + """ Block the calling thread until waypoints have been downloaded. This can be called after :py:func:`download()` to block the thread until the asynchronous download is complete. - ''' - # FIXME this is a super crufty spin-wait, also we should give the user the option of specifying a timeout - while not self._vehicle._wp_loaded: - time.sleep(0.1) + """ + return self._vehicle.wait_ready('commands', **kwargs) def takeoff(self, alt=None): if alt is not None: @@ -1442,9 +1440,7 @@ def clear(self): This command will be sent to the vehicleonly after you call :py:func:`upload() `. ''' - - # Add home point again. - self.wait_valid() + self.wait_ready() self._vehicle._wploader.clear() self._vehicle._wpts_dirty = True @@ -1456,7 +1452,7 @@ def add(self, cmd): :param Command cmd: The command to be added. ''' - self.wait_valid() + self.wait_ready() self._vehicle._wploader.add(cmd, comment = 'Added by DroneAPI') self._vehicle._wpts_dirty = True diff --git a/examples/flight_replay/flight_replay.py b/examples/flight_replay/flight_replay.py index e4ce156b6..d77d2f503 100644 --- a/examples/flight_replay/flight_replay.py +++ b/examples/flight_replay/flight_replay.py @@ -111,7 +111,7 @@ def replay_mission(payload): # Now download the vehicle waypoints cmds = vehicle.commands -cmds.wait_valid() +cmds.wait_ready() mission_id = int(args.mission_id) max_freq = 0.1 json = download_messages(mission_id, max_freq) diff --git a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py index 87534979b..fa195c7c0 100644 --- a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py +++ b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py @@ -611,8 +611,8 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z): print "Get new home location" #This reloads the home location in GCSs cmds = vehicle.commands cmds.download() -cmds.wait_valid() -print " Home Location: %s" % vehicle.home_location +cmds.wait_ready() +print " Home WP: %s" % cmds[0] print("Velocity South and West") send_global_velocity(NORTH,EAST,0) diff --git a/examples/mission_basic/mission_basic.py b/examples/mission_basic/mission_basic.py index 835e890e7..73a974960 100644 --- a/examples/mission_basic/mission_basic.py +++ b/examples/mission_basic/mission_basic.py @@ -76,6 +76,22 @@ def distance_to_current_waypoint(): targetWaypointLocation=LocationGlobal(lat,lon,alt,is_relative=True) distancetopoint = get_distance_metres(vehicle.location.global_frame, targetWaypointLocation) return distancetopoint + + +def clear_mission(): + """ + Clear the current mission. + """ + cmds = vehicle.commands + vehicle.commands.clear() + vehicle.flush() + + # After clearing the mission you MUST re-download the mission from the vehicle + # before vehicle.commands can be used again + # (see https://github.com/dronekit/dronekit-python/issues/230) + cmds = vehicle.commands + cmds.download() + cmds.wait_ready() def download_mission(): @@ -84,7 +100,7 @@ def download_mission(): """ cmds = vehicle.commands cmds.download() - cmds.wait_valid() # wait until download is complete. + cmds.wait_ready() # wait until download is complete. diff --git a/examples/mission_import_export/mission_import_export.py b/examples/mission_import_export/mission_import_export.py index ce150c60f..f1d27584d 100644 --- a/examples/mission_import_export/mission_import_export.py +++ b/examples/mission_import_export/mission_import_export.py @@ -71,8 +71,14 @@ def upload_mission(aFileName): #Clear existing mission from vehicle print ' Clear mission' cmds = vehicle.commands + cmds.download() + cmds.wait_ready() cmds.clear() - #Add new mission to vehicle + vehicle.flush() + print 'ClearCount: %s' % cmds.count + #add new mission + cmds.download() + cmds.wait_ready() for command in missionlist: cmds.add(command) print ' Upload mission' @@ -88,8 +94,8 @@ def download_mission(): missionlist=[] cmds = vehicle.commands cmds.download() - cmds.wait_valid() - for cmd in cmds: + cmds.wait_ready() + for cmd in cmds[1:]: #skip first item as it is home waypoint. missionlist.append(cmd) return missionlist diff --git a/examples/perf/perf_test.py b/examples/perf/perf_test.py index e43d590d3..773ced7a8 100644 --- a/examples/perf/perf_test.py +++ b/examples/perf/perf_test.py @@ -228,7 +228,7 @@ def send_testpackets(): # Now download the vehicle waypoints cmds = vehicle.commands cmds.download() -cmds.wait_valid() +cmds.wait_ready() print "Home WP: %s" % cmds[0] print "Current dest: %s" % cmds.next diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 1dc987aba..1cec91544 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -97,6 +97,14 @@ def mode_callback(attribute): vehicle.remove_attribute_observer('mode', mode_callback) +# Get Vehicle Home location ((0 index in Vehicle.commands) +print "\nGet home location" +cmds = vehicle.commands +cmds.download() +cmds.wait_ready() +print " Home WP: %s" % cmds[0] + + # Get/Set Vehicle Parameters print "\nRead vehicle param 'THR_MIN': %s" % vehicle.parameters['THR_MIN'] print "Write vehicle param 'THR_MIN' : 10" diff --git a/tests/sitl/test_waypoints.py b/tests/sitl/test_waypoints.py index a3d4cf044..f90a0c06b 100644 --- a/tests/sitl/test_waypoints.py +++ b/tests/sitl/test_waypoints.py @@ -48,20 +48,17 @@ def test_parameter(connpath): time.sleep(10) # Initial - vehicle.commands.download() - vehicle.commands.wait_valid() - assert_equals(len(vehicle.commands), 0) - assert_not_equals(vehicle.home_location, None) - - # Save home for comparison. - home = vehicle.home_location + cmds = vehicle.commands + cmds.download() + cmds.wait_ready() + assert_equals(len(cmds), 1) # After clearing - vehicle.commands.clear() - vehicle.commands.upload() - vehicle.commands.download() - vehicle.commands.wait_valid() - assert_equals(len(vehicle.commands), 0) + cmds.clear() + vehicle.flush() + cmds.download() + cmds.wait_ready() + assert_equals(len(cmds), 1) # Upload for command in [ @@ -78,33 +75,6 @@ def test_parameter(connpath): vehicle.commands.upload() # After upload - vehicle.commands.download() - vehicle.commands.wait_valid() - assert_equals(len(vehicle.commands), 8) - - # Test iteration. - count = 0 - for cmd in vehicle.commands: - assert_not_equals(cmd, None) - count += 1 - assert_equals(count, 8) - - # Test slicing - count = 3 - for cmd in vehicle.commands[2:5]: - assert_not_equals(cmd, None) - assert_equals(cmd.seq, count) - count += 1 - assert_equals(count, 6) - - # Test next property - assert_equals(vehicle.commands.next, 0) - vehicle.commands.next = 3 - while vehicle.commands.next != 3: - time.sleep(0.1) - assert_equals(vehicle.commands.next, 3) - - # Home should be preserved - assert_equals(home.lat, vehicle.home_location.lat) - assert_equals(home.lon, vehicle.home_location.lon) - assert_equals(home.alt, vehicle.home_location.alt) + cmds.download() + cmds.wait_ready() + assert_equals(len(cmds), 9) From 9f2fac9858b9cc341387c2a9069c30e1241dac78 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 2 Nov 2015 20:36:25 -0800 Subject: [PATCH 119/475] Fixes fallout from rebase. --- docs/guide/auto_mode.rst | 47 +++--- docs/guide/vehicle_state_and_parameters.rst | 25 +-- dronekit/__init__.py | 6 +- dronekit/lib/__init__.py | 152 ++++++++---------- .../guided_set_speed_yaw.py | 2 +- examples/mission_basic/mission_basic.py | 16 -- .../mission_import_export.py | 13 +- examples/vehicle_state/vehicle_state.py | 10 +- tests/sitl/test_waypoints.py | 58 +++++-- 9 files changed, 137 insertions(+), 192 deletions(-) diff --git a/docs/guide/auto_mode.rst b/docs/guide/auto_mode.rst index 4b3b7b0e5..3f20ef245 100644 --- a/docs/guide/auto_mode.rst +++ b/docs/guide/auto_mode.rst @@ -103,13 +103,7 @@ To clear a mission you call :py:func:`clear() `. - + .. code:: python def upload_mission(aFileName): - """ - Upload a mission from a file. - """ - missionlist = readmission(aFileName) - #clear existing mission - print 'Clear mission' - cmds = vehicle.commands - cmds.download() - cmds.wait_ready() - cmds.clear() - vehicle.flush() - print 'ClearCount: %s' % cmds.count - #add new mission - cmds.download() - cmds.wait_ready() - for command in missionlist: - cmds.add(command) - vehicle.flush() + """ + Upload a mission from a file. + """ + #Read mission from file + missionlist = readmission(aFileName) + + print "\nUpload mission from a file: %s" % import_mission_filename + #Clear existing mission from vehicle + print ' Clear mission' + cmds = vehicle.commands + cmds.clear() + #Add new mission to vehicle + for command in missionlist: + cmds.add(command) + print ' Upload mission' + vehicle.commands.upload() ``readmission()`` reads a mission from the specified file and returns a list of :py:class:`Command ` objects. diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index 8f7bccf1f..2d7cf2c34 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -196,7 +196,7 @@ The behaviour of :py:attr:`Vehicle.home_location ` object @@ -266,29 +266,6 @@ At time of writing :py:class:`Parameters ` does `not su -.. _vehicle_state_home_location: - -Home location -============= - -The *Home location* is set when a vehicle is armed and first gets a good location fix from the GPS. The location is used -as the target when the vehicle does a "return to launch". In Copter missions (and most Plane) missions, the altitude of -waypoints is set relative to this position. - -Unlike other vehicle state information, the home location is accessed as the 0 index value of -:py:attr:`Vehicle.commands `: - -.. code:: python - - cmds = vehicle.commands - cmds.download() - cmds.wait_ready() - print " Home WP: %s" % cmds[0] - -The returned value is a :py:class:`Command ` object. - - - .. _api-information-known-issues: Known issues diff --git a/dronekit/__init__.py b/dronekit/__init__.py index ec3ece1f9..f7935af49 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -81,7 +81,7 @@ def mavlink_thread(): except socket.error as error: if error.errno == ECONNABORTED: errprinter('reestablishing connection after read timeout') - if self.master.reset: + if hasattr(self.master, 'reset'): self.master.reset() else: try: @@ -105,7 +105,7 @@ def mavlink_thread(): except socket.error as error: if error.errno == ECONNABORTED: errprinter('reestablishing connection after send timeout') - if self.master.reset: + if hasattr(self.master, 'reset'): self.master.reset() else: try: @@ -118,7 +118,7 @@ def mavlink_thread(): # If connection reset (closed), stop polling. return except Exception as e: - # TODO this should be more rigious. How to avoid + # TODO this should be more rigorous. How to avoid # invalid MAVLink prefix '73' # invalid MAVLink prefix '13' # errprinter('mav recv error:', e) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index fa825b7c9..0fa8b1c14 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -15,11 +15,10 @@ .. code:: python from dronekit import connect - + # Connect to the Vehicle using "connection string" (in this case an address on network) vehicle = connect('127.0.0.1:14550', await_params=True) - :py:class:`Vehicle ` provides access to vehicle *state* through python attributes (e.g. :py:attr:`Vehicle.mode `) and to settings/parameters though the :py:attr:`Vehicle.parameters ` attribute. @@ -33,15 +32,13 @@ (:py:func:`Vehicle.send_mavlink `, :py:func:`Vehicle.message_factory `). * Missions are downloaded and uploaded through the :py:attr:`Vehicle.commands ` attribute (see :py:class:`CommandSequence ` for more information). - + A number of other useful classes and methods are listed below. ---- .. todo:: Update this when have confirmed how to register for parameter notifications. - - .. py:function:: connect(ip, await_params=False, status_printer=errprinter, vehicle_class=Vehicle, rate=4) Returns a :py:class:`Vehicle` object connected to the address specified by string parameter ``ip``. @@ -52,13 +49,13 @@ :param status_printer: NA :param Vehicle vehicle_class: NA :param int rate: NA - + :returns: A connected :py:class:`Vehicle` object. ---- - + .. todo:: Confirm what status_printer, vehicle_class and rate "mean". Can we hide in API. Can we get method defined in this file. - + """ local_path = '' @@ -121,7 +118,7 @@ def __init__(self, lat, lon, alt=None, is_relative=True): self.lon = lon self.alt = alt self.is_relative = is_relative - + # This is for backward compatibility. self.local_frame = None self.global_fame = None @@ -135,9 +132,9 @@ def __str__(self): class LocationLocal(object): """ A local location object. - + The north, east and down are relative to the EKF origin. This is most likely the location where the vehicle was turned on. - + :param north: Position north of the EKF origin in meters. :param east: Position east of the EKF origin in meters. :param down: Position down from the EKF origin in meters. (i.e. negative altitude in meters) @@ -146,7 +143,7 @@ def __init__(self, north, east, down): self.north = north self.east = east self.down = down - + def __str__(self): return "LocationLocal:north=%s,east=%s,down=%s" % (self.north, self.east, self.down) @@ -172,7 +169,6 @@ def __init__(self, eph, epv, fix_type, satellites_visible): def __str__(self): return "GPSInfo:fix=%s,num_sat=%s" % (self.fix_type, self.satellites_visible) - class Battery(object): """ System battery information. @@ -195,7 +191,6 @@ def __init__(self, voltage, current, level): def __str__(self): return "Battery:voltage={},current={},level={}".format(self.voltage, self.current, self.level) - class Rangefinder(object): """ Rangefinder readings. @@ -210,7 +205,6 @@ def __init__(self, distance, voltage): def __str__(self): return "Rangefinder: distance={}, voltage={}".format(self.distance, self.voltage) - class VehicleMode(object): """ This object is used to get and set the current "flight mode". @@ -240,7 +234,6 @@ def mode_callback(self, mode): vehicle.on_attribute('mode', mode_callback) - The code snippet below shows how to change the vehicle mode to AUTO: .. code:: python @@ -283,7 +276,7 @@ def on_attribute(self, attr_name, observer): The listener callback function is called with the ``vehicle`` and ``attr_name`` arguments. This can be used to infer the related attribute if the same callback is used for watching several attributes. - + The example below shows how to get callbacks for location changes: .. code:: python @@ -295,7 +288,7 @@ def location_callback(vehicle, location): #Add observer for the vehicle's current location vehicle.on_attribute('location', location_callback) - + .. note:: Attribute changes will only be published for changes due to some other entity. They will not be published for changes made by the local API client @@ -304,7 +297,6 @@ def location_callback(vehicle, location): :param attr_name: The attribute to watch. :param observer: The callback to invoke when a change in the attribute is detected. - """ l = self.__observers.get(attr_name) if l is None: @@ -323,11 +315,9 @@ def remove_attribute_listener(self, attr_name, observer): vehicle.remove_attribute_listener('global_frame', location_callback) - :param attr_name: The attribute name that is to have an observer removed. :param observer: The callback function to remove. - """ l = self.__observers.get(attr_name) if l is not None: @@ -390,27 +380,22 @@ class Vehicle(HasObservers): Current :py:class:`LocationGlobal`. - .. py:attribute:: location.local_frame Current :py:class:`LocationLocal`. - .. py:attribute:: attitude Current vehicle :py:class:`Attitude` (pitch, yaw, roll). - .. py:attribute:: velocity Current velocity as a three element list ``[ vx, vy, vz ]`` (in meter/sec). - .. py:attribute:: mode This attribute is used to get and set the current flight mode (:py:class:`VehicleMode`). - .. py:attribute:: airspeed Current airspeed in metres/second (``double``). @@ -425,7 +410,6 @@ class Vehicle(HasObservers): GPS position information (:py:class:`GPSInfo`). - .. py:attribute:: armed This attribute can be used to get and set the ``armed`` state of the vehicle (``boolean``). @@ -443,24 +427,20 @@ class Vehicle(HasObservers): # Arm the vehicle vehicle.armed = True - .. py:attribute:: mount_status Current status of the camera mount (gimbal) as a three element list: ``[ pitch, yaw, roll ]``. The values in the list are set to ``None`` if no mount is configured. - .. py:attribute:: battery Current system :py:class:`Battery` status. - .. py:attribute:: rangefinder :py:class:`Rangefinder` distance and voltage values. - .. py:attribute:: channel_override .. warning:: @@ -497,12 +477,10 @@ class Vehicle(HasObservers): # Cancel override on channel 1 and 4 by sending 0 vehicle.channel_override = { "1" : 0, "4" : 0 } - .. versionchanged:: 1.0 This update replaces ``rc_override`` with ``channel_override``/``channel_readback`` documentation. - .. todo:: Add note to the examples/guide like warning above not to use this mechanism except as intended: https://github.com/dronekit/dronekit-python/issues/72 @@ -525,7 +503,6 @@ class Vehicle(HasObservers): * how to address the units issue? Merely with documentation or some other way? * is there any benefit of using lists rather than tuples for these attributes - .. py:attribute:: channel_readback This read-only attribute returns a dictionary containing the *original* vehicle RC channel values (ignoring any overrides set using @@ -537,8 +514,6 @@ class Vehicle(HasObservers): RC readback: {'1': 1500, '3': 1000, '2': 1500, '5': 1800, '4': 1500, '7': 1000, '6': 1000, '8': 1800} ? Dictionary () (read only) - - .. todo:: In V2, there may be ardupilot specific attributes & types (as in the introduction). If so, text below might be useful. **Autopilot specific attributes & types:** @@ -551,7 +526,6 @@ class Vehicle(HasObservers): ? double (0, 1, 2.3 etc...) - .. todo:: Add waypoint_home attribute IF this is added: https://github.com/dronekit/dronekit-python/issues/105 """ @@ -582,7 +556,7 @@ def listener(_, msg): self._vx = None self._vy = None self._vz = None - + @self.message_listener('GLOBAL_POSITION_INT') def listener(self, name, m): (self._lat, self._lon) = (m.lat / 1.0e7, m.lon / 1.0e7) @@ -607,7 +581,7 @@ def listener(self, name, m): self._pitchspeed = None self._yawspeed = None self._rollspeed = None - + @self.message_listener('ATTITUDE') def listener(self, name, m): self._pitch = m.pitch @@ -622,7 +596,7 @@ def listener(self, name, m): self._alt = None self._airspeed = None self._groundspeed = None - + @self.message_listener('VFR_HUD') def listener(self, name, m): self._heading = m.heading @@ -675,7 +649,7 @@ def set_rc(chnum, v): self._voltage = None self._current = None self._level = None - + @self.message_listener('SYS_STATUS') def listener(self, name, m): self._voltage = m.voltage_battery @@ -687,7 +661,7 @@ def listener(self, name, m): self._epv = None self._satellites_visible = None self._fix_type = None # FIXME support multiple GPSs per vehicle - possibly by using componentId - + @self.message_listener('GPS_RAW_INT') def listener(self, name, m): self._eph = m.eph @@ -700,7 +674,7 @@ def listener(self, name, m): @self.message_listener(['WAYPOINT_CURRENT', 'MISSION_CURRENT']) def listener(self, name, m): - self._last_waypoint = m.seq + self._last_waypoint = max(m.seq - 1, 0) self._ekf_poshorizabs = False self._ekf_constposmode = False @@ -770,7 +744,7 @@ def listener(self, name, msg): handler.fix_targets(wp) self._master.mav.send(wp) self._wp_uploaded[msg.seq] = True - + # TODO: Waypoint loop listeners # Parameters. @@ -831,7 +805,7 @@ def listener(self, name, msg): traceback.print_exc() # Heartbeats. - + self._heartbeat_started = False self._heartbeat_lastsent = 0 self._heartbeat_lastreceived = 0 @@ -908,20 +882,12 @@ def flush(self): After the return from ``flush()`` any writes are guaranteed to have completed (or thrown an exception) and future reads will see their effects. - + .. warning:: - + This has been replaced by :py:func:`Vehicle.commands.upload() `. """ - if self._wpts_dirty: - self._master.waypoint_clear_all_send() - if self._wploader.count() > 0: - self._wp_uploaded = [False]*self._wploader.count() - self._master.waypoint_count_send(self._wploader.count()) - while False in self._wp_uploaded: - time.sleep(0.1) - self._wp_uploaded = None - self._wpts_dirty = False + return self.commands.upload() # # Private sugar methods @@ -1034,12 +1000,12 @@ def channel_readback(self): def home_location(self): """ The current home location in a :py:class:`LocationGlobal`. - + This value is initially set by the autopilot as the location of first GPS Lock. The attribute has a value of ``None`` until :py:func:`Vehicle.commands` has been downloaded. If the attribute is queried before the home location is set the returned `LocationGlobal` will have zero values for its member attributes. - + .. code-block:: python #Connect to a vehicle object (for example, on com14) @@ -1048,25 +1014,25 @@ def home_location(self): # Download the vehicle waypoints (commands). Wait until download is complete. cmds = vehicle.commands cmds.download() - cmds.wait_valid() - + cmds.wait_ready() + # Get the home location home = vehicle.home_location - + The attribute is not writeable or observable. - + """ - loc = self.__module.wploader.wp(0) + loc = self._wploader.wp(0) if loc: return LocationGlobal(loc.x, loc.y, loc.z, is_relative=False) - + @home_location.setter def home_location(self, pos): """ Sets the home location to that of a ``LocationGlobal`` object. .. note:: - + If the GPS values differ heavily from EKF values, setting this value will fail silently. """ self.send_mavlink(self.message_factory.command_long_encode( @@ -1215,7 +1181,6 @@ class Parameters(HasObservers): # Change the parameter value to something different. vehicle.parameters['THR_MIN']=100 - .. note:: At time of writing ``Parameters`` does not implement the observer methods, and change notification for parameters @@ -1261,7 +1226,7 @@ def set(self, name, value, retries=3, wait_ready=False): if name in self._vehicle._params_map and self._vehicle._params_map[name] == value: return True time.sleep(0.1) - + if retries > 0: errprinter("timeout setting parameter %s to %f" % (name, value)) return False @@ -1286,7 +1251,6 @@ class Command(mavutil.mavlink.MAVLink_mission_item_message): cmd = Command(0,0,0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0,-34.364114, 149.166022, 30) - :param target_system: The id number of the message's target system (drone, GSC) within the MAVLink network. Set this to zero (broadcast) when communicating with a companion computer. :param target_component: The id of a component the message should be routed to within the target system @@ -1322,8 +1286,7 @@ class CommandSequence(object): The current commands/mission for a vehicle are accessed using the :py:attr:`Vehicle.commands ` attribute. Waypoints are not downloaded from vehicle until :py:func:`download()` is called. The download is asynchronous; - use :py:func:`wait_ready()` to block your thread until the download is complete. - + use :py:func:`wait_valid()` to block your thread until the download is complete. The code to download the commands from a vehicle is shown below: .. code-block:: python @@ -1335,13 +1298,12 @@ class CommandSequence(object): # Download the vehicle waypoints (commands). Wait until download is complete. cmds = vehicle.commands cmds.download() - cmds.wait_ready() + cmds.wait_valid() The set of commands can be changed and uploaded to the client. The changes are not guaranteed to be complete until :py:func:`upload() ` is called. .. code:: python - cmds = vehicle.commands cmds.clear() lat = -34.364114, @@ -1380,8 +1342,7 @@ def __init__(self, vehicle): def download(self): ''' Download all waypoints from the vehicle. - - The download is asynchronous. Use :py:func:`wait_ready()` to block your thread until the download is complete. + The download is asynchronous. Use :py:func:`wait_valid()` to block your thread until the download is complete. ''' self.wait_ready() self._vehicle._ready_attrs.remove('commands') @@ -1437,23 +1398,28 @@ def goto(self, l): def clear(self): ''' Clear the command list. - + This command will be sent to the vehicleonly after you call :py:func:`upload() `. ''' + + # Add home point again. self.wait_ready() + home = self._vehicle._wploader.wp(0) self._vehicle._wploader.clear() + if home: + self._vehicle._wploader.add(home, comment='Added by DroneKit') self._vehicle._wpts_dirty = True def add(self, cmd): ''' Add a new command (waypoint) at the end of the command list. - - .. note:: Commands are sent to the vehicle only after you call ::py:func:`upload() `. + .. note:: Commands are sent to the vehicle only after you call ::py:func:`upload() `. :param Command cmd: The command to be added. ''' self.wait_ready() - self._vehicle._wploader.add(cmd, comment = 'Added by DroneAPI') + self._vehicle._handler.fix_targets(cmd) + self._vehicle._wploader.add(cmd, comment='Added by DroneKit') self._vehicle._wpts_dirty = True def upload(self): @@ -1463,9 +1429,15 @@ def upload(self): After the return from ``upload()`` any writes are guaranteed to have completed (or thrown an exception) and future reads will see their effects. """ - if self.__module.vehicle.wpts_dirty: - self.__module.send_all_waypoints() - self.__module.vehicle.wpts_dirty = False + if self._vehicle._wpts_dirty: + self._vehicle._master.waypoint_clear_all_send() + if self._vehicle._wploader.count() > 0: + self._vehicle._wp_uploaded = [False]*self._vehicle._wploader.count() + self._vehicle._master.waypoint_count_send(self._vehicle._wploader.count()) + while False in self._vehicle._wp_uploaded: + time.sleep(0.1) + self._vehicle._wp_uploaded = None + self._vehicle._wpts_dirty = False @property def count(self): @@ -1474,7 +1446,7 @@ def count(self): :return: The number of waypoints in the sequence. ''' - return self._vehicle._wploader.count() + return max(self._vehicle._wploader.count() - 1, 0) @property def next(self): @@ -1488,7 +1460,7 @@ def next(self, index): """ Set a new ``next`` waypoint for the vehicle. """ - self._vehicle._master.waypoint_set_current_send(index) + self._vehicle._master.waypoint_set_current_send(index + 1) def __len__(self): ''' @@ -1496,11 +1468,19 @@ def __len__(self): :return: The number of waypoints in the sequence. ''' - return self._vehicle._wploader.count() + return max(self._vehicle._wploader.count() - 1, 0) def __getitem__(self, index): - return self._vehicle._wploader.wp(index) + if isinstance(index, slice): + return [self[ii] for ii in xrange(*index.indices(len(self)))] + elif isinstance(index, int): + item = self._vehicle._wploader.wp(index + 1) + if not item: + raise IndexError('Index %s out of range.' % index) + return item + else: + raise TypeError('Invalid argument type.') def __setitem__(self, index, value): - self._vehicle._wploader.set(value, index) + self._vehicle._wploader.set(value, index + 1) self._vehicle._wpts_dirty = True diff --git a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py index fa195c7c0..ffba95b55 100644 --- a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py +++ b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py @@ -612,7 +612,7 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z): cmds = vehicle.commands cmds.download() cmds.wait_ready() -print " Home WP: %s" % cmds[0] +print " Home Location: %s" % vehicle.home_location print("Velocity South and West") send_global_velocity(NORTH,EAST,0) diff --git a/examples/mission_basic/mission_basic.py b/examples/mission_basic/mission_basic.py index 73a974960..6ef7d5363 100644 --- a/examples/mission_basic/mission_basic.py +++ b/examples/mission_basic/mission_basic.py @@ -78,22 +78,6 @@ def distance_to_current_waypoint(): return distancetopoint -def clear_mission(): - """ - Clear the current mission. - """ - cmds = vehicle.commands - vehicle.commands.clear() - vehicle.flush() - - # After clearing the mission you MUST re-download the mission from the vehicle - # before vehicle.commands can be used again - # (see https://github.com/dronekit/dronekit-python/issues/230) - cmds = vehicle.commands - cmds.download() - cmds.wait_ready() - - def download_mission(): """ Download the current mission from the vehicle. diff --git a/examples/mission_import_export/mission_import_export.py b/examples/mission_import_export/mission_import_export.py index f1d27584d..0a45e1e23 100644 --- a/examples/mission_import_export/mission_import_export.py +++ b/examples/mission_import_export/mission_import_export.py @@ -71,14 +71,8 @@ def upload_mission(aFileName): #Clear existing mission from vehicle print ' Clear mission' cmds = vehicle.commands - cmds.download() - cmds.wait_ready() cmds.clear() - vehicle.flush() - print 'ClearCount: %s' % cmds.count - #add new mission - cmds.download() - cmds.wait_ready() + #Add new mission to vehicle for command in missionlist: cmds.add(command) print ' Upload mission' @@ -94,8 +88,8 @@ def download_mission(): missionlist=[] cmds = vehicle.commands cmds.download() - cmds.wait_ready() - for cmd in cmds[1:]: #skip first item as it is home waypoint. + cmds.wait_valid() + for cmd in cmds: missionlist.append(cmd) return missionlist @@ -151,4 +145,3 @@ def printfile(aFileName): printfile(import_mission_filename) #Print exported file (for demo purposes only) printfile(export_mission_filename) - diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 1cec91544..672b706a2 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -55,7 +55,7 @@ cmds = vehicle.commands cmds.download() -cmds.wait_valid() +cmds.wait_ready() print " Home Location (after downloading waypoints): %s" % vehicle.home_location @@ -97,14 +97,6 @@ def mode_callback(attribute): vehicle.remove_attribute_observer('mode', mode_callback) -# Get Vehicle Home location ((0 index in Vehicle.commands) -print "\nGet home location" -cmds = vehicle.commands -cmds.download() -cmds.wait_ready() -print " Home WP: %s" % cmds[0] - - # Get/Set Vehicle Parameters print "\nRead vehicle param 'THR_MIN': %s" % vehicle.parameters['THR_MIN'] print "Write vehicle param 'THR_MIN' : 10" diff --git a/tests/sitl/test_waypoints.py b/tests/sitl/test_waypoints.py index f90a0c06b..21818ff1b 100644 --- a/tests/sitl/test_waypoints.py +++ b/tests/sitl/test_waypoints.py @@ -22,7 +22,7 @@ def test_set_home(connpath): # once we request it via cmds.download() time.sleep(10) vehicle.commands.download() - vehicle.commands.wait_valid() + vehicle.commands.wait_ready() assert_not_equals(vehicle.home_location, None) # Note: If the GPS values differ heavily from EKF values, this command @@ -30,7 +30,7 @@ def test_set_home(connpath): # the with_sitl initializer uses to not fail. vehicle.home_location = LocationGlobal(-35, 149, 600) vehicle.commands.download() - vehicle.commands.wait_valid() + vehicle.commands.wait_ready() assert_equals(vehicle.home_location.lat, -35) assert_equals(vehicle.home_location.lon, 149) @@ -48,17 +48,20 @@ def test_parameter(connpath): time.sleep(10) # Initial - cmds = vehicle.commands - cmds.download() - cmds.wait_ready() - assert_equals(len(cmds), 1) + vehicle.commands.download() + vehicle.commands.wait_ready() + assert_equals(len(vehicle.commands), 0) + assert_not_equals(vehicle.home_location, None) + + # Save home for comparison. + home = vehicle.home_location # After clearing - cmds.clear() - vehicle.flush() - cmds.download() - cmds.wait_ready() - assert_equals(len(cmds), 1) + vehicle.commands.clear() + vehicle.commands.upload() + vehicle.commands.download() + vehicle.commands.wait_ready() + assert_equals(len(vehicle.commands), 0) # Upload for command in [ @@ -75,6 +78,33 @@ def test_parameter(connpath): vehicle.commands.upload() # After upload - cmds.download() - cmds.wait_ready() - assert_equals(len(cmds), 9) + vehicle.commands.download() + vehicle.commands.wait_ready() + assert_equals(len(vehicle.commands), 8) + + # Test iteration. + count = 0 + for cmd in vehicle.commands: + assert_not_equals(cmd, None) + count += 1 + assert_equals(count, 8) + + # Test slicing + count = 3 + for cmd in vehicle.commands[2:5]: + assert_not_equals(cmd, None) + assert_equals(cmd.seq, count) + count += 1 + assert_equals(count, 6) + + # Test next property + assert_equals(vehicle.commands.next, 0) + vehicle.commands.next = 3 + while vehicle.commands.next != 3: + time.sleep(0.1) + assert_equals(vehicle.commands.next, 3) + + # Home should be preserved + assert_equals(home.lat, vehicle.home_location.lat) + assert_equals(home.lon, vehicle.home_location.lon) + assert_equals(home.alt, vehicle.home_location.alt) From 90f18e55a01c238d414cb78939354490cf5a742e Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 3 Nov 2015 10:12:17 -0800 Subject: [PATCH 120/475] Small docs fix. --- dronekit/lib/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 0fa8b1c14..022798422 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -282,7 +282,7 @@ def on_attribute(self, attr_name, observer): .. code:: python #Callback to print the location in global and local frames - def location_callback(vehicle, location): + def location_callback(vehicle, attr_name): print "Location (Global): ", vehicle.location.global_frame print "Location (Local): ", vehicle.location.local_frame From cd746d2aadbd5746e859dfad762344ad62e2b6c3 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 3 Nov 2015 20:31:48 +1100 Subject: [PATCH 121/475] Update examples and documentation to reflect get/set behaviour of vehicle.home_location - as per #392 --- docs/examples/guided-set-speed-yaw-demo.rst | 5 +- docs/examples/vehicle_state.rst | 15 ++++-- docs/guide/copter/guided_mode.rst | 40 +--------------- docs/guide/vehicle_state_and_parameters.rst | 48 ++++++++++++++----- .../guided_set_speed_yaw.py | 31 ++---------- examples/vehicle_state/vehicle_state.py | 34 +++++++++++-- 6 files changed, 84 insertions(+), 89 deletions(-) diff --git a/docs/examples/guided-set-speed-yaw-demo.rst b/docs/examples/guided-set-speed-yaw-demo.rst index dff4cd12a..787023136 100644 --- a/docs/examples/guided-set-speed-yaw-demo.rst +++ b/docs/examples/guided-set-speed-yaw-demo.rst @@ -189,7 +189,6 @@ The functions sending immediate commands are: * :ref:`condition_yaw() ` * :ref:`set_roi(location) ` * :ref:`set_speed(speed) ` -* :ref:`set_home() ` The example uses a number functions to convert global locations co-ordinates (decimal degrees) into local coordinates relative to the vehicle (in metres). These are :ref:`described in the guide `. @@ -349,14 +348,14 @@ This demo has been tested on Windows against SITL running both natively and in a DroneKit environment (from PIP): -* droneapi: 1.2.0 +* droneapi: 2.0.0rc2 * pymavlink: 1.1.57 * MAVProxy: 1.4.23 * protobuf: 2.6.1 ArduPilot version: -* `3.3.0beta2 `_. +* 3.3.0. diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index 07a513ee3..cd94ecb1e 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -20,8 +20,8 @@ the vehicle and DroneKit have been set up as described in :ref:`get-started`). If you're using a simulated vehicle remember to :ref:`disable arming checks ` so that the example can run. You can also `add a virtual rangefinder `_ -(otherwise the :py:attr:`Vehicle.rangefinder ` attribute may return values of ``None`` for the distance -and voltage). +(otherwise the :py:attr:`Vehicle.rangefinder ` attribute may return +values of ``None`` for the distance and voltage). In summary, after cloning the repository: @@ -70,10 +70,17 @@ On the command prompt you should see (something like): Rangefinder voltage: None Mode: STABILIZE Armed: False + Home Location: LocationGlobal:lat=0.0,lon=0.0,alt=0.0,is_relative=False - Home Location (before downloading waypoints): None - Home Location (after downloading waypoints): LocationGlobal:lat=-35.3632621765,lon=149.165237427,alt=583.989990234,is_relative=False + Set new home location + Waiting for home location: LocationGlobal:lat=0.0,lon=0.0,alt=0.0,is_relative=False + ... + Waiting for home location: LocationGlobal:lat=0.0,lon=0.0,alt=0.0,is_relative=False + Waiting for home location: LocationGlobal:lat=0.0,lon=0.0,alt=0.0,is_relative=False + Autopilot set home location: LocationGlobal:lat=-35.3632621765,lon=149.165237427,alt=583.989990234,is_relative=False + New Home Location (altitude should be 222): LocationGlobal:lat=-35.3632621765,lon=149.165237427,alt=222.0,is_relative=False + Set Vehicle.mode=GUIDED (currently: STABILIZE) Waiting for mode change ... diff --git a/docs/guide/copter/guided_mode.rst b/docs/guide/copter/guided_mode.rst index 40695ef09..2fa224162 100644 --- a/docs/guide/copter/guided_mode.rst +++ b/docs/guide/copter/guided_mode.rst @@ -136,7 +136,7 @@ The command can be interrupted by a later movement command. When moving the vehi You can also control the velocity using the `SET_POSITION_TARGET_GLOBAL_INT `_ MAVLink command in almost exactly the same way (there is no real benefit in sending one command over the other). For more information on this option see :ref:`example_guided_mode_send_global_velocity` in the example code. - + .. _guided_mode_copter_accel_force_control: Acceleration and force control @@ -214,7 +214,7 @@ Supported commands DroneKit-Python provides a friendly Python API that abstracts many of the commands. Where possible you should use the API rather than send messages directly. For example it is better to use :py:func:`Vehicle.commands.takeoff() ` than to explicitly send the ``MAV_CMD_NAV_TAKEOFF`` command. -Some of the MAV_CMD commands that you might want to send include: :ref:`MAV_CMD_CONDITION_YAW `, :ref:`MAV_CMD_DO_CHANGE_SPEED `, :ref:`MAV_CMD_DO_SET_HOME `, :ref:`MAV_CMD_DO_SET_ROI `, ``MAV_CMD_DO_SET_SERVO``, ``MAV_CMD_DO_REPEAT_SERVO``, ``MAV_CMD_DO_SET_RELAY``, ``MAV_CMD_DO_REPEAT_RELAY``, ``MAV_CMD_DO_FENCE_ENABLE``, ``MAV_CMD_DO_PARACHUTE``, ``MAV_CMD_DO_GRIPPER``, ``MAV_CMD_MISSION_START``. These would be sent in a ``COMMAND_LONG`` message :ref:`as discussed above `. +Some of the MAV_CMD commands that you might want to send include: :ref:`MAV_CMD_CONDITION_YAW `, :ref:`MAV_CMD_DO_CHANGE_SPEED `, :ref:`MAV_CMD_DO_SET_ROI `, ``MAV_CMD_DO_SET_SERVO``, ``MAV_CMD_DO_REPEAT_SERVO``, ``MAV_CMD_DO_SET_RELAY``, ``MAV_CMD_DO_REPEAT_RELAY``, ``MAV_CMD_DO_FENCE_ENABLE``, ``MAV_CMD_DO_PARACHUTE``, ``MAV_CMD_DO_GRIPPER``, ``MAV_CMD_MISSION_START``. These would be sent in a ``COMMAND_LONG`` message :ref:`as discussed above `. @@ -321,42 +321,6 @@ Send the `MAV_CMD_DO_SET_ROI `_ -command to set the *home location* to either the current location or a specified location. - -.. code-block:: python - - def set_home(aLocation, aCurrent=1): - msg = vehicle.message_factory.command_long_encode( - 0, 0, # target system, target component - mavutil.mavlink.MAV_CMD_DO_SET_HOME, #command - 0, #confirmation - aCurrent, #param 1: 1 to use current position, 2 to use the entered values. - 0, 0, 0, #params 2-4 - aLocation.lat, - aLocation.lon, - aLocation.alt - ) - # send command to vehicle - vehicle.send_mavlink(msg) - - -The *home location* is updated immediately in ArduPilot, but the change may not appear in the GCS/*Mission Planner*. You can force an update by reading the mission commands (this works, because the home location is currently implemented as the 0th waypoint command): - -.. code-block:: python - - # Set new Home location to current LocationGlobal - set_home(vehicle.location.global_frame) - # Reloads the home location in GCSs - cmds = vehicle.commands - cmds.download() - cmds.wait_ready() - print " Home WP: %s" % cmds[0] .. _guided_mode_copter_responses: diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index 2d7cf2c34..1a9aaf04a 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -30,15 +30,18 @@ Vehicle state information is exposed through vehicle *attributes*. DroneKit-Pyth :py:attr:`Vehicle.mount_status `, :py:attr:`Vehicle.battery `, :py:attr:`Vehicle.rangefinder `, -:py:attr:`Vehicle.home_location ` +:py:attr:`Vehicle.home_location `, :py:attr:`Vehicle.armed `, :py:attr:`Vehicle.mode `. All of the attributes can be :ref:`read ` and :ref:`observed `, -but only the :py:attr:`Vehicle.mode ` and :py:attr:`Vehicle.armed ` +but only the :py:attr:`Vehicle.home_location `, +:py:attr:`Vehicle.mode ` and +:py:attr:`Vehicle.armed ` status can be :ref:`written `. - +The behaviour of :py:attr:`Vehicle.home_location ` is different +from the other attributes, and is :ref:`discussed in its own section below `. .. _vehicle_state_read_attributes: @@ -73,8 +76,6 @@ If an attribute cannot be retrieved then the returned object will contain with ``None`` values for ``eph``, ``satellites_visible`` etc.) Attributes will also return ``None`` if the associated hardware is not present on the connected device. -The behaviour of :py:attr:`Vehicle.home_location ` is different, -:ref:`as discussed below `. .. tip:: @@ -82,7 +83,6 @@ The behaviour of :py:attr:`Vehicle.home_location `_ and `optical flow sensors `_. - .. todo:: we need to be able to verify mount_status works/setup. @@ -184,13 +184,13 @@ For example, the following code can be used in the callback to only print output Home location ------------- -The *Home location* is set when a vehicle is armed and first gets a good location fix from the GPS. The location is used +The *Home location* is set when a vehicle first gets a good location fix from the GPS. The location is used as the target when the vehicle does a "return to launch". In Copter missions (and often Plane) missions, the altitude of waypoints is set relative to this position. -The behaviour of :py:attr:`Vehicle.home_location ` is slightly different than other attributes: +:py:attr:`Vehicle.home_location ` has the following behaviour: -* In order to get the current value you must first download :py:attr:`Vehicle.commands `, as shown: +* In order to *get* the current value you must first download :py:attr:`Vehicle.commands `, as shown: .. code:: python @@ -200,11 +200,35 @@ The behaviour of :py:attr:`Vehicle.home_location ` object - (or ``None`` before you download the commands). -* The attribute is not observable. -* While you cannot directly set the attribute it can be :ref:`set using a message `. + (or ``None`` before you download the commands). If the location has not been set, then + the returned value's attributes will all be set to zero. + +* The attribute can be *set* to a :py:class:`LocationGlobal ` object + (the code fragment below sets it to the current location): + + .. code:: python + vehicle.home_location=vehicle.location.global_frame + + There are some caveats: + + * You must download the commands again to read the changed ``home_location``. + * The autopilot must first set the value (on startup) before it can be changed by DroneKit-Python code. + * The new location must be within 50 km of the EKF origin or setting the value will silently fail. + +* The attribute is not observable. + + +.. note:: + + :py:attr:`Vehicle.home_location ` behaves this way because + ArduPilot implements/stores the home location as a waypoint rather than sending them as messages. + While DroneKit-Python hides this fact from you when working with commands, to access the value + you still need to download the commands. + We hope to improve this attribute in later versions of ArduPilot, where there may be specific + commands to get the home location from the vehicle. + .. _vehicle_state_parameters: diff --git a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py index ffba95b55..e5458fd64 100644 --- a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py +++ b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py @@ -74,7 +74,6 @@ def arm_and_takeoff(aTargetAltitude): * MAV_CMD_CONDITION_YAW - set direction of the front of the Copter (latitude, longitude) * MAV_CMD_DO_SET_ROI - set direction where the camera gimbal is aimed (latitude, longitude, altitude) * MAV_CMD_DO_CHANGE_SPEED - set target speed in metres/second. -* MAV_CMD_DO_SET_HOME - set the home location. The full set of available commands are listed here: @@ -163,29 +162,6 @@ def set_speed(speed): vehicle.send_mavlink(msg) -def set_home(aLocation, aCurrent=1): - """ - Send MAV_CMD_DO_SET_HOME command to set the Home location to either the current LocationGlobal - or a specified location. - - For more information see: - http://copter.ardupilot.com/common-mavlink-mission-command-messages-mav_cmd/#mav_cmd_do_set_home - """ - # create the MAV_CMD_DO_SET_HOME command: - # http://copter.ardupilot.com/common-mavlink-mission-command-messages-mav_cmd/#mav_cmd_do_set_home - msg = vehicle.message_factory.command_long_encode( - 0, 0, # target system, target component - mavutil.mavlink.MAV_CMD_DO_SET_HOME, #command - 0, #confirmation - aCurrent, #param 1: 1 to use current position, 2 to use the entered values. - 0, 0, 0, #params 2-4 - aLocation.lat, - aLocation.lon, - aLocation.alt - ) - # send command to vehicle - vehicle.send_mavlink(msg) - """ @@ -606,9 +582,10 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z): time.sleep(DURATION) send_global_velocity(0,0,0) -print("Set new Home location to current location") -set_home(vehicle.location.global_frame) -print "Get new home location" #This reloads the home location in GCSs +print("Set new home location to current location") +vehicle.home_location=vehicle.location.global_frame +print "Get new home location" +#This reloads the home location in DroneKit and GCSs cmds = vehicle.commands cmds.download() cmds.wait_ready() diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 672b706a2..1f6e9a69f 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -50,16 +50,40 @@ print " Armed: %s" % vehicle.armed # settable -# Get Vehicle Home location -print "\n Home Location (before downloading waypoints): %s" % vehicle.home_location +# Get Vehicle Home location +# Note: home_location attributes will be 0.0 if the autopilot has not yet set the home location. +cmds = vehicle.commands +cmds.download() +cmds.wait_valid() +print " Home Location: %s" % vehicle.home_location + + +# Set vehicle home_location, mode, and armed attributes (the only settable attributes) +print "\nSet new home location" + +# Home location must first have been set by the autopilot before we can set it. +while vehicle.home_location.lat == 0.0: + cmds = vehicle.commands + cmds.download() + cmds.wait_valid() + if vehicle.home_location.lat == 0.0: + print " Waiting for home location: %s" % vehicle.home_location + else: + print "\n Autopilot set home location: %s" % vehicle.home_location + +# Home location must be within 50km of EKF home location (or setting will fail silently) +# In this case, just set value to current location with an easily recognisable altitude (222) +my_location_alt=vehicle.location.global_frame +my_location_alt.alt=222 +vehicle.home_location=my_location_alt +#Confirm it is written out (note that you must re-download commands) cmds = vehicle.commands cmds.download() -cmds.wait_ready() -print " Home Location (after downloading waypoints): %s" % vehicle.home_location +cmds.wait_valid() +print " New Home Location (altitude should be 222): %s" % vehicle.home_location -# Set vehicle mode and armed attributes (the only settable attributes) print "\nSet Vehicle.mode=GUIDED (currently: %s)" % vehicle.mode.name vehicle.mode = VehicleMode("GUIDED") while not vehicle.mode.name=='GUIDED': #Wait until mode has changed From 654282170a60469124cc101bc951facdc52696c4 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 3 Nov 2015 10:45:39 -0800 Subject: [PATCH 122/475] Fixes remaining wait_ready renames. --- dronekit/lib/__init__.py | 6 +++--- examples/mission_import_export/mission_import_export.py | 2 +- examples/vehicle_state/vehicle_state.py | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 022798422..51580074e 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1286,7 +1286,7 @@ class CommandSequence(object): The current commands/mission for a vehicle are accessed using the :py:attr:`Vehicle.commands ` attribute. Waypoints are not downloaded from vehicle until :py:func:`download()` is called. The download is asynchronous; - use :py:func:`wait_valid()` to block your thread until the download is complete. + use :py:func:`wait_ready()` to block your thread until the download is complete. The code to download the commands from a vehicle is shown below: .. code-block:: python @@ -1298,7 +1298,7 @@ class CommandSequence(object): # Download the vehicle waypoints (commands). Wait until download is complete. cmds = vehicle.commands cmds.download() - cmds.wait_valid() + cmds.wait_ready() The set of commands can be changed and uploaded to the client. The changes are not guaranteed to be complete until :py:func:`upload() ` is called. @@ -1342,7 +1342,7 @@ def __init__(self, vehicle): def download(self): ''' Download all waypoints from the vehicle. - The download is asynchronous. Use :py:func:`wait_valid()` to block your thread until the download is complete. + The download is asynchronous. Use :py:func:`wait_ready()` to block your thread until the download is complete. ''' self.wait_ready() self._vehicle._ready_attrs.remove('commands') diff --git a/examples/mission_import_export/mission_import_export.py b/examples/mission_import_export/mission_import_export.py index 0a45e1e23..82dd96108 100644 --- a/examples/mission_import_export/mission_import_export.py +++ b/examples/mission_import_export/mission_import_export.py @@ -89,7 +89,7 @@ def download_mission(): cmds = vehicle.commands cmds.download() cmds.wait_valid() - for cmd in cmds: + for cmd in cmds: missionlist.append(cmd) return missionlist diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 1f6e9a69f..249b33d02 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -54,7 +54,7 @@ # Note: home_location attributes will be 0.0 if the autopilot has not yet set the home location. cmds = vehicle.commands cmds.download() -cmds.wait_valid() +cmds.wait_ready() print " Home Location: %s" % vehicle.home_location @@ -65,7 +65,7 @@ while vehicle.home_location.lat == 0.0: cmds = vehicle.commands cmds.download() - cmds.wait_valid() + cmds.wait_ready() if vehicle.home_location.lat == 0.0: print " Waiting for home location: %s" % vehicle.home_location else: @@ -80,7 +80,7 @@ #Confirm it is written out (note that you must re-download commands) cmds = vehicle.commands cmds.download() -cmds.wait_valid() +cmds.wait_ready() print " New Home Location (altitude should be 222): %s" % vehicle.home_location From 18beb586fc8f7894497e870d9b76e45377e9feeb Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 3 Nov 2015 11:19:59 -0800 Subject: [PATCH 123/475] Adds Parameters.get function. --- dronekit/lib/__init__.py | 5 +++++ tests/sitl/test_parameters.py | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 tests/sitl/test_parameters.py diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 51580074e..54bbae7d5 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1203,6 +1203,11 @@ def __setitem__(self, name, value): self.wait_ready() self.set(name, value) + def get(self, name, wait_ready=True): + if wait_ready: + self.wait_ready() + return self._vehicle._params_map.get(name, None) + def set(self, name, value, retries=3, wait_ready=False): if wait_ready: self.wait_ready() diff --git a/tests/sitl/test_parameters.py b/tests/sitl/test_parameters.py new file mode 100644 index 000000000..21ef1b5f2 --- /dev/null +++ b/tests/sitl/test_parameters.py @@ -0,0 +1,24 @@ +import time +import sys +import os +from dronekit import connect, VehicleMode +from dronekit.tools import with_sitl +from nose.tools import assert_equals, assert_not_equals + +@with_sitl +def test_parameters(connpath): + vehicle = connect(connpath) + + # When called on startup, parameter should return none. + assert_equals(vehicle.parameters.get('THR_MIN', wait_ready=False), None) + + # With wait_ready, it should not be none. + assert_not_equals(vehicle.parameters.get('THR_MIN', wait_ready=True), None) + + try: + assert_not_equals(vehicle.parameters['THR_MIN'], None) + except: + assert False + + # Garbage value after all parameters are downloaded should be None. + assert_equals(vehicle.parameters.get('xXx_extreme_garbage_value_xXx', wait_ready=True), None) From 89eefeb69b36eccf3de5e4e9403713acca33dded Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 3 Nov 2015 12:32:22 -0800 Subject: [PATCH 124/475] 2.0.0rc5 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 44e58487d..2fae18283 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.0.0rc3' +version = '2.0.0rc5' setup(name='dronekit', zip_safe=True, From 2f1f87203cb3fd625c561af1e9efc98a37105286 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 3 Nov 2015 13:18:46 -0800 Subject: [PATCH 125/475] Adds wait_ready to connect, and Vehicle defaults. --- dronekit/__init__.py | 11 ++++++++++- dronekit/lib/__init__.py | 7 +++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index f7935af49..e21cf178e 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -171,7 +171,7 @@ def close(self): time.sleep(0.1) self.master.close() -def connect(ip, await_params=False, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200): +def connect(ip, await_params=False, wait_ready=None, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200): handler = MAVHandler(mavutil.mavlink_connection(ip, baud=baud)) vehicle = vehicle_class(handler) @@ -181,6 +181,15 @@ def listener(self, name, m): status_printer(re.sub(r'(^|\n)', '>>> ', m.text.rstrip())) vehicle.initialize(rate=rate) + + # Legacy / deprecated. if await_params: vehicle.wait_ready('parameters', 'gps_0') + + if wait_ready: + if wait_ready == True: + vehicle.wait_ready(True) + else: + vehicle.wait_ready(*wait_ready) + return vehicle diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 54bbae7d5..4bcb56cae 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -540,6 +540,9 @@ def __init__(self, handler): # By default, we presume all "commands" are loaded. self._ready_attrs = set(['commands']) + # Default parameters when calling wait_ready() or wait_ready(True). + self._default_ready_attrs = ['parameters', 'gps_0', 'armed', 'mode', 'attitude'] + @self.attribute_listener('*') def listener(_, name): self._ready_attrs.add(name) @@ -1149,6 +1152,10 @@ def wait_ready(self, *types, **kwargs): timeout = kwargs.get('timeout', 30) raise_exception = kwargs.get('raise_exception', True) + # Vehicle defaults for wait_ready(True) or wait_ready() + if types == [True] or types == []: + types = self._default_ready_attrs + if not all(isinstance(item, basestring) for item in types): raise APIException('wait_ready expects one or more string arguments.') From 52be5ca8465dafc3e17779836d3f83ca7d343660 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 3 Nov 2015 13:22:29 -0800 Subject: [PATCH 126/475] Replaces await_params with wait_ready. --- README.md | 2 +- docs/examples/create_attribute.rst | 2 +- docs/guide/auto_mode.rst | 10 +++++----- docs/guide/getting_started.rst | 4 ++-- docs/guide/migrating.rst | 4 ++-- docs/guide/taking_off.rst | 2 +- dronekit/__init__.py | 6 +----- dronekit/lib/__init__.py | 14 +++++++------- examples/channel_overrides/channel_overrides.py | 2 +- examples/create_attribute/create_attribute.py | 2 +- examples/drone_delivery/drone_delivery.py | 2 +- examples/flight_replay/flight_replay.py | 2 +- examples/follow_me/follow_me.py | 2 +- examples/gcs/microgcs.py | 2 +- .../guided_set_speed_yaw/guided_set_speed_yaw.py | 2 +- examples/mission_basic/mission_basic.py | 2 +- .../mission_import_export/mission_import_export.py | 2 +- examples/perf/perf_test.py | 2 +- examples/simple_goto/simple_goto.py | 2 +- examples/vehicle_state/vehicle_state.py | 2 +- tests/sitl/test_110.py | 2 +- tests/sitl/test_115.py | 2 +- tests/sitl/test_12.py | 2 +- tests/sitl/test_goto.py | 2 +- tests/sitl/test_localposition.py | 2 +- tests/sitl/test_simpledemo.py | 4 ++-- tests/sitl/test_waypoints.py | 4 ++-- 27 files changed, 41 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index f04ee20af..e27f6856e 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ from dronekit import connect from dronekit.lib import VehicleMode # Connect to UDP endpoint. -vehicle = connect('127.0.0.1:14550', await_params=True) +vehicle = connect('127.0.0.1:14550', wait_ready=True) # Use returned Vehicle object to query device state - e.g. to get the mode: print " Mode: %s" % vehicle.mode.name ``` diff --git a/docs/examples/create_attribute.rst b/docs/examples/create_attribute.rst index 1c35d2408..86bb01e5f 100644 --- a/docs/examples/create_attribute.rst +++ b/docs/examples/create_attribute.rst @@ -124,7 +124,7 @@ All values in the new attribute should be set to ``None`` so that it is obvious .. code:: python # Connect to the Vehicle passed in as args.connect - vehicle = connect(args.connect, await_params=True) + vehicle = connect(args.connect, wait_ready=True) #Create an Vehicle.raw_imu object and set all values to None. vehicle.raw_imu=RawIMU(None,None,None,None,None,None,None,None,None,None) diff --git a/docs/guide/auto_mode.rst b/docs/guide/auto_mode.rst index 3f20ef245..ed00f0c07 100644 --- a/docs/guide/auto_mode.rst +++ b/docs/guide/auto_mode.rst @@ -71,7 +71,7 @@ use :py:func:`wait_ready() ` to block y .. code:: python # Connect to the Vehicle (in this case a simulated vehicle at 127.0.0.1:14550) - vehicle = connect('127.0.0.1:14550', await_params=True) + vehicle = connect('127.0.0.1:14550', wait_ready=True) # Download the vehicle waypoints (commands). Wait until download is complete. cmds = vehicle.commands @@ -96,7 +96,7 @@ To clear a mission you call :py:func:`clear() ` is fully populated with values from the vehicle. Vehicle *attributes* are populated in parallel but are not guaranteed to have values when ``connect()`` completes (an attribute will have value ``None`` if a corresponding MAVLink message has not been received - for example, diff --git a/docs/guide/migrating.rst b/docs/guide/migrating.rst index 14dbfd621..2a2329c7d 100644 --- a/docs/guide/migrating.rst +++ b/docs/guide/migrating.rst @@ -59,10 +59,10 @@ values as were passed to *MAVProxy* when setting up a connection in DKPY 1.x (in from dronekit import connect # Connect to the Vehicle (in this case a UDP endpoint) - vehicle = connect('127.0.0.1:14550', await_params=True) + vehicle = connect('127.0.0.1:14550', wait_ready=True) -The ``await_params=True`` parameter ensures that ``connect()`` won't return until +The ``wait_ready=True`` parameter ensures that ``connect()`` won't return until :py:attr:`Vehicle.parameters ` has been populated. This also allows *MAVLink* messages to arrive from the connected vehicle and populate other ``Vehicle`` attributes. diff --git a/docs/guide/taking_off.rst b/docs/guide/taking_off.rst index 369444125..5f58072f3 100644 --- a/docs/guide/taking_off.rst +++ b/docs/guide/taking_off.rst @@ -25,7 +25,7 @@ The code below shows a function to arm a Copter, take off, and fly to a specifie .. code-block:: python # Connect to the Vehicle (in this case a simulator running the same computer) - vehicle = connect('127.0.0.1:14550', await_params=True) + vehicle = connect('127.0.0.1:14550', wait_ready=True) def arm_and_takeoff(aTargetAltitude): """ diff --git a/dronekit/__init__.py b/dronekit/__init__.py index e21cf178e..c6822c266 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -171,7 +171,7 @@ def close(self): time.sleep(0.1) self.master.close() -def connect(ip, await_params=False, wait_ready=None, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200): +def connect(ip, wait_ready=None, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200): handler = MAVHandler(mavutil.mavlink_connection(ip, baud=baud)) vehicle = vehicle_class(handler) @@ -182,10 +182,6 @@ def listener(self, name, m): vehicle.initialize(rate=rate) - # Legacy / deprecated. - if await_params: - vehicle.wait_ready('parameters', 'gps_0') - if wait_ready: if wait_ready == True: vehicle.wait_ready(True) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 4bcb56cae..89812e409 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -17,7 +17,7 @@ from dronekit import connect # Connect to the Vehicle using "connection string" (in this case an address on network) - vehicle = connect('127.0.0.1:14550', await_params=True) + vehicle = connect('127.0.0.1:14550', wait_ready=True) :py:class:`Vehicle ` provides access to vehicle *state* through python attributes (e.g. :py:attr:`Vehicle.mode `) @@ -39,13 +39,13 @@ .. todo:: Update this when have confirmed how to register for parameter notifications. -.. py:function:: connect(ip, await_params=False, status_printer=errprinter, vehicle_class=Vehicle, rate=4) +.. py:function:: connect(ip, wait_ready=False, status_printer=errprinter, vehicle_class=Vehicle, rate=4) Returns a :py:class:`Vehicle` object connected to the address specified by string parameter ``ip``. Connection string parameters for different targets are listed in the :ref:`getting started guide `. :param String ip: Connection string for target address - e.g. 127.0.0.1:14550. - :param Bool await_params: Wait until all :py:func:`Vehicle.parameters` have downloaded before the method returns (default is false) + :param Bool wait_ready: Wait until all :py:func:`Vehicle.parameters` have downloaded before the method returns (default is false) :param status_printer: NA :param Vehicle vehicle_class: NA :param int rate: NA @@ -1012,7 +1012,7 @@ def home_location(self): .. code-block:: python #Connect to a vehicle object (for example, on com14) - vehicle = connect('com14', await_params=True) + vehicle = connect('com14', wait_ready=True) # Download the vehicle waypoints (commands). Wait until download is complete. cmds = vehicle.commands @@ -1116,7 +1116,7 @@ def message_factory(self): """ return self._master.mav - def initialize(self, await_params=False, rate=None): + def initialize(self, wait_ready=False, rate=None): self._handler.start() # Wait for first heartbeat. @@ -1153,7 +1153,7 @@ def wait_ready(self, *types, **kwargs): raise_exception = kwargs.get('raise_exception', True) # Vehicle defaults for wait_ready(True) or wait_ready() - if types == [True] or types == []: + if list(types) == [True] or list(types) == []: types = self._default_ready_attrs if not all(isinstance(item, basestring) for item in types): @@ -1305,7 +1305,7 @@ class CommandSequence(object): :emphasize-lines: 5-10 #Connect to a vehicle object (for example, on com14) - vehicle = connect('com14', await_params=True) + vehicle = connect('com14', wait_ready=True) # Download the vehicle waypoints (commands). Wait until download is complete. cmds = vehicle.commands diff --git a/examples/channel_overrides/channel_overrides.py b/examples/channel_overrides/channel_overrides.py index 89066ce0b..57f9908ce 100644 --- a/examples/channel_overrides/channel_overrides.py +++ b/examples/channel_overrides/channel_overrides.py @@ -28,7 +28,7 @@ # Connect to the Vehicle print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, await_params=True) +vehicle = connect(args.connect, wait_ready=True) #Override channels print "\nOverriding RC channels for roll and yaw" diff --git a/examples/create_attribute/create_attribute.py b/examples/create_attribute/create_attribute.py index 0bcdd10a2..b629b0d82 100644 --- a/examples/create_attribute/create_attribute.py +++ b/examples/create_attribute/create_attribute.py @@ -26,7 +26,7 @@ # Connect to the Vehicle print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, await_params=True) +vehicle = connect(args.connect, wait_ready=True) diff --git a/examples/drone_delivery/drone_delivery.py b/examples/drone_delivery/drone_delivery.py index 85a1d21bd..e617e99d7 100644 --- a/examples/drone_delivery/drone_delivery.py +++ b/examples/drone_delivery/drone_delivery.py @@ -47,7 +47,7 @@ class Drone(object): def __init__(self, home_coords, server_enabled=True): # Connect to the Vehicle print 'Connecting to vehicle on: %s' % args.connect - self.vehicle = connect(args.connect, await_params=True) + self.vehicle = connect(args.connect, wait_ready=True) print "connected ..." self.gps_lock = False self.altitude = 30.0 diff --git a/examples/flight_replay/flight_replay.py b/examples/flight_replay/flight_replay.py index d77d2f503..6cda9042c 100644 --- a/examples/flight_replay/flight_replay.py +++ b/examples/flight_replay/flight_replay.py @@ -28,7 +28,7 @@ # Connect to the Vehicle print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, await_params=True) +vehicle = connect(args.connect, wait_ready=True) diff --git a/examples/follow_me/follow_me.py b/examples/follow_me/follow_me.py index 2db35cdd7..4f50801db 100644 --- a/examples/follow_me/follow_me.py +++ b/examples/follow_me/follow_me.py @@ -27,7 +27,7 @@ # Connect to the Vehicle print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, await_params=True) +vehicle = connect(args.connect, wait_ready=True) diff --git a/examples/gcs/microgcs.py b/examples/gcs/microgcs.py index 720589416..6e264d00c 100644 --- a/examples/gcs/microgcs.py +++ b/examples/gcs/microgcs.py @@ -20,7 +20,7 @@ # Connect to the Vehicle print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, await_params=True) +vehicle = connect(args.connect, wait_ready=True) def setMode(mode): # Now change the vehicle into auto mode diff --git a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py index e5458fd64..fecc8942d 100644 --- a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py +++ b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py @@ -23,7 +23,7 @@ # Connect to the Vehicle print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, await_params=True) +vehicle = connect(args.connect, wait_ready=True) def arm_and_takeoff(aTargetAltitude): diff --git a/examples/mission_basic/mission_basic.py b/examples/mission_basic/mission_basic.py index 6ef7d5363..6e7e6ba16 100644 --- a/examples/mission_basic/mission_basic.py +++ b/examples/mission_basic/mission_basic.py @@ -21,7 +21,7 @@ # Connect to the Vehicle print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, await_params=True) +vehicle = connect(args.connect, wait_ready=True) def get_location_metres(original_location, dNorth, dEast): diff --git a/examples/mission_import_export/mission_import_export.py b/examples/mission_import_export/mission_import_export.py index 82dd96108..2514f5358 100644 --- a/examples/mission_import_export/mission_import_export.py +++ b/examples/mission_import_export/mission_import_export.py @@ -23,7 +23,7 @@ #Connect to the Vehicle print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, await_params=True) +vehicle = connect(args.connect, wait_ready=True) def readmission(aFileName): diff --git a/examples/perf/perf_test.py b/examples/perf/perf_test.py index 773ced7a8..a4ea8efd1 100644 --- a/examples/perf/perf_test.py +++ b/examples/perf/perf_test.py @@ -110,7 +110,7 @@ # Connect to the Vehicle print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, await_params=True) +vehicle = connect(args.connect, wait_ready=True) #global vehicle diff --git a/examples/simple_goto/simple_goto.py b/examples/simple_goto/simple_goto.py index 10caa358c..c69a73ee5 100644 --- a/examples/simple_goto/simple_goto.py +++ b/examples/simple_goto/simple_goto.py @@ -23,7 +23,7 @@ # Connect to the Vehicle print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, await_params=True) +vehicle = connect(args.connect, wait_ready=True) def arm_and_takeoff(aTargetAltitude): diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 249b33d02..de7dcb703 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -21,7 +21,7 @@ # Connect to the Vehicle print "\nConnecting to vehicle on: %s" % args.connect -vehicle = connect(args.connect, await_params=True) +vehicle = connect(args.connect, wait_ready=True) if vehicle.mode.name == "INITIALISING": print "Waiting for vehicle to initialise" diff --git a/tests/sitl/test_110.py b/tests/sitl/test_110.py index e759815ba..cf28bde23 100644 --- a/tests/sitl/test_110.py +++ b/tests/sitl/test_110.py @@ -7,7 +7,7 @@ @with_sitl def test_110(connpath): - v = connect(connpath, await_params=True) + v = connect(connpath, wait_ready=True) # NOTE these are *very inappropriate settings* # to make on a real vehicle. They are leveraged diff --git a/tests/sitl/test_115.py b/tests/sitl/test_115.py index ed5b0b1f9..7334475d6 100644 --- a/tests/sitl/test_115.py +++ b/tests/sitl/test_115.py @@ -7,7 +7,7 @@ @with_sitl def test_115(connpath): - v = connect(connpath, await_params=True) + v = connect(connpath, wait_ready=True) # Dummy callback def mavlink_callback(*args): diff --git a/tests/sitl/test_12.py b/tests/sitl/test_12.py index 71d25e5fd..a3e8b8b7f 100644 --- a/tests/sitl/test_12.py +++ b/tests/sitl/test_12.py @@ -10,7 +10,7 @@ def current_milli_time(): @with_sitl def test_timeout(connpath): - v = connect(connpath, await_params=True) + v = connect(connpath, wait_ready=True) value = v.parameters['THR_MIN'] assert_equals(type(value), float) diff --git a/tests/sitl/test_goto.py b/tests/sitl/test_goto.py index 31de61d57..89cbbff19 100644 --- a/tests/sitl/test_goto.py +++ b/tests/sitl/test_goto.py @@ -14,7 +14,7 @@ @with_sitl def test_goto(connpath): - vehicle = connect(connpath, await_params=True) + vehicle = connect(connpath, wait_ready=True) # NOTE these are *very inappropriate settings* # to make on a real vehicle. They are leveraged diff --git a/tests/sitl/test_localposition.py b/tests/sitl/test_localposition.py index e3e116a67..013ba44a1 100644 --- a/tests/sitl/test_localposition.py +++ b/tests/sitl/test_localposition.py @@ -5,7 +5,7 @@ @with_sitl def test_timeout(connpath): - vehicle = connect(connpath, await_params=True) + vehicle = connect(connpath, wait_ready=True) # NOTE these are *very inappropriate settings* # to make on a real vehicle. They are leveraged diff --git a/tests/sitl/test_simpledemo.py b/tests/sitl/test_simpledemo.py index e3abe755d..04539b12e 100644 --- a/tests/sitl/test_simpledemo.py +++ b/tests/sitl/test_simpledemo.py @@ -13,7 +13,7 @@ # This test runs first! @with_sitl def test_parameter(connpath): - v = connect(connpath, await_params=True) + v = connect(connpath, wait_ready=True) # Perform a simple parameter check assert_equals(type(v.parameters['THR_MIN']), float) @@ -21,7 +21,7 @@ def test_parameter(connpath): # This test runs second. Add as many tests as you like @with_sitl def test_mode(connpath): - v = connect(connpath, await_params=True) + v = connect(connpath, wait_ready=True) # Ensure Mode is an instance of VehicleMode assert isinstance(v.mode, VehicleMode) diff --git a/tests/sitl/test_waypoints.py b/tests/sitl/test_waypoints.py index 21818ff1b..a8d968199 100644 --- a/tests/sitl/test_waypoints.py +++ b/tests/sitl/test_waypoints.py @@ -16,7 +16,7 @@ def test_empty_clear(connpath): @with_sitl def test_set_home(connpath): - vehicle = connect(connpath, await_params=True) + vehicle = connect(connpath, wait_ready=True) # Wait for home position to be real and not 0, 0, 0 # once we request it via cmds.download() @@ -38,7 +38,7 @@ def test_set_home(connpath): @with_sitl def test_parameter(connpath): - vehicle = connect(connpath, await_params=True) + vehicle = connect(connpath, wait_ready=True) # Home should be None at first. assert_equals(vehicle.home_location, None) From b1cdb3885ca5cd6e210bb73934a0c4b883743e75 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 3 Nov 2015 16:08:06 -0800 Subject: [PATCH 127/475] Fixes SITL importing. --- dronekit/tools/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/tools/__init__.py b/dronekit/tools/__init__.py index 8b0d9e9c4..6593f97e8 100644 --- a/dronekit/tools/__init__.py +++ b/dronekit/tools/__init__.py @@ -1,7 +1,6 @@ from __future__ import print_function import os import sys -from dronekit_sitl import SITL sitl = None sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] @@ -12,6 +11,7 @@ sitl_args += ['-r', str(os.environ['SITL_RATE'])] def setup_sitl(): + from dronekit_sitl import SITL global sitl sitl = SITL('copter', '3.3-rc5') sitl.launch(sitl_args, await_ready=True, restart=True) From a2cac1d8bd6ad7e53411db8aae065f711ef12ebd Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 3 Nov 2015 16:08:15 -0800 Subject: [PATCH 128/475] 2.0.0rc6 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 2fae18283..f8549d23b 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.0.0rc5' +version = '2.0.0rc6' setup(name='dronekit', zip_safe=True, From 9a58c9cd3d55c6659827071f3037998235ac190c Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 3 Nov 2015 16:30:26 -0800 Subject: [PATCH 129/475] Moves tests to dronekit.test folder. --- .travis.yml | 6 +++--- appveyor.yml | 6 +++--- circle.yml | 6 +++--- dronekit/__init__.py | 2 +- dronekit/lib/__init__.py | 2 +- {tests => dronekit/test}/README.md | 0 dronekit/{tools => test}/__init__.py | 7 ++----- {tests => dronekit/test/sitl}/__init__.py | 0 {tests => dronekit/test}/sitl/test_110.py | 2 +- {tests => dronekit/test}/sitl/test_115.py | 2 +- {tests => dronekit/test}/sitl/test_12.py | 2 +- {tests => dronekit/test}/sitl/test_goto.py | 2 +- {tests => dronekit/test}/sitl/test_localposition.py | 2 +- {tests => dronekit/test}/sitl/test_parameters.py | 2 +- {tests => dronekit/test}/sitl/test_simpledemo.py | 2 +- {tests => dronekit/test}/sitl/test_vehicleclass.py | 2 +- {tests => dronekit/test}/sitl/test_waypoints.py | 2 +- {tests/sitl => dronekit/test/unit}/__init__.py | 0 {tests => dronekit/test}/unit/test_api.py | 0 {tests => dronekit/test}/web/__init__.py | 0 {tests => dronekit/test}/web/cloud_client_test.py | 0 dronekit/util.py | 5 +++++ setup.py | 2 +- tests/unit/__init__.py | 0 24 files changed, 28 insertions(+), 26 deletions(-) rename {tests => dronekit/test}/README.md (100%) rename dronekit/{tools => test}/__init__.py (82%) rename {tests => dronekit/test/sitl}/__init__.py (100%) rename {tests => dronekit/test}/sitl/test_110.py (98%) rename {tests => dronekit/test}/sitl/test_115.py (96%) rename {tests => dronekit/test}/sitl/test_12.py (95%) rename {tests => dronekit/test}/sitl/test_goto.py (98%) rename {tests => dronekit/test}/sitl/test_localposition.py (96%) rename {tests => dronekit/test}/sitl/test_parameters.py (95%) rename {tests => dronekit/test}/sitl/test_simpledemo.py (94%) rename {tests => dronekit/test}/sitl/test_vehicleclass.py (92%) rename {tests => dronekit/test}/sitl/test_waypoints.py (98%) rename {tests/sitl => dronekit/test/unit}/__init__.py (100%) rename {tests => dronekit/test}/unit/test_api.py (100%) rename {tests => dronekit/test}/web/__init__.py (100%) rename {tests => dronekit/test}/web/cloud_client_test.py (100%) create mode 100644 dronekit/util.py delete mode 100644 tests/unit/__init__.py diff --git a/.travis.yml b/.travis.yml index a061c5378..ac9c1f0ba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,9 +11,9 @@ install: - 'sudo pip install -r requirements.txt -UI' script: - - '[ "${TRAVIS_PULL_REQUEST}" != "false" ] || nosetests tests/web' - - 'nosetests tests/unit' - - 'nosetests tests/sitl' + - '[ "${TRAVIS_PULL_REQUEST}" != "false" ] || nosetests dronekit.test.web' + - 'nosetests dronekit.test.unit' + - 'nosetests dronekit.test.sitl' git: depth: 10 diff --git a/appveyor.yml b/appveyor.yml index 26ffd8f44..6c4aac62e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -25,9 +25,9 @@ install: - cmd: 'pip install -r requirements.txt -UI' build_script: - - cmd: 'nosetests tests\\web' - - cmd: 'nosetests -s -v tests\\sitl || nosetests -s -v tests\\sitl || nosetests -s -v tests\\sitl || nosetests -s -v tests\\sitl' - - cmd: 'nosetests tests\\unit' + - cmd: 'nosetests dronekit.test.web' + - cmd: 'nosetests dronekit.test.unit' + - cmd: 'nosetests -sv dronekit.test.sitl || nosetests -sv dronekit.test.sitl || nosetests -sv dronekit.test.sitl || nosetests -sv dronekit.test.sitl' clone_depth: 10 test: 'off' diff --git a/circle.yml b/circle.yml index 62b0bb8c7..a61d9ecd0 100644 --- a/circle.yml +++ b/circle.yml @@ -10,9 +10,9 @@ dependencies: test: override: - - 'nosetests tests/web' - - 'nosetests tests/unit' - - 'nosetests tests/sitl' + - 'nosetests dronekit.test.web' + - 'nosetests dronekit.test.unit' + - 'nosetests dronekit.test.sitl' general: build_dir: . diff --git a/dronekit/__init__.py b/dronekit/__init__.py index c6822c266..6c27cb37d 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -6,7 +6,7 @@ import platform import re import dronekit.lib -from dronekit.tools import errprinter +from dronekit.util import errprinter from pymavlink import mavutil, mavwp from Queue import Queue, Empty from threading import Thread diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 89812e409..2c2f02c51 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -4,7 +4,7 @@ import CloudClient from pymavlink.dialects.v10 import ardupilotmega from pymavlink import mavutil, mavwp -from dronekit.tools import errprinter +from dronekit.util import errprinter """ This is the API Reference for the DroneKit-Python API. diff --git a/tests/README.md b/dronekit/test/README.md similarity index 100% rename from tests/README.md rename to dronekit/test/README.md diff --git a/dronekit/tools/__init__.py b/dronekit/test/__init__.py similarity index 82% rename from dronekit/tools/__init__.py rename to dronekit/test/__init__.py index 6593f97e8..b533a1d57 100644 --- a/dronekit/tools/__init__.py +++ b/dronekit/test/__init__.py @@ -1,6 +1,8 @@ from __future__ import print_function import os import sys +from dronekit_sitl import SITL +from nose.tools import assert_equals, with_setup sitl = None sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] @@ -11,7 +13,6 @@ sitl_args += ['-r', str(os.environ['SITL_RATE'])] def setup_sitl(): - from dronekit_sitl import SITL global sitl sitl = SITL('copter', '3.3-rc5') sitl.launch(sitl_args, await_ready=True, restart=True) @@ -20,11 +21,7 @@ def teardown_sitl(): sitl.stop() def with_sitl(fn): - from nose.tools import assert_equals, with_setup @with_setup(setup_sitl, teardown_sitl) def test(*args, **kargs): return fn('tcp:127.0.0.1:5760', *args, **kargs) return test - -def errprinter(*args): - print(*args, file=sys.stderr) diff --git a/tests/__init__.py b/dronekit/test/sitl/__init__.py similarity index 100% rename from tests/__init__.py rename to dronekit/test/sitl/__init__.py diff --git a/tests/sitl/test_110.py b/dronekit/test/sitl/test_110.py similarity index 98% rename from tests/sitl/test_110.py rename to dronekit/test/sitl/test_110.py index cf28bde23..3baa8ab1a 100644 --- a/tests/sitl/test_110.py +++ b/dronekit/test/sitl/test_110.py @@ -2,7 +2,7 @@ import sys import os from dronekit import connect, VehicleMode -from dronekit.tools import with_sitl +from dronekit.test import with_sitl from nose.tools import assert_equals @with_sitl diff --git a/tests/sitl/test_115.py b/dronekit/test/sitl/test_115.py similarity index 96% rename from tests/sitl/test_115.py rename to dronekit/test/sitl/test_115.py index 7334475d6..3ab48c905 100644 --- a/tests/sitl/test_115.py +++ b/dronekit/test/sitl/test_115.py @@ -2,7 +2,7 @@ import sys import os from dronekit import connect, VehicleMode -from dronekit.tools import with_sitl +from dronekit.test import with_sitl from nose.tools import assert_equals @with_sitl diff --git a/tests/sitl/test_12.py b/dronekit/test/sitl/test_12.py similarity index 95% rename from tests/sitl/test_12.py rename to dronekit/test/sitl/test_12.py index a3e8b8b7f..1489f831f 100644 --- a/tests/sitl/test_12.py +++ b/dronekit/test/sitl/test_12.py @@ -2,7 +2,7 @@ import sys import os from dronekit import connect, VehicleMode -from dronekit.tools import with_sitl +from dronekit.test import with_sitl from nose.tools import assert_equals def current_milli_time(): diff --git a/tests/sitl/test_goto.py b/dronekit/test/sitl/test_goto.py similarity index 98% rename from tests/sitl/test_goto.py rename to dronekit/test/sitl/test_goto.py index 89cbbff19..57b6f4ae7 100644 --- a/tests/sitl/test_goto.py +++ b/dronekit/test/sitl/test_goto.py @@ -9,7 +9,7 @@ import time from dronekit import connect, VehicleMode, LocationGlobal -from dronekit.tools import with_sitl +from dronekit.test import with_sitl from nose.tools import assert_equals @with_sitl diff --git a/tests/sitl/test_localposition.py b/dronekit/test/sitl/test_localposition.py similarity index 96% rename from tests/sitl/test_localposition.py rename to dronekit/test/sitl/test_localposition.py index 013ba44a1..9cdd992d3 100644 --- a/tests/sitl/test_localposition.py +++ b/dronekit/test/sitl/test_localposition.py @@ -1,6 +1,6 @@ import time from dronekit import connect, VehicleMode, LocationGlobal -from dronekit.tools import with_sitl +from dronekit.test import with_sitl from nose.tools import assert_not_equals @with_sitl diff --git a/tests/sitl/test_parameters.py b/dronekit/test/sitl/test_parameters.py similarity index 95% rename from tests/sitl/test_parameters.py rename to dronekit/test/sitl/test_parameters.py index 21ef1b5f2..05a6cb6ee 100644 --- a/tests/sitl/test_parameters.py +++ b/dronekit/test/sitl/test_parameters.py @@ -2,7 +2,7 @@ import sys import os from dronekit import connect, VehicleMode -from dronekit.tools import with_sitl +from dronekit.test import with_sitl from nose.tools import assert_equals, assert_not_equals @with_sitl diff --git a/tests/sitl/test_simpledemo.py b/dronekit/test/sitl/test_simpledemo.py similarity index 94% rename from tests/sitl/test_simpledemo.py rename to dronekit/test/sitl/test_simpledemo.py index 04539b12e..8ed4d14bd 100644 --- a/tests/sitl/test_simpledemo.py +++ b/dronekit/test/sitl/test_simpledemo.py @@ -7,7 +7,7 @@ import sys import os from dronekit import connect, VehicleMode -from dronekit.tools import with_sitl +from dronekit.test import with_sitl from nose.tools import assert_equals # This test runs first! diff --git a/tests/sitl/test_vehicleclass.py b/dronekit/test/sitl/test_vehicleclass.py similarity index 92% rename from tests/sitl/test_vehicleclass.py rename to dronekit/test/sitl/test_vehicleclass.py index 551691f89..f32ad2ee0 100644 --- a/tests/sitl/test_vehicleclass.py +++ b/dronekit/test/sitl/test_vehicleclass.py @@ -1,6 +1,6 @@ import time from dronekit import connect, Vehicle -from dronekit.tools import with_sitl +from dronekit.test import with_sitl from nose.tools import assert_equals class DummyVehicle(Vehicle): diff --git a/tests/sitl/test_waypoints.py b/dronekit/test/sitl/test_waypoints.py similarity index 98% rename from tests/sitl/test_waypoints.py rename to dronekit/test/sitl/test_waypoints.py index a8d968199..5f114ec41 100644 --- a/tests/sitl/test_waypoints.py +++ b/dronekit/test/sitl/test_waypoints.py @@ -1,7 +1,7 @@ import time import math from dronekit import connect, VehicleMode, LocationGlobal, Command -from dronekit.tools import with_sitl +from dronekit.test import with_sitl from nose.tools import assert_not_equals, assert_equals @with_sitl diff --git a/tests/sitl/__init__.py b/dronekit/test/unit/__init__.py similarity index 100% rename from tests/sitl/__init__.py rename to dronekit/test/unit/__init__.py diff --git a/tests/unit/test_api.py b/dronekit/test/unit/test_api.py similarity index 100% rename from tests/unit/test_api.py rename to dronekit/test/unit/test_api.py diff --git a/tests/web/__init__.py b/dronekit/test/web/__init__.py similarity index 100% rename from tests/web/__init__.py rename to dronekit/test/web/__init__.py diff --git a/tests/web/cloud_client_test.py b/dronekit/test/web/cloud_client_test.py similarity index 100% rename from tests/web/cloud_client_test.py rename to dronekit/test/web/cloud_client_test.py diff --git a/dronekit/util.py b/dronekit/util.py new file mode 100644 index 000000000..793475900 --- /dev/null +++ b/dronekit/util.py @@ -0,0 +1,5 @@ +from __future__ import print_function +import sys + +def errprinter(*args): + print(*args, file=sys.stderr) diff --git a/setup.py b/setup.py index f8549d23b..f1b83deaa 100644 --- a/setup.py +++ b/setup.py @@ -26,6 +26,6 @@ ], license='apache', packages=[ - 'dronekit', 'dronekit.lib' + 'dronekit', 'dronekit.lib', 'dronekit.test', ], ext_modules=[]) diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py deleted file mode 100644 index e69de29bb..000000000 From 80325181bd46a39dce5d378ae98c304e6481da3a Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 3 Nov 2015 17:14:24 -0800 Subject: [PATCH 130/475] 2.0.0rc7 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index f1b83deaa..c1dddcc87 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.0.0rc6' +version = '2.0.0rc7' setup(name='dronekit', zip_safe=True, From ef53e5fd793246836e0b434ba300f6618cc4909f Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 4 Nov 2015 12:23:36 +1100 Subject: [PATCH 131/475] Fix errors in API ref generation due to file structure --- dronekit/lib/__init__.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 2c2f02c51..9145fa322 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1,11 +1,3 @@ -# DroneAPI module - -import threading, time, math, copy -import CloudClient -from pymavlink.dialects.v10 import ardupilotmega -from pymavlink import mavutil, mavwp -from dronekit.util import errprinter - """ This is the API Reference for the DroneKit-Python API. @@ -58,6 +50,14 @@ """ +# DroneAPI module + +import threading, time, math, copy +import CloudClient +from pymavlink.dialects.v10 import ardupilotmega +from pymavlink import mavutil, mavwp +from dronekit.util import errprinter + local_path = '' class APIException(Exception): @@ -343,6 +343,7 @@ def attribute_listener(self, name): Decorator for attribute listeners. .. code:: python + @vehicle.attribute_listener('attitude') def attitude_listener(self, name, msg): pass @@ -838,6 +839,7 @@ def message_listener(self, name): Decorator for message listeners. .. code:: python + @vehicle.message_listener('HEARTBEAT') def my_method(self, name, msg): pass @@ -1316,6 +1318,7 @@ class CommandSequence(object): :py:func:`upload() ` is called. .. code:: python + cmds = vehicle.commands cmds.clear() lat = -34.364114, @@ -1426,7 +1429,10 @@ def add(self, cmd): ''' Add a new command (waypoint) at the end of the command list. - .. note:: Commands are sent to the vehicle only after you call ::py:func:`upload() `. + .. note:: + + Commands are sent to the vehicle only after you call ::py:func:`upload() `. + :param Command cmd: The command to be added. ''' self.wait_ready() From 0e01e7a80518880f6689dc56bcf32a2741a58785 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 4 Nov 2015 11:56:25 +1100 Subject: [PATCH 132/475] Add docs on new connect baud parameter - #393. Fix up the debugging doc - #118, Fix auto-mode doc use of slice. Remove excluded methods from automodule generation as these are not longer present in init --- docs/automodule.rst | 2 +- docs/guide/auto_mode.rst | 2 +- docs/guide/debugging.rst | 99 +++++++++++----------------------- docs/guide/getting_started.rst | 6 ++- docs/guide/migrating.rst | 8 +++ dronekit/lib/__init__.py | 12 +++-- 6 files changed, 55 insertions(+), 74 deletions(-) diff --git a/docs/automodule.rst b/docs/automodule.rst index f79944102..e8a9b1632 100644 --- a/docs/automodule.rst +++ b/docs/automodule.rst @@ -8,7 +8,7 @@ DroneKit-Python API Reference .. automodule:: dronekit.lib :members: :inherited-members: - :exclude-members: Mission, get_mission, ConnectionInfo, web_connect, AuthInfo, delete, notify_observers, remove_all_observers, local_connect, APIConnection, flush + :exclude-members: diff --git a/docs/guide/auto_mode.rst b/docs/guide/auto_mode.rst index ed00f0c07..4a4e8dcd6 100644 --- a/docs/guide/auto_mode.rst +++ b/docs/guide/auto_mode.rst @@ -371,7 +371,7 @@ adds them to a list. Downloading mission is discussed :ref:`in the guide `_. +The `Python Debugger - pdb `_ can be used to debug *DroneKit-Python* apps. +The command below can be used to run a script in debug mode: -Print/log statements -==================== +.. code-block:: bash -The simplest and most common method of debugging is to manually add debug/print statements to the source. + python -m pdb my_dronekit_script.py + +You can also instrument your code to invoke the debugger at a certain point. To do this +add ``set-trace()`` at the point where you want to break execution: .. code-block:: python - :emphasize-lines: 6 + :emphasize-lines: 4 - # Get the vehicle - api = local_connect() - vehicle = api.get_vehicles()[0] + # Connect to the Vehicle on udp at 127.0.0.1:14550 + vehicle = connect('127.0.0.1:14550', wait_ready=True) - # print out debug information - print "Location: %s" % vehicle.location - -In addition to printing DroneKit variables, Python provides numerous inbuilt and add-on modules/methods -for inspecting code (e.g. `dir() `_, `traceback `_, etc.) + import pdb; pdb.set_trace() + print "Global Location: %s" % vehicle.location.global_frame -pdb - The Python Debugger -========================= +The available `debugger commands are listed here `_. + -The `Python Debugger - pdb `_ can be used to debug *DroneKit-Python* apps. -To start debugging, add ``set-trace()`` at the point where you want to break execution (as shown below): + +Print/log statements +==================== +The simplest and most common method of debugging is to manually add debug/print statements to the source. .. code-block:: python - :emphasize-lines: 5 - - # Get the vehicle - api = local_connect() - vehicle = api.get_vehicles()[0] - - import pdb; pdb.set_trace() - print "Location: %s" % v.location - -When you run the app, the code will stop at the marked line: - -.. code:: bash + :emphasize-lines: 4 - MAV> api start small_demo.py - AUTO> > c:\users\hamis_000\documents\vagranttesting\tmpdeleteme\small_demo.py(20)() - -> print "Location: %s" % v.location - -Press **Enter** to bring up the **(Pdb)** prompt. This is where you can enter the commands to step through the code, show stack traces, -etc. For example the console output below shows the **w** command being used to output the current stack trace. + # Connect to the Vehicle on udp at 127.0.0.1:14550 + vehicle = connect('127.0.0.1:14550', wait_ready=True) -.. code:: bash - - AUTO> - (Pdb) w - c:\users\hamis_000\downloads\winpython-64bit-2.7.6.4\python-2.7.6.amd64\lib\threading.py(783)__bootstrap() - cAUTO> :\users\hamis_000\downloads\winpython-64bit-2.7.6.4\python-2.7.6.amd64\lib\site-packages\dronekit\module\api.py(321)run() - -> self.fn()amis_000\downloads\winpython-64bit-2.7.6.4\python-2.7.6.amd64\lib\threading.py(810)__bootstrap_inner() - c:\users\hamis_000\downloads\winpython-64bit-2.7.6.4\python-2.7.6.amd64\lib\site-packages\dronekit\module\api.py(592)() - -> APIThread(self, lambda: execfile(args[1], g), args[1]) - -The available `debugger commands are listed here `_. For more information -about *pdb* see the `Python Debugger site `_. - -.. note:: - - *Pdb* commands must be entered in the **(Pdb)** prompt. If you press "Enter" in an empty prompt the previous command will be called - again. This is helpful if you want to **s** (step) through every line of code. + # print out debug information + print "Global Location: %s" % vehicle.location.global_frame +In addition to printing DroneKit variables, Python provides numerous inbuilt and add-on modules/methods +for inspecting code (e.g. `dir() `_, `traceback `_, etc.) -Other debuggers -=============== -At time of writing we don't have information about how to debug DroneKit apps with other debuggers (although anecdotally *gdb* has -successfully been used). +Other IDEs/debuggers +==================== -If you have information about how to set up and use other debuggers with DroneKit, please :ref:`contribute them `. \ No newline at end of file +There is no reason you should not be able to straightforwardly use other popular Python IDEs including IDLE and Eclipse. \ No newline at end of file diff --git a/docs/guide/getting_started.rst b/docs/guide/getting_started.rst index 73625e3ce..f771a7dbd 100644 --- a/docs/guide/getting_started.rst +++ b/docs/guide/getting_started.rst @@ -137,7 +137,11 @@ the more common connection types: * - Linux computer connected to the vehicle via USB - ``/dev/ttyUSB0`` * - Linux computer connected to the vehicle via Serial port (RaspberryPi example) - - ``/dev/ttyAMA0,57600`` + - ``/dev/ttyAMA0`` + + .. note:: + To connect on a serial port you may also need to reduce the baud rate to 57600 + - e.g. ``vehicle=connect('/dev/ttyAMA0', baud=57600)`` * - SITL connected to the vehicle via UDP - ``127.0.0.1:14550`` * - OSX computer connected to the vehicle via USB diff --git a/docs/guide/migrating.rst b/docs/guide/migrating.rst index 2a2329c7d..4120b8673 100644 --- a/docs/guide/migrating.rst +++ b/docs/guide/migrating.rst @@ -174,4 +174,12 @@ This code must be replaced with the DroneKit-Python 2.x :py:attr:`Vehicle.home_l :py:attr:`Vehicle.home_location `. +Debugging +========= + +DroneKit-Python 1.x scripts were run in the context of a MAVProxy. This made them difficult to debug because you had to +instrument your code in order to launch the debugger, and debug messages were interleaved with MAVProxy output. + +Debugging on DroneKit-Python 2.x is much easier. Apps are now just standalone scripts, and can be debugged +using standard Python methods (including the debugger/IDE of your choice). diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 9145fa322..cca0009dc 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -31,7 +31,7 @@ .. todo:: Update this when have confirmed how to register for parameter notifications. -.. py:function:: connect(ip, wait_ready=False, status_printer=errprinter, vehicle_class=Vehicle, rate=4) +.. py:function:: connect(ip, wait_ready=False, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200) Returns a :py:class:`Vehicle` object connected to the address specified by string parameter ``ip``. Connection string parameters for different targets are listed in the :ref:`getting started guide `. @@ -41,13 +41,17 @@ :param status_printer: NA :param Vehicle vehicle_class: NA :param int rate: NA - + :param int baud: The baud rate for the connection. The default is 115200. + :returns: A connected :py:class:`Vehicle` object. ---- - .. todo:: Confirm what status_printer, vehicle_class and rate "mean". Can we hide in API. Can we get method defined in this file. - + .. todo:: + + Confirm what status_printer, vehicle_class and rate "mean" (https://github.com/dronekit/dronekit-python/issues/395#issuecomment-153527657) + Can we hide in API. Can we get method defined in this file or connect method file exported + """ # DroneAPI module From c85cb73c25861b62b75df626caada43ebe273822 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 3 Nov 2015 12:31:48 -0800 Subject: [PATCH 133/475] Reworks timeout logic. Supports hard timeout of 30s. --- dronekit/__init__.py | 15 ++++++++++----- dronekit/lib/__init__.py | 23 +++++++++++++++-------- tests/sitl/test_timeout.py | 20 ++++++++++++++++++++ 3 files changed, 45 insertions(+), 13 deletions(-) create mode 100644 tests/sitl/test_timeout.py diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 6c27cb37d..d8b4f12c3 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -56,10 +56,13 @@ def __init__(self, master, vehicle_class=Vehicle): self.loop_listeners = [] self.message_listeners = [] + # Debug flag. + self._accept_input = True + self._alive = True + import atexit - self.exiting = False def onexit(): - self.exiting = True + self._alive = False atexit.register(onexit) def mavlink_thread(): @@ -99,7 +102,7 @@ def mavlink_thread(): errprinter('mav send error:', e) break - while True: + while self._accept_input: try: msg = self.master.recv_msg() except socket.error as error: @@ -132,9 +135,11 @@ def mavlink_thread(): except Exception as e: # http://bugs.python.org/issue1856 - if self.exiting: + if not self._alive: pass else: + self._alive = False + self.master.close() raise t = Thread(target=mavlink_thread) @@ -166,7 +171,7 @@ def start(self): def close(self): # TODO this can block forever if parameters continue to be added - self.exiting = True + self._alive = False while not self.out_queue.empty(): time.sleep(0.1) self.master.close() diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index cca0009dc..9c436d97c 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -817,6 +817,10 @@ def listener(self, name, msg): self._heartbeat_started = False self._heartbeat_lastsent = 0 self._heartbeat_lastreceived = 0 + self._heartbeat_timeout = False + + self._heartbeat_warning = 5 + self._heartbeat_error = 30 @handler.loop_listener def listener(_): @@ -825,18 +829,21 @@ def listener(_): self._master.mav.heartbeat_send(mavutil.mavlink.MAV_TYPE_GCS, mavutil.mavlink.MAV_AUTOPILOT_INVALID, 0, 0, 0) self._heartbeat_lastsent = time.time() - # And timeout after 5. - if self._heartbeat_started: - if self._heartbeat_lastreceived == 0: - self._heartbeat_lastreceived = time.time() - elif time.time() - self._heartbeat_lastreceived > 5: - # raise Exception('Link timeout, no heartbeat in last 5 seconds') - errprinter('Link timeout, no heartbeat in last 5 seconds') - self._heartbeat_lastreceived = time.time() + # Timeouts. + if self._heartbeat_started and self._heartbeat_lastreceived != 0: + if time.time() - self._heartbeat_lastreceived > self._heartbeat_error: + raise Exception('>>> No heartbeat in %s seconds, aborting.' % self._heartbeat_error) + elif time.time() - self._heartbeat_lastreceived > self._heartbeat_warning: + if self._heartbeat_timeout == False: + errprinter('>>> Link timeout, no heartbeat in last %s seconds' % self._heartbeat_warning) + self._heartbeat_timeout = True @self.message_listener(['HEARTBEAT']) def listener(self, name, msg): self._heartbeat_lastreceived = time.time() + if self._heartbeat_timeout: + errprinter('>>> ...link restored.') + self._heartbeat_timeout = False def message_listener(self, name): """ diff --git a/tests/sitl/test_timeout.py b/tests/sitl/test_timeout.py new file mode 100644 index 000000000..6bef43251 --- /dev/null +++ b/tests/sitl/test_timeout.py @@ -0,0 +1,20 @@ +import time +import sys +import os +from dronekit import connect, VehicleMode +from dronekit.tools import with_sitl +from nose.tools import assert_equals + +@with_sitl +def test_timeout(connpath): + vehicle = connect(connpath, await_params=True) + + # Stall input and lower error threshold to 10 seconds. + vehicle._heartbeat_error = 10 + vehicle._handler._accept_input = False + + start = time.time() + while vehicle._handler._alive and time.time() - start < 20: + time.sleep(.1) + + assert_equals(vehicle._handler._alive, False) From b8b7d5eb7ac03c10343deb3ed3384bc1a168cb78 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 5 Nov 2015 10:38:02 -0800 Subject: [PATCH 134/475] Fixes Windows tests by closing connections. --- appveyor.yml | 8 ++++---- dronekit/__init__.py | 4 ++-- dronekit/lib/__init__.py | 2 +- dronekit/test/sitl/test_110.py | 2 ++ dronekit/test/sitl/test_115.py | 2 ++ dronekit/test/sitl/test_12.py | 2 ++ dronekit/test/sitl/test_goto.py | 2 ++ dronekit/test/sitl/test_localposition.py | 3 +++ dronekit/test/sitl/test_parameters.py | 2 ++ dronekit/test/sitl/test_simpledemo.py | 4 ++++ dronekit/test/sitl/test_vehicleclass.py | 2 ++ dronekit/test/sitl/test_waypoints.py | 4 ++++ dronekit/util.py | 1 + 13 files changed, 31 insertions(+), 7 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 6c4aac62e..e49df033b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ environment: global: - SITL_SPEEDUP: 20 + SITL_SPEEDUP: 10 SITL_RATE: 200 cache: @@ -25,9 +25,9 @@ install: - cmd: 'pip install -r requirements.txt -UI' build_script: - - cmd: 'nosetests dronekit.test.web' - - cmd: 'nosetests dronekit.test.unit' - - cmd: 'nosetests -sv dronekit.test.sitl || nosetests -sv dronekit.test.sitl || nosetests -sv dronekit.test.sitl || nosetests -sv dronekit.test.sitl' + - cmd: 'nosetests -vx dronekit.test.web' + - cmd: 'nosetests -vx dronekit.test.unit' + - cmd: 'nosetests -svx dronekit.test.sitl' clone_depth: 10 test: 'off' diff --git a/dronekit/__init__.py b/dronekit/__init__.py index d8b4f12c3..37f6f3e74 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -83,7 +83,7 @@ def mavlink_thread(): self.master.write(msg) except socket.error as error: if error.errno == ECONNABORTED: - errprinter('reestablishing connection after read timeout') + errprinter('>>> reestablishing connection after read aborted') if hasattr(self.master, 'reset'): self.master.reset() else: @@ -107,7 +107,7 @@ def mavlink_thread(): msg = self.master.recv_msg() except socket.error as error: if error.errno == ECONNABORTED: - errprinter('reestablishing connection after send timeout') + errprinter('>>> reestablishing connection after send aborted') if hasattr(self.master, 'reset'): self.master.reset() else: diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 9c436d97c..2c3f17456 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -820,7 +820,7 @@ def listener(self, name, msg): self._heartbeat_timeout = False self._heartbeat_warning = 5 - self._heartbeat_error = 30 + self._heartbeat_error = 60 @handler.loop_listener def listener(_): diff --git a/dronekit/test/sitl/test_110.py b/dronekit/test/sitl/test_110.py index 3baa8ab1a..4560a2ad1 100644 --- a/dronekit/test/sitl/test_110.py +++ b/dronekit/test/sitl/test_110.py @@ -60,3 +60,5 @@ def armed_callback(vehicle, attribute): # Ensure the callback was called zero times. assert_equals(armed_callback.called, callcount, "Callback should not have been called once removed.") + + v.close() diff --git a/dronekit/test/sitl/test_115.py b/dronekit/test/sitl/test_115.py index 3ab48c905..bbf6474e5 100644 --- a/dronekit/test/sitl/test_115.py +++ b/dronekit/test/sitl/test_115.py @@ -41,3 +41,5 @@ def mavlink_callback(*args): v.armed = True # NOTE wait crudely for ACK on mode update time.sleep(3) + + v.close() diff --git a/dronekit/test/sitl/test_12.py b/dronekit/test/sitl/test_12.py index 1489f831f..e89e6a7ed 100644 --- a/dronekit/test/sitl/test_12.py +++ b/dronekit/test/sitl/test_12.py @@ -26,3 +26,5 @@ def test_timeout(connpath): # Checks that time to set parameter was <1s # see https://github.com/dronekit/dronekit-python/issues/12 assert end - start < 1000, 'time to set parameter was %s, over 1s' % (end - start,) + + v.close() diff --git a/dronekit/test/sitl/test_goto.py b/dronekit/test/sitl/test_goto.py index 57b6f4ae7..7f0547e42 100644 --- a/dronekit/test/sitl/test_goto.py +++ b/dronekit/test/sitl/test_goto.py @@ -94,3 +94,5 @@ def arm_and_takeoff(aTargetAltitude): # print "Returning to Launch" vehicle.mode = VehicleMode("RTL") + + vehicle.close() diff --git a/dronekit/test/sitl/test_localposition.py b/dronekit/test/sitl/test_localposition.py index 9cdd992d3..8c4563a9a 100644 --- a/dronekit/test/sitl/test_localposition.py +++ b/dronekit/test/sitl/test_localposition.py @@ -11,6 +11,7 @@ def test_timeout(connpath): # to make on a real vehicle. They are leveraged # exclusively for simulation. Take heed!!! vehicle.parameters['ARMING_CHECK'] = 0 + vehicle.parameters['EKF_CHECK_THRESH'] = 0 # ARM vehicle.armed = True @@ -27,3 +28,5 @@ def test_timeout(connpath): assert_not_equals(vehicle.location.local_frame.north, None) assert_not_equals(vehicle.location.local_frame.east, None) assert_not_equals(vehicle.location.local_frame.down, None) + + vehicle.close() diff --git a/dronekit/test/sitl/test_parameters.py b/dronekit/test/sitl/test_parameters.py index 05a6cb6ee..a6a815713 100644 --- a/dronekit/test/sitl/test_parameters.py +++ b/dronekit/test/sitl/test_parameters.py @@ -22,3 +22,5 @@ def test_parameters(connpath): # Garbage value after all parameters are downloaded should be None. assert_equals(vehicle.parameters.get('xXx_extreme_garbage_value_xXx', wait_ready=True), None) + + vehicle.close() diff --git a/dronekit/test/sitl/test_simpledemo.py b/dronekit/test/sitl/test_simpledemo.py index 8ed4d14bd..ec3dc170b 100644 --- a/dronekit/test/sitl/test_simpledemo.py +++ b/dronekit/test/sitl/test_simpledemo.py @@ -18,6 +18,8 @@ def test_parameter(connpath): # Perform a simple parameter check assert_equals(type(v.parameters['THR_MIN']), float) + v.close() + # This test runs second. Add as many tests as you like @with_sitl def test_mode(connpath): @@ -25,3 +27,5 @@ def test_mode(connpath): # Ensure Mode is an instance of VehicleMode assert isinstance(v.mode, VehicleMode) + + v.close() diff --git a/dronekit/test/sitl/test_vehicleclass.py b/dronekit/test/sitl/test_vehicleclass.py index f32ad2ee0..f6150f6c3 100644 --- a/dronekit/test/sitl/test_vehicleclass.py +++ b/dronekit/test/sitl/test_vehicleclass.py @@ -18,3 +18,5 @@ def test_timeout(connpath): while not v.success: time.sleep(0.1) + + v.close() diff --git a/dronekit/test/sitl/test_waypoints.py b/dronekit/test/sitl/test_waypoints.py index 5f114ec41..eae9eff75 100644 --- a/dronekit/test/sitl/test_waypoints.py +++ b/dronekit/test/sitl/test_waypoints.py @@ -14,6 +14,8 @@ def test_empty_clear(connpath): assert_equals(len(vehicle.commands), 0) + vehicle.close() + @with_sitl def test_set_home(connpath): vehicle = connect(connpath, wait_ready=True) @@ -108,3 +110,5 @@ def test_parameter(connpath): assert_equals(home.lat, vehicle.home_location.lat) assert_equals(home.lon, vehicle.home_location.lon) assert_equals(home.alt, vehicle.home_location.alt) + + vehicle.close() diff --git a/dronekit/util.py b/dronekit/util.py index 793475900..5cfb21600 100644 --- a/dronekit/util.py +++ b/dronekit/util.py @@ -3,3 +3,4 @@ def errprinter(*args): print(*args, file=sys.stderr) + sys.stderr.flush() From 23dbb5f819bd3388df5450de05e5ba716744fab2 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 5 Nov 2015 13:16:56 -0800 Subject: [PATCH 135/475] Improves localposition test. --- dronekit/test/sitl/test_localposition.py | 65 ++++++++++++++++++++---- 1 file changed, 56 insertions(+), 9 deletions(-) diff --git a/dronekit/test/sitl/test_localposition.py b/dronekit/test/sitl/test_localposition.py index 8c4563a9a..63bebeb00 100644 --- a/dronekit/test/sitl/test_localposition.py +++ b/dronekit/test/sitl/test_localposition.py @@ -1,7 +1,7 @@ import time from dronekit import connect, VehicleMode, LocationGlobal from dronekit.test import with_sitl -from nose.tools import assert_not_equals +from nose.tools import assert_equals, assert_not_equals @with_sitl def test_timeout(connpath): @@ -11,17 +11,64 @@ def test_timeout(connpath): # to make on a real vehicle. They are leveraged # exclusively for simulation. Take heed!!! vehicle.parameters['ARMING_CHECK'] = 0 + vehicle.parameters['FS_THR_ENABLE'] = 0 + vehicle.parameters['FS_GCS_ENABLE'] = 0 vehicle.parameters['EKF_CHECK_THRESH'] = 0 - # ARM - vehicle.armed = True - i = 60 - while not vehicle.armed and i > 0: - time.sleep(1) - i = i - 1 + def arm_and_takeoff(aTargetAltitude): + """ + Arms vehicle and fly to aTargetAltitude. + """ - # Await attributes - time.sleep(3) + # print "Basic pre-arm checks" + # Don't let the user try to fly autopilot is booting + if vehicle.mode.name == "INITIALISING": + # print "Waiting for vehicle to initialise" + time.sleep(1) + while vehicle.gps_0.fix_type < 2: + # print "Waiting for GPS...:", vehicle.gps_0.fix_type + time.sleep(1) + + # print "Arming motors" + # Copter should arm in GUIDED mode + vehicle.mode = VehicleMode("GUIDED") + + i = 60 + while vehicle.mode.name != 'GUIDED' and i > 0: + # print " Waiting for guided %s seconds..." % (i,) + time.sleep(1) + i = i - 1 + + vehicle.armed = True + + i = 60 + while not vehicle.armed and vehicle.mode.name == 'GUIDED' and i > 0: + # print " Waiting for arming %s seconds..." % (i,) + time.sleep(1) + i = i - 1 + + # Failure will result in arming but immediately landing + assert vehicle.armed + assert_equals(vehicle.mode.name, 'GUIDED') + + # print "Taking off!" + vehicle.commands.takeoff(aTargetAltitude) # Take off to target altitude + + # Wait until the vehicle reaches a safe height before + # processing the goto (otherwise the command after + # Vehicle.commands.takeoff will execute immediately). + while True: + # print " Altitude: ", vehicle.location.alt + # Test for altitude just below target, in case of undershoot. + if vehicle.location.global_frame.alt >= aTargetAltitude * 0.95: + # print "Reached target altitude" + break + + assert_equals(vehicle.mode.name, 'GUIDED') + time.sleep(1) + + arm_and_takeoff(10) + vehicle.wait_ready('local_position', timeout=60) # .north, .east, and .down are initialized to None. # Any other value suggests that a LOCAL_POSITION_NED was received and parsed. From 44550ed6a2d51744e79cca49fb1dd28209ba2d04 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 5 Nov 2015 13:50:28 -0800 Subject: [PATCH 136/475] Adds heartbeat timeouts and tests. --- dronekit/__init__.py | 4 +-- dronekit/lib/__init__.py | 26 ++++++++++++-------- dronekit/test/sitl/test_timeout.py | 39 ++++++++++++++++++++++++++++++ tests/sitl/test_timeout.py | 20 --------------- 4 files changed, 57 insertions(+), 32 deletions(-) create mode 100644 dronekit/test/sitl/test_timeout.py delete mode 100644 tests/sitl/test_timeout.py diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 37f6f3e74..1196085b2 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -176,7 +176,7 @@ def close(self): time.sleep(0.1) self.master.close() -def connect(ip, wait_ready=None, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200): +def connect(ip, wait_ready=None, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200, heartbeat_timeout=30): handler = MAVHandler(mavutil.mavlink_connection(ip, baud=baud)) vehicle = vehicle_class(handler) @@ -185,7 +185,7 @@ def connect(ip, wait_ready=None, status_printer=errprinter, vehicle_class=Vehicl def listener(self, name, m): status_printer(re.sub(r'(^|\n)', '>>> ', m.text.rstrip())) - vehicle.initialize(rate=rate) + vehicle.initialize(rate=rate, heartbeat_timeout=heartbeat_timeout) if wait_ready: if wait_ready == True: diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 2c3f17456..6dca73868 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -820,7 +820,7 @@ def listener(self, name, msg): self._heartbeat_timeout = False self._heartbeat_warning = 5 - self._heartbeat_error = 60 + self._heartbeat_error = 30 @handler.loop_listener def listener(_): @@ -830,7 +830,7 @@ def listener(_): self._heartbeat_lastsent = time.time() # Timeouts. - if self._heartbeat_started and self._heartbeat_lastreceived != 0: + if self._heartbeat_started: if time.time() - self._heartbeat_lastreceived > self._heartbeat_error: raise Exception('>>> No heartbeat in %s seconds, aborting.' % self._heartbeat_error) elif time.time() - self._heartbeat_lastreceived > self._heartbeat_warning: @@ -1129,17 +1129,23 @@ def message_factory(self): """ return self._master.mav - def initialize(self, wait_ready=False, rate=None): + def initialize(self, wait_ready=False, rate=None, heartbeat_timeout=30): self._handler.start() - # Wait for first heartbeat. - while True: - try: - self._master.wait_heartbeat() - break - except mavutil.mavlink.MAVError: - continue + # Start heartbeat polling. + start = time.time() + self._heartbeat_error = heartbeat_timeout self._heartbeat_started = True + self._heartbeat_lastreceived = start + + # Poll for first heartbeat. + # If heartbeat times out, this will interrupt. + while self._handler._alive: + time.sleep(.1) + if self._heartbeat_lastreceived != start: + break + if not self._handler._alive: + raise APIException('Timeout in initializing connection.') # Wait until board has booted. while True: diff --git a/dronekit/test/sitl/test_timeout.py b/dronekit/test/sitl/test_timeout.py new file mode 100644 index 000000000..fe310be55 --- /dev/null +++ b/dronekit/test/sitl/test_timeout.py @@ -0,0 +1,39 @@ +import time +import sys +import os +import socket +from dronekit import connect, VehicleMode +from dronekit.test import with_sitl +from nose.tools import assert_equals + +@with_sitl +def test_timeout(connpath): + # Connect with timeout of 10s. + vehicle = connect(connpath, wait_ready=True, heartbeat_timeout=20) + + # Stall input. + vehicle._handler._accept_input = False + + start = time.time() + while vehicle._handler._alive and time.time() - start < 30: + time.sleep(.1) + + assert_equals(vehicle._handler._alive, False) + + vehicle.close() + +def test_timeout_empty(): + # Create a dummy server. + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + s.bind(('127.0.0.1', 5760)) + s.listen(1) + + try: + # Connect with timeout of 10s. + vehicle = connect('tcp:127.0.0.1:5760', wait_ready=True, heartbeat_timeout=20) + + # Should not pass + assert False + except: + pass diff --git a/tests/sitl/test_timeout.py b/tests/sitl/test_timeout.py deleted file mode 100644 index 6bef43251..000000000 --- a/tests/sitl/test_timeout.py +++ /dev/null @@ -1,20 +0,0 @@ -import time -import sys -import os -from dronekit import connect, VehicleMode -from dronekit.tools import with_sitl -from nose.tools import assert_equals - -@with_sitl -def test_timeout(connpath): - vehicle = connect(connpath, await_params=True) - - # Stall input and lower error threshold to 10 seconds. - vehicle._heartbeat_error = 10 - vehicle._handler._accept_input = False - - start = time.time() - while vehicle._handler._alive and time.time() - start < 20: - time.sleep(.1) - - assert_equals(vehicle._handler._alive, False) From 14afef4d19bb2a35952a926d53f2100375ee8d08 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 3 Nov 2015 11:39:19 -0800 Subject: [PATCH 137/475] Supports Copter 3.3 and new DroneKit SITL. --- dronekit/test/__init__.py | 3 ++- dronekit/test/sitl/test_110.py | 30 +++++++++++------------- dronekit/test/sitl/test_goto.py | 8 ++++--- dronekit/test/sitl/test_localposition.py | 8 ++++--- requirements.txt | 2 +- 5 files changed, 27 insertions(+), 24 deletions(-) diff --git a/dronekit/test/__init__.py b/dronekit/test/__init__.py index b533a1d57..50639b872 100644 --- a/dronekit/test/__init__.py +++ b/dronekit/test/__init__.py @@ -14,7 +14,8 @@ def setup_sitl(): global sitl - sitl = SITL('copter', '3.3-rc5') + sitl = SITL() + sitl.download('copter', '3.3') sitl.launch(sitl_args, await_ready=True, restart=True) def teardown_sitl(): diff --git a/dronekit/test/sitl/test_110.py b/dronekit/test/sitl/test_110.py index 4560a2ad1..20714b31f 100644 --- a/dronekit/test/sitl/test_110.py +++ b/dronekit/test/sitl/test_110.py @@ -7,18 +7,16 @@ @with_sitl def test_110(connpath): - v = connect(connpath, wait_ready=True) + vehicle = connect(connpath, wait_ready=True) # NOTE these are *very inappropriate settings* # to make on a real vehicle. They are leveraged # exclusively for simulation. Take heed!!! - v.parameters['ARMING_CHECK'] = 0 - v.parameters['FS_THR_ENABLE'] = 0 - v.parameters['FS_GCS_ENABLE'] = 0 - v.parameters['EKF_CHECK_THRESH'] = 0 + vehicle.parameters['FS_GCS_ENABLE'] = 0 + vehicle.parameters['FS_EKF_THRESH'] = 100 # Change the vehicle into STABILIZE mode - v.mode = VehicleMode("STABILIZE") + vehicle.mode = VehicleMode("STABILIZE") # NOTE wait crudely for ACK on mode update time.sleep(3) @@ -30,14 +28,14 @@ def armed_callback(vehicle, attribute): # When the same (event, callback) pair is passed to on_attribute, # only one instance of the observer callback should be added. - v.on_attribute('armed', armed_callback) - v.on_attribute('armed', armed_callback) - v.on_attribute('armed', armed_callback) - v.on_attribute('armed', armed_callback) - v.on_attribute('armed', armed_callback) + vehicle.on_attribute('armed', armed_callback) + vehicle.on_attribute('armed', armed_callback) + vehicle.on_attribute('armed', armed_callback) + vehicle.on_attribute('armed', armed_callback) + vehicle.on_attribute('armed', armed_callback) # Disarm and see update. - v.armed = False + vehicle.armed = False # Wait for ACK. time.sleep(3) @@ -49,16 +47,16 @@ def armed_callback(vehicle, attribute): # NOTE: We test if armed_callback were treating adding each additional callback # and remove_attribute_listener were removing them one at a time; in this # case, there would be three callbacks still attached. - v.remove_attribute_listener('armed', armed_callback) - v.remove_attribute_listener('armed', armed_callback) + vehicle.remove_attribute_listener('armed', armed_callback) + vehicle.remove_attribute_listener('armed', armed_callback) callcount = armed_callback.called # Re-arm and see update. - v.armed = True + vehicle.armed = True # Wait for ack time.sleep(3) # Ensure the callback was called zero times. assert_equals(armed_callback.called, callcount, "Callback should not have been called once removed.") - v.close() + vehicle.close() diff --git a/dronekit/test/sitl/test_goto.py b/dronekit/test/sitl/test_goto.py index 7f0547e42..0439ecf05 100644 --- a/dronekit/test/sitl/test_goto.py +++ b/dronekit/test/sitl/test_goto.py @@ -19,10 +19,8 @@ def test_goto(connpath): # NOTE these are *very inappropriate settings* # to make on a real vehicle. They are leveraged # exclusively for simulation. Take heed!!! - vehicle.parameters['ARMING_CHECK'] = 0 - vehicle.parameters['FS_THR_ENABLE'] = 0 vehicle.parameters['FS_GCS_ENABLE'] = 0 - vehicle.parameters['EKF_CHECK_THRESH'] = 0 + vehicle.parameters['FS_EKF_THRESH'] = 100 def arm_and_takeoff(aTargetAltitude): """ @@ -48,6 +46,10 @@ def arm_and_takeoff(aTargetAltitude): time.sleep(1) i = i - 1 + # EKF warmup. Await that EKF's predicted horizontal position (absolute) estimate is good + while not vehicle._ekf_predposhorizabs: + time.sleep(1) + vehicle.armed = True i = 60 diff --git a/dronekit/test/sitl/test_localposition.py b/dronekit/test/sitl/test_localposition.py index 63bebeb00..844677484 100644 --- a/dronekit/test/sitl/test_localposition.py +++ b/dronekit/test/sitl/test_localposition.py @@ -10,10 +10,8 @@ def test_timeout(connpath): # NOTE these are *very inappropriate settings* # to make on a real vehicle. They are leveraged # exclusively for simulation. Take heed!!! - vehicle.parameters['ARMING_CHECK'] = 0 - vehicle.parameters['FS_THR_ENABLE'] = 0 vehicle.parameters['FS_GCS_ENABLE'] = 0 - vehicle.parameters['EKF_CHECK_THRESH'] = 0 + vehicle.parameters['FS_EKF_THRESH'] = 100 def arm_and_takeoff(aTargetAltitude): """ @@ -39,6 +37,10 @@ def arm_and_takeoff(aTargetAltitude): time.sleep(1) i = i - 1 + # EKF warmup. Await that EKF's predicted horizontal position (absolute) estimate is good + while not vehicle._ekf_predposhorizabs: + time.sleep(1) + vehicle.armed = True i = 60 diff --git a/requirements.txt b/requirements.txt index d538d87df..928cd69c7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,4 +5,4 @@ nose>=1.3.7 psutil>=3.0.0 mock>=1.3.0 six>=1.9.0 -dronekit-sitl>=2.3.0,<=2.99999 +dronekit-sitl>=3.0,<=3.99999 From 9b1e510ab65ef3b8134fc980a8fe11501f62b0be Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 5 Nov 2015 17:46:40 -0800 Subject: [PATCH 138/475] Allows timeout to be set to 0. --- dronekit/lib/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 6dca73868..b4993d46b 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -831,7 +831,7 @@ def listener(_): # Timeouts. if self._heartbeat_started: - if time.time() - self._heartbeat_lastreceived > self._heartbeat_error: + if self._heartbeat_error and self._heartbeat_error > 0 and time.time() - self._heartbeat_lastreceived > self._heartbeat_error: raise Exception('>>> No heartbeat in %s seconds, aborting.' % self._heartbeat_error) elif time.time() - self._heartbeat_lastreceived > self._heartbeat_warning: if self._heartbeat_timeout == False: @@ -1134,7 +1134,7 @@ def initialize(self, wait_ready=False, rate=None, heartbeat_timeout=30): # Start heartbeat polling. start = time.time() - self._heartbeat_error = heartbeat_timeout + self._heartbeat_error = heartbeat_timeout or 0 self._heartbeat_started = True self._heartbeat_lastreceived = start From 0f2f963a7f6c1b0fe2266c10820b7499c7f13a51 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 5 Nov 2015 15:56:03 +1100 Subject: [PATCH 139/475] Update the main attribute_observer examples and docs --- docs/examples/vehicle_state.rst | 38 ++++--------- docs/guide/vehicle_state_and_parameters.rst | 62 ++++++++++++--------- dronekit/lib/__init__.py | 56 +++++++++++++------ examples/vehicle_state/vehicle_state.py | 18 +++--- 4 files changed, 98 insertions(+), 76 deletions(-) diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index cd94ecb1e..6ab011add 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -56,31 +56,25 @@ On the command prompt you should see (something like): Accumulating vehicle attribute messages Get all vehicle attribute values: - Global Location: LocationGlobal:lat=-35.3632615,lon=149.1652301,alt=0.0,is_relative=False + Global Location: LocationGlobal:lat=-35.3632585,lon=149.165227,alt=362.0,is_relative=False Local Location: LocationLocal:north=None,east=None,down=None - Attitude: Attitude:pitch=0.00589594058692,yaw=-0.0884591862559,roll=0.000426373298978 - Velocity: [-0.02, 0.02, 0.0] + Attitude: Attitude:pitch=-0.00352983362973,yaw=-0.0589601770043,roll=-0.00761049194261 + Velocity: [0.02, -0.02, 0.0] GPS: GPSInfo:fix=3,num_sat=10 Groundspeed: 0.0 Airspeed: 0.0 Mount status: [None, None, None] - Battery: Battery:voltage=12.587,current=0.0,level=99 + Battery: Battery:voltage=12.587,current=0.0,level=98 Rangefinder: Rangefinder: distance=None, voltage=None Rangefinder distance: None Rangefinder voltage: None Mode: STABILIZE Armed: False - Home Location: LocationGlobal:lat=0.0,lon=0.0,alt=0.0,is_relative=False + Home Location: LocationGlobal:lat=-35.3632583618,lon=149.165222168,alt=222.0,is_relative=False Set new home location - Waiting for home location: LocationGlobal:lat=0.0,lon=0.0,alt=0.0,is_relative=False - ... - Waiting for home location: LocationGlobal:lat=0.0,lon=0.0,alt=0.0,is_relative=False - Waiting for home location: LocationGlobal:lat=0.0,lon=0.0,alt=0.0,is_relative=False - - Autopilot set home location: LocationGlobal:lat=-35.3632621765,lon=149.165237427,alt=583.989990234,is_relative=False - New Home Location (altitude should be 222): LocationGlobal:lat=-35.3632621765,lon=149.165237427,alt=222.0,is_relative=False - + New Home Location (altitude should be 222): LocationGlobal:lat=-35.3632583618,lon=149.165222168,alt=222.0,is_relative=False + Set Vehicle.mode=GUIDED (currently: STABILIZE) Waiting for mode change ... @@ -89,11 +83,12 @@ On the command prompt you should see (something like): >>> ARMING MOTORS >>> Initialising APM... - Add mode attribute observer for Vehicle.mode + Add attribute callback/observer on `vehicle` for `mode` attribute Set mode=STABILIZE (currently: GUIDED) Wait 2s so callback invoked before observer removed - CALLBACK: Mode changed to: STABILIZE - CALLBACK: Mode changed to: STABILIZE + CALLBACK: Mode changed to VehicleMode:STABILIZE + CALLBACK: Mode changed to VehicleMode:STABILIZE + Remove Vehicle.mode observer Read vehicle param 'THR_MIN': 130.0 Write vehicle param 'THR_MIN' : 10 @@ -122,16 +117,7 @@ The guide topic :ref:`vehicle-information` provides an explanation of how this c Known issues ============ -This example works around the :ref:`known issues in the API `. -Provided that the vehicle is connected and able to arm, it should run through to completion. - -You may observe these issues: - -* When the observer sets the mode callback, it waits two seconds after changing the mode before removing the observer - (to ensure that the callback function is run before the observer is removed). In this time you may see the callback being - called twice even though the mode is only changed once. - See `#60 Attribute observer callbacks are called with heartbeat until disabled - after first called `_ - for more information. +This example has no known issues. diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index 1a9aaf04a..416d530a7 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -34,6 +34,9 @@ Vehicle state information is exposed through vehicle *attributes*. DroneKit-Pyth :py:attr:`Vehicle.armed `, :py:attr:`Vehicle.mode `. +Attributes are initially created with ``None`` values for their members. In most cases the members are populated +(and repopulated) as new MAVLink messages of the associated types are received from the vehicle. + All of the attributes can be :ref:`read ` and :ref:`observed `, but only the :py:attr:`Vehicle.home_location `, :py:attr:`Vehicle.mode ` and @@ -70,11 +73,12 @@ The code fragment below shows how to read and print almost the attributes. The v print "Armed: %s" % vehicle.armed # settable -If an attribute cannot be retrieved then the returned object will contain -``None`` values for its members (for example, if there was no GPS lock then -:py:attr:`Vehicle.gps_0 ` would return a :py:class:`GPSInfo ` -with ``None`` values for ``eph``, ``satellites_visible`` etc.) -Attributes will also return ``None`` if the associated hardware is not present on the connected device. +.. note:: + + A value of ``None`` for an attribute member indicates that the value has not yet been populated from the vehicle. + For example, before GPS lock :py:attr:`Vehicle.gps_0 ` will return a + :py:class:`GPSInfo ` with ``None`` values for ``eph``, ``satellites_visible`` etc. + Attributes will also return ``None`` if the associated hardware is not present on the connected device. .. tip:: @@ -131,31 +135,41 @@ to confirm they have changed before proceeding. Observing attribute changes --------------------------- -You can observe any of the attributes (except the ``home_location``) and will receive notification every time a value is received from the connected vehicle. -This allows you to monitor changes to velocity and other vehicle state without the need for polling. +You can observe any of the attributes (except for :py:attr:`Vehicle.home_location ` and +:py:attr:`Vehicle.parameters `) and will receive notification every time a value is received +from the connected vehicle. This allows you to monitor changes to velocity and other vehicle state without the need for polling. -Observers are added using :py:func:`Vehicle.add_attribute_observer() `, -specifying the name of the attribute to observe and a callback function. The same string is passed to the callback -when it is notified. Observers are removed using :py:func:`remove_attribute_observer() `. +Observers are added using :py:func:`Vehicle.on_attribute() `, +specifying the name of the attribute to observe and a callback function. +Observers are removed using :py:func:`remove_attribute_listener() `. + +The ``observer`` callback function is invoked with the ``self`` and ``attr_name`` arguments: + +* The ``attr_name`` (attribute name) is needed if the same callback is used for watching several attributes. +* The ``self`` attribute is the associated :py:class:`Vehicle`. It is needed if you want to + implement vehicle-specific callback handling (by comparing it to a global vehicle handle). + +The code snippet below shows how to add (and remove) a callback function to observe location changes +(:py:attr:`Vehicle.location.global_frame `). +The two second ``sleep()`` is required because otherwise the observer might be removed before the the +callback is first run. -The code snippet below shows how to add (and remove) a callback function to observe :py:attr:`location ` -attribute changes. The two second ``sleep()`` is required because otherwise the observer might be removed before the the callback is first run. .. code:: python - # Callback function. The parameter is the name of the observed attribute (a string) - def location_callback(attribute): - print " CALLBACK: Global Location changed to: ", vehicle.location.global_frame - print " CALLBACK: Location changed to: ", vehicle.location.local_frame + #Callback to print the location in global and local frames + def location_callback(self, attr_name): + print "Location (Global): ", self.location.global_frame + print "Location (Local): ", self.location.local_frame # Add a callback. The first parameter the name of the observed attribute (a string). - vehicle.add_attribute_observer('location', location_callback) + vehicle.on_attribute('location', location_callback) # Wait 2s so callback can be notified before the observer is removed time.sleep(2) # Remove observer - specifying the attribute and previously registered callback function - vehicle.remove_attribute_observer('location', location_callback) + vehicle.remove_message_listener('location', location_callback) The callback is triggered every time a message is received from the vehicle (whether or not the observed attribute changes). @@ -167,15 +181,15 @@ For example, the following code can be used in the callback to only print output last_rangefinder_distance=0 - def rangefinder_callback(rangefinder): + def rangefinder_callback(self,attr_name): + #attr_name not used here. global last_rangefinder_distance - if last_rangefinder_distance == round(vehicle.rangefinder.distance, 1): + if last_rangefinder_distance == round(self.rangefinder.distance, 1): return - last_rangefinder_distance = round(vehicle.rangefinder.distance, 1) + last_rangefinder_distance = round(self.rangefinder.distance, 1) print " Rangefinder (metres): %s" % last_rangefinder_distance - - vehicle.add_attribute_observer('rangefinder', rangefinder_callback) + vehicle.on_attribute('rangefinder', rangefinder_callback) @@ -297,10 +311,8 @@ Known issues Below are a number of bugs and known issues related to vehicle state and settings: -* `#60 Attribute observer callbacks are called with heartbeat until disabled - after first called `_ * `#107 Add implementation for observer methods in Parameter class `_ * `#114 DroneKit has no method for detecting command failure `_ -* `#392 vehicle.home_location should be settable `_ Other API issues and improvement suggestions can viewed on `github here `_. \ No newline at end of file diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index b4993d46b..2b3a1e92b 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -228,14 +228,16 @@ class VehicleMode(object): `Rover `_). If an unsupported mode is set the script will raise a ``KeyError`` exception. - The :py:attr:`Vehicle.mode ` attribute can be queried for the current mode. The code snippet - below shows how to read (print) and observe changes to the mode: + The :py:attr:`Vehicle.mode ` attribute can be queried for the current mode. + The code snippet below shows how to observe changes to the mode and then read the value: .. code:: python - def mode_callback(self, mode): - print "Vehicle Mode", vehicle.mode + #Callback definition for mode observer + def mode_callback(self, attr_name): + print "Vehicle Mode", self.mode + #Add observer callback for attribute `mode` vehicle.on_attribute('mode', mode_callback) The code snippet below shows how to change the vehicle mode to AUTO: @@ -245,7 +247,8 @@ def mode_callback(self, mode): # Set the vehicle into auto mode vehicle.mode = VehicleMode("AUTO") - For more information on getting/setting/observing the :py:attr:`Vehicle.mode ` (and other attributes) see the :ref:`attributes guide `. + For more information on getting/setting/observing the :py:attr:`Vehicle.mode ` + (and other attributes) see the :ref:`attributes guide `. .. py:attribute:: name @@ -277,28 +280,34 @@ def on_attribute(self, attr_name, observer): """ Add an attribute listener. - The listener callback function is called with the ``vehicle`` and ``attr_name`` arguments. - This can be used to infer the related attribute if the same callback is used - for watching several attributes. + The ``observer`` callback function is called with the ``self`` and ``attr_name`` + arguments: + + * The ``attr_name`` (attribute name) can be used to infer which attribute has triggered + if the same callback is used for watching several attributes. + * The ``self`` attribute is the associated :py:class:`Vehicle`. If needed, it can be compared + to a global vehicle handle to implement vehicle-specific callback handling. The example below shows how to get callbacks for location changes: .. code:: python #Callback to print the location in global and local frames - def location_callback(vehicle, attr_name): - print "Location (Global): ", vehicle.location.global_frame - print "Location (Local): ", vehicle.location.local_frame + def location_callback(self, attr_name): + print "Location (Global): ", self.location.global_frame + print "Location (Local): ", self.location.local_frame #Add observer for the vehicle's current location vehicle.on_attribute('location', location_callback) + .. note:: - Attribute changes will only be published for changes due to some other entity. - They will not be published for changes made by the local API client - (in order to prevent redundant notification for local changes). - :param attr_name: The attribute to watch. + The callback function is invoked every time the associated attribute is updated + from the vehicle (the attribute value may not have *changed*). + The callback can be removed using :py:func:`remove_attribute_listener`. + + :param String attr_name: The attribute to watch. :param observer: The callback to invoke when a change in the attribute is detected. """ @@ -311,15 +320,16 @@ def location_callback(vehicle, attr_name): def remove_attribute_listener(self, attr_name, observer): """ - Remove an attribute listener. + Remove an attribute listener (observer) that was previously added using :py:func:`on_attribute`. - For example, the following line would remove a previously added vehicle 'global_frame' observer called location_callback: + For example, the following line would remove a previously added vehicle 'global_frame' + observer called ``location_callback``: .. code:: python vehicle.remove_attribute_listener('global_frame', location_callback) - :param attr_name: The attribute name that is to have an observer removed. + :param String attr_name: The attribute name that is to have an observer removed. :param observer: The callback function to remove. """ @@ -345,6 +355,16 @@ def _notify_attribute_listeners(self, attr_name): def attribute_listener(self, name): """ Decorator for attribute listeners. + + This is used to create/define new attribute listenters. After using this method you can + register an observer for the attribute using :py:func:`on_attribute`. + + .. note:: + + The in-built attributes already have listeners (created using this method). The + method is public so that you can use it to add listeners to *new* attributes. + + The example below shows how you can create a listener for the attitude attribute. .. code:: python diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index de7dcb703..049785741 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -104,12 +104,15 @@ time.sleep(1) -# Show how to add and remove and attribute observer callbacks (using mode as example) -def mode_callback(attribute): - print " CALLBACK: Mode changed to: ", vehicle.mode.name +# Add and remove and attribute callbacks (using mode as example) +def mode_callback(self, attr_name): + # `attr_name` is the observed attribute (used if callback is used for multiple attributes) + # `self` is the associated vehicle object (used if callback behaviouris different for multiple vehicles) + print " CALLBACK: Mode changed to", self.mode + +print "\nAdd attribute callback/observer on `vehicle` for `mode` attribute" +vehicle.on_attribute('mode', mode_callback) -print "\nAdd mode attribute observer for Vehicle.mode" -vehicle.add_attribute_observer('mode', mode_callback) print " Set mode=STABILIZE (currently: %s)" % vehicle.mode.name vehicle.mode = VehicleMode("STABILIZE") @@ -117,8 +120,9 @@ def mode_callback(attribute): print " Wait 2s so callback invoked before observer removed" time.sleep(2) -# Remove observer - specifying the attribute and previously registered callback function -vehicle.remove_attribute_observer('mode', mode_callback) +print " Remove Vehicle.mode observer" +# Remove observer added with `on_attribute()` - specifying the attribute and callback function +vehicle.remove_attribute_listener('mode', mode_callback) # Get/Set Vehicle Parameters From c4577af2d438b624719f635a1f09212f4cc8520e Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 5 Nov 2015 21:37:26 +1100 Subject: [PATCH 140/475] Update the mavlink message handling ref, guide, example to use the new message_listener decorator etc --- docs/examples/create_attribute.rst | 121 +++++++++--------- docs/guide/mavlink_messages.rst | 68 ++++------ examples/create_attribute/create_attribute.py | 64 ++++----- examples/drone_delivery/drone_delivery.py | 12 +- 4 files changed, 121 insertions(+), 144 deletions(-) diff --git a/docs/examples/create_attribute.rst b/docs/examples/create_attribute.rst index 86bb01e5f..4afbd4af2 100644 --- a/docs/examples/create_attribute.rst +++ b/docs/examples/create_attribute.rst @@ -7,6 +7,11 @@ Example: Create Attribute in App This example shows how you can create attributes for MAVLink messages within your DroneKit-Python script and use them in *in the same way* as the built-in :py:class:`Vehicle ` attributes. +It uses the :py:func:`Vehicle.message_listener() ` decorator +to set a function that is called to process a specific message, copy its values into an attribute, and notify +observers. An observer is then set on the new attribute using +:py:func:`Vehicle.on_attribute() `. + Additional information is provided in the guide topic :ref:`mavlink_messages`. .. tip:: @@ -16,7 +21,7 @@ Additional information is provided in the guide topic :ref:`mavlink_messages`. Please :ref:`contribute your code to the API ` so that it is available to (and can be tested by) the whole DroneKit-Python community. - + Running the example @@ -51,21 +56,30 @@ On the command prompt you should see (something like): .. code:: bash - RAW_IMU: time_boot_us=41270000,xacc=0,yacc=0,zacc=-999,xgyro=1,ygyro=1,zgyro=1,xmag=153,ymag=52,zmag=-364 - RAW_IMU: time_boot_us=41510000,xacc=0,yacc=0,zacc=-1000,xgyro=1,ygyro=0,zgyro=1,xmag=153,ymag=52,zmag=-364 - RAW_IMU: time_boot_us=41750000,xacc=1,yacc=0,zacc=-1000,xgyro=1,ygyro=1,zgyro=0,xmag=153,ymag=52,zmag=-364 - RAW_IMU: time_boot_us=41990000,xacc=0,yacc=0,zacc=-999,xgyro=0,ygyro=0,zgyro=0,xmag=153,ymag=52,zmag=-364 - RAW_IMU: time_boot_us=42230000,xacc=0,yacc=0,zacc=-1000,xgyro=0,ygyro=0,zgyro=0,xmag=153,ymag=52,zmag=-364 - RAW_IMU: time_boot_us=42470000,xacc=0,yacc=0,zacc=-999,xgyro=1,ygyro=0,zgyro=0,xmag=153,ymag=52,zmag=-364 - RAW_IMU: time_boot_us=42710000,xacc=0,yacc=0,zacc=-999,xgyro=0,ygyro=0,zgyro=0,xmag=153,ymag=52,zmag=-364 - RAW_IMU: time_boot_us=42950000,xacc=0,yacc=0,zacc=-1000,xgyro=1,ygyro=1,zgyro=0,xmag=153,ymag=52,zmag=-364 - RAW_IMU: time_boot_us=43190000,xacc=0,yacc=0,zacc=-999,xgyro=1,ygyro=1,zgyro=1,xmag=153,ymag=52,zmag=-364 - RAW_IMU: time_boot_us=43430000,xacc=0,yacc=0,zacc=-999,xgyro=0,ygyro=0,zgyro=0,xmag=153,ymag=52,zmag=-364 - RAW_IMU: time_boot_us=43670000,xacc=0,yacc=0,zacc=-999,xgyro=1,ygyro=0,zgyro=1,xmag=153,ymag=52,zmag=-364 - RAW_IMU: time_boot_us=43910000,xacc=0,yacc=0,zacc=-999,xgyro=1,ygyro=0,zgyro=1,xmag=153,ymag=52,zmag=-364 - RAW_IMU: time_boot_us=44150000,xacc=0,yacc=0,zacc=-999,xgyro=1,ygyro=1,zgyro=0,xmag=153,ymag=52,zmag=-364 - RAW_IMU: time_boot_us=44390000,xacc=0,yacc=0,zacc=-999,xgyro=1,ygyro=1,zgyro=0,xmag=153,ymag=52,zmag=-364 - APIThread-0 exiting... + Connecting to vehicle on: tcp:127.0.0.1:14550 + >>> APM:Copter V3.3 (d6053245) + >>> Frame: QUAD + Display RAW_IMU messages for 5 seconds and then exit. + RAW_IMU: time_boot_us=1593318928,xacc=-3,yacc=5,zacc=-999,xgyro=0,ygyro=0,zgyro=0,xmag=156,ymag=41,zmag=-365 + RAW_IMU: time_boot_us=1593558928,xacc=-4,yacc=5,zacc=-1000,xgyro=0,ygyro=1,zgyro=1,xmag=156,ymag=41,zmag=-365 + RAW_IMU: time_boot_us=1593798928,xacc=-2,yacc=6,zacc=-1000,xgyro=1,ygyro=0,zgyro=0,xmag=156,ymag=41,zmag=-365 + RAW_IMU: time_boot_us=1594038928,xacc=-2,yacc=6,zacc=-1000,xgyro=1,ygyro=1,zgyro=1,xmag=156,ymag=41,zmag=-365 + RAW_IMU: time_boot_us=1594278928,xacc=-2,yacc=5,zacc=-999,xgyro=0,ygyro=1,zgyro=1,xmag=156,ymag=41,zmag=-365 + RAW_IMU: time_boot_us=1594518928,xacc=-2,yacc=4,zacc=-998,xgyro=1,ygyro=1,zgyro=1,xmag=156,ymag=41,zmag=-365 + RAW_IMU: time_boot_us=1594758928,xacc=-3,yacc=5,zacc=-1000,xgyro=0,ygyro=1,zgyro=0,xmag=156,ymag=41,zmag=-365 + RAW_IMU: time_boot_us=1594998928,xacc=-2,yacc=4,zacc=-999,xgyro=1,ygyro=0,zgyro=0,xmag=156,ymag=41,zmag=-365 + RAW_IMU: time_boot_us=1595238928,xacc=-3,yacc=5,zacc=-1000,xgyro=0,ygyro=1,zgyro=1,xmag=156,ymag=41,zmag=-365 + RAW_IMU: time_boot_us=1595478928,xacc=-2,yacc=4,zacc=-1000,xgyro=1,ygyro=0,zgyro=0,xmag=156,ymag=41,zmag=-365 + RAW_IMU: time_boot_us=1595718928,xacc=-2,yacc=4,zacc=-999,xgyro=0,ygyro=1,zgyro=0,xmag=156,ymag=41,zmag=-365 + RAW_IMU: time_boot_us=1595958928,xacc=-3,yacc=6,zacc=-1000,xgyro=0,ygyro=1,zgyro=1,xmag=156,ymag=41,zmag=-365 + RAW_IMU: time_boot_us=1596198928,xacc=-4,yacc=6,zacc=-1000,xgyro=1,ygyro=1,zgyro=1,xmag=156,ymag=41,zmag=-365 + RAW_IMU: time_boot_us=1596438928,xacc=-2,yacc=6,zacc=-1000,xgyro=0,ygyro=1,zgyro=0,xmag=156,ymag=41,zmag=-365 + RAW_IMU: time_boot_us=1596678928,xacc=-3,yacc=4,zacc=-999,xgyro=1,ygyro=0,zgyro=0,xmag=156,ymag=41,zmag=-365 + RAW_IMU: time_boot_us=1596918928,xacc=-2,yacc=4,zacc=-999,xgyro=0,ygyro=1,zgyro=0,xmag=156,ymag=41,zmag=-365 + RAW_IMU: time_boot_us=1597158928,xacc=-2,yacc=6,zacc=-1000,xgyro=0,ygyro=1,zgyro=1,xmag=156,ymag=41,zmag=-365 + RAW_IMU: time_boot_us=1597398928,xacc=-2,yacc=5,zacc=-1000,xgyro=0,ygyro=1,zgyro=0,xmag=156,ymag=41,zmag=-365 + RAW_IMU: time_boot_us=1597638928,xacc=-3,yacc=5,zacc=-1000,xgyro=1,ygyro=0,zgyro=0,xmag=156,ymag=41,zmag=-365 + Close vehicle object @@ -116,7 +130,7 @@ representation for printing the object. """ String representation of the RawIMU object """ - return "RAW_IMU: time_boot_us={},xacc={},yacc={},zacc={},xgyro={},ygyro={},zgyro={},xmag={},ymag={},zmag={}".format(self.time_boot_us, self.xacc, self.yacc,self.zacc,self.xgyro,self.ygyro,self.zgyro,self.xmag,self.ymag,self.zmag) + return "RAW_IMU: time_boot_us={},xacc={},yacc={},zacc={},xgyro={},ygyro={},zgyro={},xmag={},ymag={},zmag={}".format(self.time_boot_us, self.xacc, self.yacc,self.zacc,self.xgyro,self.ygyro,self.zgyro,self.xmag,self.ymag,self.zmag) The script should then create an instance of the class and add it as an attribute to the vehicle object retrieved from the connection. All values in the new attribute should be set to ``None`` so that it is obvious to users when no messages have been received. @@ -129,66 +143,51 @@ All values in the new attribute should be set to ``None`` so that it is obvious #Create an Vehicle.raw_imu object and set all values to None. vehicle.raw_imu=RawIMU(None,None,None,None,None,None,None,None,None,None) -We set a callback to intercept all MAVLink messages using :py:func:`Vehicle.set_mavlink_callback() ` -as shown below. +We create a listener using the :py:func:`Vehicle.message_listener() ` +decorator as shown below. The listener is called for messages that contain the string "RAW_IMU", +with arguments for the vehicle, message name, and the message. It copies the message information into +the attribute and then notifies all observers. .. code:: python - def mavrx_debug_handler(message): - """ - Handler for MAVLink messages. - """ - #Handle raw_imu messages - mav_raw_imu_handler(message) + #Create a message listener using the decorator. + @vehicle.message_listener('RAW_IMU') + def listener(self, name, message): + #Copy the message contents into the raw_imu attribute + self.raw_imu.time_boot_us=message.time_usec + self.raw_imu.xacc=message.xacc + self.raw_imu.yacc=message.yacc + self.raw_imu.zacc=message.zacc + self.raw_imu.xgyro=message.xgyro + self.raw_imu.ygyro=message.ygyro + self.raw_imu.zgyro=message.zgyro + self.raw_imu.xmag=message.xmag + self.raw_imu.ymag=message.ymag + self.raw_imu.zmag=message.zmag + + # Notify all observers of new message. + self._notify_attribute_listeners('raw_imu') - # Set MAVLink callback handler (after getting Vehicle instance) - vehicle.set_mavlink_callback(mavrx_debug_handler) -For clarity we have separated the handling code for the RAW_IMU message into ``mav_raw_imu_handler()``. The handler simply checks the message type and -(for the correct messages) writes the values into the attribute. It then calls ``vehicle.notify_observers('raw_imu')`` to notify all observers of this attribute type. - -.. code:: python +.. note:: - def mav_raw_imu_handler(message): - """ - Writes received message to the (newly attached) vehicle.raw_imu object and notifies observers. - """ - messagetype=str(message).split('{')[0].strip() - if messagetype=='RAW_IMU': - vehicle.raw_imu.time_boot_us=message.time_usec - vehicle.raw_imu.xacc=message.xacc - vehicle.raw_imu.yacc=message.yacc - vehicle.raw_imu.zacc=message.zacc - vehicle.raw_imu.xgyro=message.xgyro - vehicle.raw_imu.ygyro=message.ygyro - vehicle.raw_imu.zgyro=message.zgyro - vehicle.raw_imu.xmag=message.xmag - vehicle.raw_imu.ymag=message.ymag - vehicle.raw_imu.zmag=message.zmag - - #Add Notify all observers of new message. - vehicle.notify_observers('raw_imu') + The decorator pattern means that you can have multiple listeners for a particular message or for different + messages and they can all have the same function name/prototype (in this case ``listener(self, name, message``). -At this point the ``Vehicle.raw_imu`` attribute can be treated the same as any other attribute for the duration of the session. -You can query the attribute to get any of the values, and even add an observer as shown: +From this point the ``Vehicle.raw_imu`` attribute can be treated the same as any other (inbuilt) attribute. +You can query the attribute to get any of its members, and even add an observer as shown: .. code:: python #Callback to print the raw_imu - def raw_imu_callback(rawimu): - print vehicle.raw_imu + def raw_imu_callback(self, attr_name): + print self.raw_imu #Add observer for the vehicle's current location - vehicle.add_attribute_observer('raw_imu', raw_imu_callback) - - -.. note:: - - It is not possible to reliably use this approach to create independent modules because only one - MAVLink callback can be set at a time in the running program (``set_mavlink_callback()``) + vehicle.on_attribute('raw_imu', raw_imu_callback) Known issues diff --git a/docs/guide/mavlink_messages.rst b/docs/guide/mavlink_messages.rst index ec0af1e4b..c6f698547 100644 --- a/docs/guide/mavlink_messages.rst +++ b/docs/guide/mavlink_messages.rst @@ -7,80 +7,66 @@ MAVLink Messages Some useful MAVLink messages sent by the autopilot are not (yet) directly available to DroneKit-Python scripts through the :ref:`observable attributes ` in :py:class:`Vehicle `. -This topic shows how you can intercept all MAVLink messages using -:py:func:`Vehicle.set_mavlink_callback() `. +This topic shows how you can intercept specific MAVLink messages by defining a listener callback function +using the :py:func:`Vehicle.message_listener() ` +decorator. .. tip:: :ref:`example_create_attribute` shows how you can extend this approach to create a new :py:class:`Vehicle ` attribute in your client code. - +.. _mavlink_messages_message_listener: .. _mavlink_messages_set_mavlink_callback: -Creating a message observer +Creating a message listener =========================== -The :py:func:`Vehicle.set_mavlink_callback() ` method provides asynchronous -notification when any *MAVLink* packet is received from the connected vehicle. +The :py:func:`Vehicle.message_listener() ` decorator can be used to +set a particular function as the callback handler for a particular message type. You can create listeners +for as many messages as you like, or even multiple listeners for the same message. -The code snippet below shows how to set a “demo” callback function as the callback handler: +For example, code snippet below shows how to set a listener for the ``RANGEFINDER`` message: .. code:: python - # Demo callback handler for raw MAVLink messages - def mavrx_debug_handler(message): - print type(message) + #Create a message listener using the decorator. + @vehicle.message_listener('RANGEFINDER') + def listener(self, name, message): print message - - # Set MAVLink callback handler (after getting Vehicle instance) - vehicle.set_mavlink_callback(mavrx_debug_handler) - -.. note:: +.. tip:: - DroneKit-Python only supports a single MAVLink message observer at a time. This can be removed or replaced - with a different observer. + Every single listener can have the same name/prototpye as above ("``listener``") because + Python does not notice these decorated functions as having the same name in the same scope. -The messages are `classes `_ from the `pymavlink `_ library. +The messages are `classes `_ from the +`pymavlink `_ library. The output of the code above looks something like: .. code:: bash - RANGEFINDER {distance : 0.0899999961257, voltage : 0.00900000054389} - - TERRAIN_REPORT {lat : -353632610, lon : 1491652299, spacing : 100, terrain_height : 583.88470459, current_height : 0.0, pending : 0, loaded : 504} - - EKF_STATUS_REPORT {flags : 933, velocity_variance : 0.0, pos_horiz_variance : 0.0, pos_vert_variance : 0.000532002304681, compass_variance : 0.00632426189259, terrain_alt_variance : 0.0} - - VIBRATION {time_usec : 88430000, vibration_x : 0.0, vibration_y : 0.0, vibration_z : 0.0, clipping_0 : 0, clipping_1 : 0, clipping_2 : 0} ... -You can access the message fields directly. For example, to access the ``RANGEFINDER`` message your handler might look like this: +You can access the message fields directly. For example, to access the ``RANGEFINDER`` message your listener +function might look like this: .. code:: python - # Handler for message: RANGEFINDER {distance : 0.0899999961257, voltage : 0.00900000054389} - def mavrx_debug_handler(message): - messagetype=str(message).split('{')[0].strip() - if messagetype=='RANGEFINDER': - print 'distance: %s' % message.distance - print 'voltage: %s' % message.voltage - - - - + #Create a message listener using the decorator. + @vehicle.message_listener('RANGEFINDER') + def listener(self, name, message): + print 'distance: %s' % message.distance + print 'voltage: %s' % message.voltage + + Clearing the observer ===================== -The observer is unset by calling :py:func:`Vehicle.unset_mavlink_callback `. +The observer is unset by calling :py:func:`Vehicle.remove_message_listener `. The observer will also be removed when the thread exits. - - - - \ No newline at end of file diff --git a/examples/create_attribute/create_attribute.py b/examples/create_attribute/create_attribute.py index b629b0d82..265d77305 100644 --- a/examples/create_attribute/create_attribute.py +++ b/examples/create_attribute/create_attribute.py @@ -5,7 +5,7 @@ and use them in the same way as the built-in Vehicle attributes. The code adds a new attribute to the Vehicle class, populating it with information from RAW_IMU messages -intercepted using set_mavlink_callback. +intercepted using the message_listener decorator. Full documentation is provided at http://python.dronekit.io/examples/create_attribute.html """ @@ -29,7 +29,6 @@ vehicle = connect(args.connect, wait_ready=True) - class RawIMU(object): """ The RAW IMU readings for the usual 9DOF sensor setup. @@ -73,57 +72,50 @@ def __str__(self): #Create an Vehicle.raw_imu object and set all values to None. vehicle.raw_imu=RawIMU(None,None,None,None,None,None,None,None,None,None) + -def mav_raw_imu_handler(message): - """ - Writes received message to the (newly attached) vehicle.raw_imu object and notifies observers. - """ - messagetype=str(message).split('{')[0].strip() - if messagetype=='RAW_IMU': - vehicle.raw_imu.time_boot_us=message.time_usec - vehicle.raw_imu.xacc=message.xacc - vehicle.raw_imu.yacc=message.yacc - vehicle.raw_imu.zacc=message.zacc - vehicle.raw_imu.xgyro=message.xgyro - vehicle.raw_imu.ygyro=message.ygyro - vehicle.raw_imu.zgyro=message.zgyro - vehicle.raw_imu.xmag=message.xmag - vehicle.raw_imu.ymag=message.ymag - vehicle.raw_imu.zmag=message.zmag - - #Add Notify all observers of new message. - vehicle.notify_observers('raw_imu') - - -def mavrx_debug_handler(message): +#Create a message listener using the decorator. +@vehicle.message_listener('RAW_IMU') +def listener(self, name, message): """ - Handler for MAVLink messages. + The listener is called for messages that contain the string specified in the decorator, + passing the vehicle, message name, and the message. + + The listener writes the message to the (newly attached) ``vehicle.raw_imu`` object + and notifies observers. """ - #Handle raw_imu messages - mav_raw_imu_handler(message) - -# Set MAVLink callback handler (after getting Vehicle instance) -vehicle.set_mavlink_callback(mavrx_debug_handler) + self.raw_imu.time_boot_us=message.time_usec + self.raw_imu.xacc=message.xacc + self.raw_imu.yacc=message.yacc + self.raw_imu.zacc=message.zacc + self.raw_imu.xgyro=message.xgyro + self.raw_imu.ygyro=message.ygyro + self.raw_imu.zgyro=message.zgyro + self.raw_imu.xmag=message.xmag + self.raw_imu.ymag=message.ymag + self.raw_imu.zmag=message.zmag + + # Notify all observers of new message. + self._notify_attribute_listeners('raw_imu') + """ From this point vehicle.raw_imu can be used just like any other attribute. """ #Callback to print the raw_imu -def raw_imu_callback(rawimu): - print vehicle.raw_imu +def raw_imu_callback(self,rawimu): + print self.raw_imu #Add observer for the vehicle's current location -vehicle.add_attribute_observer('raw_imu', raw_imu_callback) +vehicle.on_attribute('raw_imu', raw_imu_callback) print 'Display RAW_IMU messages for 5 seconds and then exit.' time.sleep(5) -#The observer can be unset using ``vehicle.unset_mavlink_callback()`` OR -# ``vehicle.set_mavlink_callback(None)``. -#It is automatically removed when the thread exits. +#The message listener can be unset using ``vehicle.remove_message_listener`` #Close vehicle object before exiting script diff --git a/examples/drone_delivery/drone_delivery.py b/examples/drone_delivery/drone_delivery.py index e617e99d7..c52189cd2 100644 --- a/examples/drone_delivery/drone_delivery.py +++ b/examples/drone_delivery/drone_delivery.py @@ -58,10 +58,10 @@ def __init__(self, home_coords, server_enabled=True): self._log("DroneDelivery Start") # Register observers - self.vehicle.add_attribute_observer('armed', self.armed_callback) - self.vehicle.add_attribute_observer('location', self.location_callback) - #self.vehicle.add_attribute_observer('mode', self.mode_callback) - self.vehicle.add_attribute_observer('gps_0', self.gps_callback) + self.vehicle.on_attribute('armed', self.armed_callback) + self.vehicle.on_attribute('location', self.location_callback) + #self.vehicle.on_attribute('mode', self.mode_callback) + self.vehicle.on_attribute('gps_0', self.gps_callback) self._log("Waiting for GPS Lock") @@ -123,7 +123,7 @@ def location_callback(self, location): def armed_callback(self, armed): self._log("DroneDelivery Armed Callback") - self.vehicle.remove_attribute_observer('armed', self.armed_callback) + self.vehicle.remove_message_listener('armed', self.armed_callback) def mode_callback(self, mode): self._log("Mode: {0}".format(self.vehicle.mode)) @@ -132,7 +132,7 @@ def gps_callback(self, gps): self._log("GPS: {0}".format(self.vehicle.gps_0)) if self.gps_lock is False: self.gps_lock = True - self.vehicle.remove_attribute_observer('gps_0', self.gps_callback) + self.vehicle.remove_message_listener('gps_0', self.gps_callback) self.run() def _log(self, message): From 251418ef31ec94530886cbf53aa13e42ee722767 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 5 Nov 2015 22:10:24 +1100 Subject: [PATCH 141/475] Add observer/message listener info to migrating guide. Message listener updates to API Ref --- docs/guide/migrating.rst | 23 +++++++++++++++++++++++ dronekit/lib/__init__.py | 14 +++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/docs/guide/migrating.rst b/docs/guide/migrating.rst index 4120b8673..03dce11af 100644 --- a/docs/guide/migrating.rst +++ b/docs/guide/migrating.rst @@ -183,3 +183,26 @@ instrument your code in order to launch the debugger, and debug messages were in Debugging on DroneKit-Python 2.x is much easier. Apps are now just standalone scripts, and can be debugged using standard Python methods (including the debugger/IDE of your choice). +Observing attribute changes +--------------------------- + +The DroneKit-Python 1.x observer functions ``vehicle.add_attribute_observer`` and ``Vehicle.remove_attribute_observer`` +have been replaced by :py:func:`Vehicle.on_attribute() ` +and :py:func:`remove_attribute_listener() `, respectively. + +The functions are used in a very similar way, the main difference being that the callback function now takes two arguments +(the vehicle and the attribute name) rather than just the attribute name. + +See :ref:`vehicle_state_observe_attributes` for more information. + +Intercepting MAVLink Messages +----------------------------- + +DroneKit-Python 1.x used ``Vehicle.set_mavlink_callback()`` and ``Vehicle.unset_mavlink_callback`` +to set/unset a callback function that was invoked for every single mavlink message. + +In DKPY2 this has been replaced by the :py:func:`Vehicle.message_listener() ` +decorator, which allows you to specify a callback function that will be invoked for a single message. The same +mechanism is used internally for message capture and to create ``Vehicle`` attributes. + +See :ref:`mavlink_messages` for more information. diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 2b3a1e92b..265cad371 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -868,12 +868,24 @@ def listener(self, name, msg): def message_listener(self, name): """ Decorator for message listeners. + + A decorated message listener is called with three arguments every time the + specified message is received: + + * ``self`` - the current vehicle. + * ``name`` - the name of the message that was intercepted. + * ``message`` - the actual message, a `pymavlink `_ + `class `_. + For example, in the fragment below ``my_method`` will be called for every heartbeat message: + .. code:: python @vehicle.message_listener('HEARTBEAT') def my_method(self, name, msg): pass + + :param String name: The name of the message to be intercepted by the decorated listener function. """ def decorator(fn): if isinstance(name, list): @@ -895,7 +907,7 @@ def on_message(self, name, fn): def remove_message_listener(self, name, fn): """ - Removes a message listener. + Removes a message listener (that was added using :py:func:`message_listener`) """ name = str(name) if name in self._message_listeners: From e09b975944b7b787986dc5f53e552e20e6638dac Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 5 Nov 2015 10:31:56 +1100 Subject: [PATCH 142/475] Fix GPSInfo to remove units from eph and epv definition --- dronekit/lib/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 265cad371..b463070d8 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -153,12 +153,12 @@ def __str__(self): class GPSInfo(object): """ - Standard information available about GPS. + Standard information about GPS. If there is no GPS lock the parameters are set to ``None``. - :param IntType eph: GPS horizontal dilution of position (HDOP) in cm (m*100). - :param IntType epv: GPS horizontal dilution of position (VDOP) in cm (m*100). + :param IntType eph: GPS horizontal dilution of position (HDOP). + :param IntType epv: GPS horizontal dilution of position (VDOP). :param IntType fix_type: 0-1: no fix, 2: 2D fix, 3: 3D fix :param IntType satellites_visible: Number of satellites visible. From 3aa02724be93897bb1c20b4fe6ee433067500ca2 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 5 Nov 2015 18:31:31 -0800 Subject: [PATCH 143/475] Adds docs building to Circle CI test. --- circle.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/circle.yml b/circle.yml index a61d9ecd0..ab69ade37 100644 --- a/circle.yml +++ b/circle.yml @@ -10,6 +10,10 @@ dependencies: test: override: + # docs + - 'cd docs; make clean; make html' + + # code - 'nosetests dronekit.test.web' - 'nosetests dronekit.test.unit' - 'nosetests dronekit.test.sitl' From 84615f6130f82889314030889e3a90ef36357c72 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 5 Nov 2015 18:35:29 -0800 Subject: [PATCH 144/475] Removes empty excluded-members line. --- docs/automodule.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/automodule.rst b/docs/automodule.rst index e8a9b1632..3fdb2e34a 100644 --- a/docs/automodule.rst +++ b/docs/automodule.rst @@ -8,7 +8,6 @@ DroneKit-Python API Reference .. automodule:: dronekit.lib :members: :inherited-members: - :exclude-members: From c210c9b08eaf69e7f9468415a93fbb853718e64d Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 6 Nov 2015 13:00:51 -0800 Subject: [PATCH 145/475] Don't try to reconnect during failed sends. --- dronekit/__init__.py | 47 +++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 1196085b2..d2517cf12 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -82,44 +82,26 @@ def mavlink_thread(): self.fix_targets(msg) self.master.write(msg) except socket.error as error: - if error.errno == ECONNABORTED: - errprinter('>>> reestablishing connection after read aborted') - if hasattr(self.master, 'reset'): - self.master.reset() - else: - try: - self.master.close() - except: - pass - self.master = mavutil.mavlink_connection(self.master.address) - continue - # If connection reset (closed), stop polling. - return + if error.errno == ECONNABORTED: + errprinter('>>> connection aborted during read') + return + raise except Empty: break except Exception as e: - errprinter('mav send error:', e) + errprinter('>>> mav send error:', e) break while self._accept_input: try: msg = self.master.recv_msg() except socket.error as error: - if error.errno == ECONNABORTED: - errprinter('>>> reestablishing connection after send aborted') - if hasattr(self.master, 'reset'): - self.master.reset() - else: - try: - self.master.close() - except: - pass - self.master = mavutil.mavlink_connection(self.master.address) - continue - # If connection reset (closed), stop polling. - return + if error.errno == ECONNABORTED: + errprinter('>>> connection aborting during send') + return + raise except Exception as e: # TODO this should be more rigorous. How to avoid # invalid MAVLink prefix '73' @@ -146,6 +128,17 @@ def mavlink_thread(): t.daemon = True self.mavlink_thread = t + def reset(self): + self.out_queue = Queue() + if hasattr(self.master, 'reset'): + self.master.reset() + else: + try: + self.master.close() + except: + pass + self.master = mavutil.mavlink_connection(self.master.address) + def fix_targets(self, message): """Set correct target IDs for our vehicle""" if hasattr(message, 'target_system'): From 2f7cdce062d1a7faae5d670af4c2037efd66fd7b Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 6 Nov 2015 13:02:42 -0800 Subject: [PATCH 146/475] Removes race condition in test_parameters --- dronekit/test/sitl/test_parameters.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dronekit/test/sitl/test_parameters.py b/dronekit/test/sitl/test_parameters.py index a6a815713..9cea8b856 100644 --- a/dronekit/test/sitl/test_parameters.py +++ b/dronekit/test/sitl/test_parameters.py @@ -9,8 +9,8 @@ def test_parameters(connpath): vehicle = connect(connpath) - # When called on startup, parameter should return none. - assert_equals(vehicle.parameters.get('THR_MIN', wait_ready=False), None) + # When called on startup, parameter (may!) be none. + # assert_equals(vehicle.parameters.get('THR_MIN', wait_ready=False), None) # With wait_ready, it should not be none. assert_not_equals(vehicle.parameters.get('THR_MIN', wait_ready=True), None) From ed52418e3f4b36e188895878d04e1122cd4924ae Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 5 Nov 2015 19:56:04 -0800 Subject: [PATCH 147/475] Corrects .next definition to be current waypoint (not command entry). --- dronekit/lib/__init__.py | 8 ++++---- examples/mission_basic/mission_basic.py | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index b463070d8..39e47ea88 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -698,11 +698,11 @@ def listener(self, name, m): self._fix_type = m.fix_type self._notify_attribute_listeners('gps_0') - self._last_waypoint = 0 + self._current_waypoint = 0 @self.message_listener(['WAYPOINT_CURRENT', 'MISSION_CURRENT']) def listener(self, name, m): - self._last_waypoint = max(m.seq - 1, 0) + self._current_waypoint = m.seq self._ekf_poshorizabs = False self._ekf_constposmode = False @@ -1520,14 +1520,14 @@ def next(self): """ Get the currently active waypoint number. """ - return self._vehicle._last_waypoint + return self._vehicle._current_waypoint @next.setter def next(self, index): """ Set a new ``next`` waypoint for the vehicle. """ - self._vehicle._master.waypoint_set_current_send(index + 1) + self._vehicle._master.waypoint_set_current_send(index) def __len__(self): ''' diff --git a/examples/mission_basic/mission_basic.py b/examples/mission_basic/mission_basic.py index 6e7e6ba16..8a438f4bd 100644 --- a/examples/mission_basic/mission_basic.py +++ b/examples/mission_basic/mission_basic.py @@ -140,6 +140,9 @@ def arm_and_takeoff(aTargetAltitude): print "Waiting for GPS...:", vehicle.gps_0.fix_type time.sleep(1) + # Wait for EKF to settle. + time.sleep(5) + print "Arming motors" # Copter should arm in GUIDED mode vehicle.mode = VehicleMode("GUIDED") From 73e50e33d1320148789d53cb7999557d6ca7e346 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 6 Nov 2015 13:09:22 -0800 Subject: [PATCH 148/475] 2.0.0rc8 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index c1dddcc87..98d2207fd 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.0.0rc7' +version = '2.0.0rc8' setup(name='dronekit', zip_safe=True, From cd2f26d5084078ffc02e38734f8f4dffb6831aca Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 6 Nov 2015 13:24:24 -0800 Subject: [PATCH 149/475] Renames on_attribute to add_attribute_listener, attribute_listener to on_attribute. --- docs/examples/create_attribute.rst | 10 +-- docs/guide/mavlink_messages.rst | 8 +-- docs/guide/migrating.rst | 4 +- docs/guide/vehicle_state_and_parameters.rst | 6 +- dronekit/__init__.py | 6 +- dronekit/lib/__init__.py | 70 +++++++++---------- dronekit/test/sitl/test_110.py | 12 ++-- dronekit/test/sitl/test_115.py | 2 +- dronekit/test/sitl/test_vehicleclass.py | 2 +- examples/create_attribute/create_attribute.py | 4 +- examples/drone_delivery/drone_delivery.py | 8 +-- examples/vehicle_state/vehicle_state.py | 4 +- 12 files changed, 68 insertions(+), 68 deletions(-) diff --git a/docs/examples/create_attribute.rst b/docs/examples/create_attribute.rst index 4afbd4af2..07ab1b631 100644 --- a/docs/examples/create_attribute.rst +++ b/docs/examples/create_attribute.rst @@ -7,10 +7,10 @@ Example: Create Attribute in App This example shows how you can create attributes for MAVLink messages within your DroneKit-Python script and use them in *in the same way* as the built-in :py:class:`Vehicle ` attributes. -It uses the :py:func:`Vehicle.message_listener() ` decorator +It uses the :py:func:`Vehicle.on_message() ` decorator to set a function that is called to process a specific message, copy its values into an attribute, and notify observers. An observer is then set on the new attribute using -:py:func:`Vehicle.on_attribute() `. +:py:func:`Vehicle.add_attribute_listener() `. Additional information is provided in the guide topic :ref:`mavlink_messages`. @@ -143,7 +143,7 @@ All values in the new attribute should be set to ``None`` so that it is obvious #Create an Vehicle.raw_imu object and set all values to None. vehicle.raw_imu=RawIMU(None,None,None,None,None,None,None,None,None,None) -We create a listener using the :py:func:`Vehicle.message_listener() ` +We create a listener using the :py:func:`Vehicle.on_message() ` decorator as shown below. The listener is called for messages that contain the string "RAW_IMU", with arguments for the vehicle, message name, and the message. It copies the message information into the attribute and then notifies all observers. @@ -151,7 +151,7 @@ the attribute and then notifies all observers. .. code:: python #Create a message listener using the decorator. - @vehicle.message_listener('RAW_IMU') + @vehicle.on_message('RAW_IMU') def listener(self, name, message): #Copy the message contents into the raw_imu attribute self.raw_imu.time_boot_us=message.time_usec @@ -187,7 +187,7 @@ You can query the attribute to get any of its members, and even add an observer #Add observer for the vehicle's current location - vehicle.on_attribute('raw_imu', raw_imu_callback) + vehicle.add_attribute_listener('raw_imu', raw_imu_callback) Known issues diff --git a/docs/guide/mavlink_messages.rst b/docs/guide/mavlink_messages.rst index c6f698547..9ee886657 100644 --- a/docs/guide/mavlink_messages.rst +++ b/docs/guide/mavlink_messages.rst @@ -8,7 +8,7 @@ Some useful MAVLink messages sent by the autopilot are not (yet) directly availa through the :ref:`observable attributes ` in :py:class:`Vehicle `. This topic shows how you can intercept specific MAVLink messages by defining a listener callback function -using the :py:func:`Vehicle.message_listener() ` +using the :py:func:`Vehicle.on_message() ` decorator. .. tip:: @@ -23,7 +23,7 @@ decorator. Creating a message listener =========================== -The :py:func:`Vehicle.message_listener() ` decorator can be used to +The :py:func:`Vehicle.on_message() ` decorator can be used to set a particular function as the callback handler for a particular message type. You can create listeners for as many messages as you like, or even multiple listeners for the same message. @@ -32,7 +32,7 @@ For example, code snippet below shows how to set a listener for the ``RANGEFINDE .. code:: python #Create a message listener using the decorator. - @vehicle.message_listener('RANGEFINDER') + @vehicle.on_message('RANGEFINDER') def listener(self, name, message): print message @@ -56,7 +56,7 @@ function might look like this: .. code:: python #Create a message listener using the decorator. - @vehicle.message_listener('RANGEFINDER') + @vehicle.on_message('RANGEFINDER') def listener(self, name, message): print 'distance: %s' % message.distance print 'voltage: %s' % message.voltage diff --git a/docs/guide/migrating.rst b/docs/guide/migrating.rst index 03dce11af..452efa7f0 100644 --- a/docs/guide/migrating.rst +++ b/docs/guide/migrating.rst @@ -187,7 +187,7 @@ Observing attribute changes --------------------------- The DroneKit-Python 1.x observer functions ``vehicle.add_attribute_observer`` and ``Vehicle.remove_attribute_observer`` -have been replaced by :py:func:`Vehicle.on_attribute() ` +have been replaced by :py:func:`Vehicle.add_attribute_listener() ` and :py:func:`remove_attribute_listener() `, respectively. The functions are used in a very similar way, the main difference being that the callback function now takes two arguments @@ -201,7 +201,7 @@ Intercepting MAVLink Messages DroneKit-Python 1.x used ``Vehicle.set_mavlink_callback()`` and ``Vehicle.unset_mavlink_callback`` to set/unset a callback function that was invoked for every single mavlink message. -In DKPY2 this has been replaced by the :py:func:`Vehicle.message_listener() ` +In DKPY2 this has been replaced by the :py:func:`Vehicle.on_message() ` decorator, which allows you to specify a callback function that will be invoked for a single message. The same mechanism is used internally for message capture and to create ``Vehicle`` attributes. diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index 416d530a7..a87e5a3fa 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -139,7 +139,7 @@ You can observe any of the attributes (except for :py:attr:`Vehicle.home_locatio :py:attr:`Vehicle.parameters `) and will receive notification every time a value is received from the connected vehicle. This allows you to monitor changes to velocity and other vehicle state without the need for polling. -Observers are added using :py:func:`Vehicle.on_attribute() `, +Observers are added using :py:func:`Vehicle.add_attribute_listener() `, specifying the name of the attribute to observe and a callback function. Observers are removed using :py:func:`remove_attribute_listener() `. @@ -163,7 +163,7 @@ callback is first run. print "Location (Local): ", self.location.local_frame # Add a callback. The first parameter the name of the observed attribute (a string). - vehicle.on_attribute('location', location_callback) + vehicle.add_attribute_listener('location', location_callback) # Wait 2s so callback can be notified before the observer is removed time.sleep(2) @@ -189,7 +189,7 @@ For example, the following code can be used in the callback to only print output last_rangefinder_distance = round(self.rangefinder.distance, 1) print " Rangefinder (metres): %s" % last_rangefinder_distance - vehicle.on_attribute('rangefinder', rangefinder_callback) + vehicle.add_attribute_listener('rangefinder', rangefinder_callback) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index d2517cf12..14710f283 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -146,13 +146,13 @@ def fix_targets(self, message): if hasattr(message, 'target_component'): message.target_component = self.target_component - def loop_listener(self, fn): + def forward_loop(self, fn): """ Decorator for event loop. """ self.loop_listeners.append(fn) - def message_listener(self, fn): + def forward_message(self, fn): """ Decorator for message inputs. """ @@ -174,7 +174,7 @@ def connect(ip, wait_ready=None, status_printer=errprinter, vehicle_class=Vehicl vehicle = vehicle_class(handler) if status_printer: - @vehicle.message_listener('STATUSTEXT') + @vehicle.on_message('STATUSTEXT') def listener(self, name, m): status_printer(re.sub(r'(^|\n)', '>>> ', m.text.rstrip())) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 39e47ea88..e9a4e5075 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -238,7 +238,7 @@ def mode_callback(self, attr_name): print "Vehicle Mode", self.mode #Add observer callback for attribute `mode` - vehicle.on_attribute('mode', mode_callback) + vehicle.add_attribute_listener('mode', mode_callback) The code snippet below shows how to change the vehicle mode to AUTO: @@ -276,7 +276,7 @@ def __init__(self): The argument list for observer is ``observer(object, attr_name)``. """ - def on_attribute(self, attr_name, observer): + def add_attribute_listener(self, attr_name, observer): """ Add an attribute listener. @@ -298,7 +298,7 @@ def location_callback(self, attr_name): print "Location (Local): ", self.location.local_frame #Add observer for the vehicle's current location - vehicle.on_attribute('location', location_callback) + vehicle.add_attribute_listener('location', location_callback) .. note:: @@ -320,7 +320,7 @@ def location_callback(self, attr_name): def remove_attribute_listener(self, attr_name, observer): """ - Remove an attribute listener (observer) that was previously added using :py:func:`on_attribute`. + Remove an attribute listener (observer) that was previously added using :py:func:`add_attribute_listener`. For example, the following line would remove a previously added vehicle 'global_frame' observer called ``location_callback``: @@ -352,12 +352,12 @@ def _notify_attribute_listeners(self, attr_name): for fn in self.__observers.get('*', []): fn(self, attr_name) - def attribute_listener(self, name): + def on_attribute(self, name): """ Decorator for attribute listeners. This is used to create/define new attribute listenters. After using this method you can - register an observer for the attribute using :py:func:`on_attribute`. + register an observer for the attribute using :py:func:`add_attribute_listener`. .. note:: @@ -368,16 +368,16 @@ def attribute_listener(self, name): .. code:: python - @vehicle.attribute_listener('attitude') + @vehicle.on_attribute('attitude') def attitude_listener(self, name, msg): pass """ def decorator(fn): if isinstance(name, list): for n in name: - self.on_attribute(n, fn) + self.add_attribute_listener(n, fn) else: - self.on_attribute(name, fn) + self.add_attribute_listener(name, fn) return decorator class Vehicle(HasObservers): @@ -568,14 +568,14 @@ def __init__(self, handler): # Default parameters when calling wait_ready() or wait_ready(True). self._default_ready_attrs = ['parameters', 'gps_0', 'armed', 'mode', 'attitude'] - @self.attribute_listener('*') + @self.on_attribute('*') def listener(_, name): self._ready_attrs.add(name) # Attaches message listeners. self._message_listeners = dict() - @handler.message_listener + @handler.forward_message def listener(_, msg): self._notify_message_listeners(msg.get_type(), msg) @@ -585,7 +585,7 @@ def listener(_, msg): self._vy = None self._vz = None - @self.message_listener('GLOBAL_POSITION_INT') + @self.on_message('GLOBAL_POSITION_INT') def listener(self, name, m): (self._lat, self._lon) = (m.lat / 1.0e7, m.lon / 1.0e7) self._notify_attribute_listeners('location') @@ -596,7 +596,7 @@ def listener(self, name, m): self._east = None self._down = None - @self.message_listener('LOCAL_POSITION_NED') + @self.on_message('LOCAL_POSITION_NED') def listener(self, name, m): self._north = m.x self._east = m.y @@ -610,7 +610,7 @@ def listener(self, name, m): self._yawspeed = None self._rollspeed = None - @self.message_listener('ATTITUDE') + @self.on_message('ATTITUDE') def listener(self, name, m): self._pitch = m.pitch self._yaw = m.yaw @@ -625,7 +625,7 @@ def listener(self, name, m): self._airspeed = None self._groundspeed = None - @self.message_listener('VFR_HUD') + @self.on_message('VFR_HUD') def listener(self, name, m): self._heading = m.heading self._notify_attribute_listeners('heading') @@ -639,7 +639,7 @@ def listener(self, name, m): self._rngfnd_distance = None self._rngfnd_voltage = None - @self.message_listener('RANGEFINDER') + @self.on_message('RANGEFINDER') def listener(self, name, m): self._rngfnd_distance = m.distance self._rngfnd_voltage = m.voltage @@ -649,7 +649,7 @@ def listener(self, name, m): self._mount_yaw = None self._mount_roll = None - @self.message_listener('MOUNT_STATUS') + @self.on_message('MOUNT_STATUS') def listener(self, name, m): self._mount_pitch = m.pointing_a / 100 self._mount_roll = m.pointing_b / 100 @@ -658,7 +658,7 @@ def listener(self, name, m): self._rc_readback = {} - @self.message_listener('RC_CHANNELS_RAW') + @self.on_message('RC_CHANNELS_RAW') def listener(self, name, m): def set_rc(chnum, v): '''Private utility for handling rc channel messages''' @@ -678,7 +678,7 @@ def set_rc(chnum, v): self._current = None self._level = None - @self.message_listener('SYS_STATUS') + @self.on_message('SYS_STATUS') def listener(self, name, m): self._voltage = m.voltage_battery self._current = m.current_battery @@ -690,7 +690,7 @@ def listener(self, name, m): self._satellites_visible = None self._fix_type = None # FIXME support multiple GPSs per vehicle - possibly by using componentId - @self.message_listener('GPS_RAW_INT') + @self.on_message('GPS_RAW_INT') def listener(self, name, m): self._eph = m.eph self._epv = m.epv @@ -700,7 +700,7 @@ def listener(self, name, m): self._current_waypoint = 0 - @self.message_listener(['WAYPOINT_CURRENT', 'MISSION_CURRENT']) + @self.on_message(['WAYPOINT_CURRENT', 'MISSION_CURRENT']) def listener(self, name, m): self._current_waypoint = m.seq @@ -708,7 +708,7 @@ def listener(self, name, m): self._ekf_constposmode = False self._ekf_predposhorizabs = False - @self.message_listener('EKF_STATUS_REPORT') + @self.on_message('EKF_STATUS_REPORT') def listener(self, name, m): # boolean: EKF's horizontal position (absolute) estimate is good self._ekf_poshorizabs = (m.flags & ardupilotmega.EKF_POS_HORIZ_ABS) > 0 @@ -723,7 +723,7 @@ def listener(self, name, m): self._armed = False self._system_status = None - @self.message_listener('HEARTBEAT') + @self.on_message('HEARTBEAT') def listener(self, name, m): self._armed = (m.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED) != 0 self._notify_attribute_listeners('armed') @@ -739,14 +739,14 @@ def listener(self, name, m): self._wpts_dirty = False self._commands = CommandSequence(self) - @self.message_listener(['WAYPOINT_COUNT','MISSION_COUNT']) + @self.on_message(['WAYPOINT_COUNT','MISSION_COUNT']) def listener(self, name, msg): if not self._wp_loaded: self._wploader.clear() self._wploader.expected_count = msg.count self._master.waypoint_request_send(0) - @self.message_listener(['WAYPOINT', 'MISSION_ITEM']) + @self.on_message(['WAYPOINT', 'MISSION_ITEM']) def listener(self, name, msg): if not self._wp_loaded: if msg.seq > self._wploader.count(): @@ -765,7 +765,7 @@ def listener(self, name, msg): self._notify_attribute_listeners('commands') # Waypoint send to master - @self.message_listener(['WAYPOINT_REQUEST', 'MISSION_REQUEST']) + @self.on_message(['WAYPOINT_REQUEST', 'MISSION_REQUEST']) def listener(self, name, msg): if self._wp_uploaded != None: wp = self._wploader.wp(msg.seq) @@ -789,7 +789,7 @@ def listener(self, name, msg): self._params_duration = start_duration self._parameters = Parameters(self) - @handler.loop_listener + @handler.forward_loop def listener(_): # Check the time duration for last "new" params exceeds watchdog. if self._params_start: @@ -808,7 +808,7 @@ def listener(_): self._params_duration = repeat_duration self._params_last = time.time() - @self.message_listener(['PARAM_VALUE']) + @self.on_message(['PARAM_VALUE']) def listener(self, name, msg): # If we discover a new param count, assume we # are receiving a new param set. @@ -842,7 +842,7 @@ def listener(self, name, msg): self._heartbeat_warning = 5 self._heartbeat_error = 30 - @handler.loop_listener + @handler.forward_loop def listener(_): # Send 1 heartbeat per second if time.time() - self._heartbeat_lastsent > 1: @@ -858,14 +858,14 @@ def listener(_): errprinter('>>> Link timeout, no heartbeat in last %s seconds' % self._heartbeat_warning) self._heartbeat_timeout = True - @self.message_listener(['HEARTBEAT']) + @self.on_message(['HEARTBEAT']) def listener(self, name, msg): self._heartbeat_lastreceived = time.time() if self._heartbeat_timeout: errprinter('>>> ...link restored.') self._heartbeat_timeout = False - def message_listener(self, name): + def on_message(self, name): """ Decorator for message listeners. @@ -881,7 +881,7 @@ def message_listener(self, name): .. code:: python - @vehicle.message_listener('HEARTBEAT') + @vehicle.on_message('HEARTBEAT') def my_method(self, name, msg): pass @@ -890,12 +890,12 @@ def my_method(self, name, msg): def decorator(fn): if isinstance(name, list): for n in name: - self.on_message(n, fn) + self.add_message_listener(n, fn) else: - self.on_message(name, fn) + self.add_message_listener(name, fn) return decorator - def on_message(self, name, fn): + def add_message_listener(self, name, fn): """ Adds a message listener. """ diff --git a/dronekit/test/sitl/test_110.py b/dronekit/test/sitl/test_110.py index 20714b31f..bccc184c5 100644 --- a/dronekit/test/sitl/test_110.py +++ b/dronekit/test/sitl/test_110.py @@ -26,13 +26,13 @@ def armed_callback(vehicle, attribute): armed_callback.called += 1 armed_callback.called = 0 - # When the same (event, callback) pair is passed to on_attribute, + # When the same (event, callback) pair is passed to add_attribute_listener, # only one instance of the observer callback should be added. - vehicle.on_attribute('armed', armed_callback) - vehicle.on_attribute('armed', armed_callback) - vehicle.on_attribute('armed', armed_callback) - vehicle.on_attribute('armed', armed_callback) - vehicle.on_attribute('armed', armed_callback) + vehicle.add_attribute_listener('armed', armed_callback) + vehicle.add_attribute_listener('armed', armed_callback) + vehicle.add_attribute_listener('armed', armed_callback) + vehicle.add_attribute_listener('armed', armed_callback) + vehicle.add_attribute_listener('armed', armed_callback) # Disarm and see update. vehicle.armed = False diff --git a/dronekit/test/sitl/test_115.py b/dronekit/test/sitl/test_115.py index bbf6474e5..19180ff3b 100644 --- a/dronekit/test/sitl/test_115.py +++ b/dronekit/test/sitl/test_115.py @@ -15,7 +15,7 @@ def mavlink_callback(*args): mavlink_callback.count = 0 # Set the callback. - v.on_message('*', mavlink_callback) + v.add_message_listener('*', mavlink_callback) # Change the vehicle into STABILIZE mode v.mode = VehicleMode("STABILIZE") diff --git a/dronekit/test/sitl/test_vehicleclass.py b/dronekit/test/sitl/test_vehicleclass.py index f6150f6c3..3f88342f1 100644 --- a/dronekit/test/sitl/test_vehicleclass.py +++ b/dronekit/test/sitl/test_vehicleclass.py @@ -10,7 +10,7 @@ def __init__(self, *args): self.success = False def success_fn(self, name, m): self.success = True - self.on_message('HEARTBEAT', success_fn) + self.add_message_listener('HEARTBEAT', success_fn) @with_sitl def test_timeout(connpath): diff --git a/examples/create_attribute/create_attribute.py b/examples/create_attribute/create_attribute.py index 265d77305..030d19153 100644 --- a/examples/create_attribute/create_attribute.py +++ b/examples/create_attribute/create_attribute.py @@ -76,7 +76,7 @@ def __str__(self): #Create a message listener using the decorator. -@vehicle.message_listener('RAW_IMU') +@vehicle.on_message('RAW_IMU') def listener(self, name, message): """ The listener is called for messages that contain the string specified in the decorator, @@ -110,7 +110,7 @@ def raw_imu_callback(self,rawimu): #Add observer for the vehicle's current location -vehicle.on_attribute('raw_imu', raw_imu_callback) +vehicle.add_attribute_listener('raw_imu', raw_imu_callback) print 'Display RAW_IMU messages for 5 seconds and then exit.' time.sleep(5) diff --git a/examples/drone_delivery/drone_delivery.py b/examples/drone_delivery/drone_delivery.py index c52189cd2..91a329ca3 100644 --- a/examples/drone_delivery/drone_delivery.py +++ b/examples/drone_delivery/drone_delivery.py @@ -58,10 +58,10 @@ def __init__(self, home_coords, server_enabled=True): self._log("DroneDelivery Start") # Register observers - self.vehicle.on_attribute('armed', self.armed_callback) - self.vehicle.on_attribute('location', self.location_callback) - #self.vehicle.on_attribute('mode', self.mode_callback) - self.vehicle.on_attribute('gps_0', self.gps_callback) + self.vehicle.add_attribute_listener('armed', self.armed_callback) + self.vehicle.add_attribute_listener('location', self.location_callback) + #self.vehicle.add_attribute_listener('mode', self.mode_callback) + self.vehicle.add_attribute_listener('gps_0', self.gps_callback) self._log("Waiting for GPS Lock") diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 049785741..e3ac58a22 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -111,7 +111,7 @@ def mode_callback(self, attr_name): print " CALLBACK: Mode changed to", self.mode print "\nAdd attribute callback/observer on `vehicle` for `mode` attribute" -vehicle.on_attribute('mode', mode_callback) +vehicle.add_attribute_listener('mode', mode_callback) print " Set mode=STABILIZE (currently: %s)" % vehicle.mode.name @@ -121,7 +121,7 @@ def mode_callback(self, attr_name): time.sleep(2) print " Remove Vehicle.mode observer" -# Remove observer added with `on_attribute()` - specifying the attribute and callback function +# Remove observer added with `add_attribute_listener()` - specifying the attribute and callback function vehicle.remove_attribute_listener('mode', mode_callback) From a2448c9cece938a50a05c433c88c0751be9f4162 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 6 Nov 2015 15:56:17 -0800 Subject: [PATCH 150/475] Makes notification functions public. --- docs/examples/create_attribute.rst | 2 +- dronekit/lib/__init__.py | 40 +++++++++---------- examples/create_attribute/create_attribute.py | 2 +- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/docs/examples/create_attribute.rst b/docs/examples/create_attribute.rst index 07ab1b631..a7c2f0613 100644 --- a/docs/examples/create_attribute.rst +++ b/docs/examples/create_attribute.rst @@ -166,7 +166,7 @@ the attribute and then notifies all observers. self.raw_imu.zmag=message.zmag # Notify all observers of new message. - self._notify_attribute_listeners('raw_imu') + self.notify_attribute_listeners('raw_imu') .. note:: diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index e9a4e5075..1fdf627a1 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -339,7 +339,7 @@ def remove_attribute_listener(self, attr_name, observer): if len(l) == 0: del self.__observers[attr_name] - def _notify_attribute_listeners(self, attr_name): + def notify_attribute_listeners(self, attr_name): """ Internal function. Do not use. @@ -577,7 +577,7 @@ def listener(_, name): @handler.forward_message def listener(_, msg): - self._notify_message_listeners(msg.get_type(), msg) + self.notify_message_listeners(msg.get_type(), msg) self._lat = None self._lon = None @@ -588,9 +588,9 @@ def listener(_, msg): @self.on_message('GLOBAL_POSITION_INT') def listener(self, name, m): (self._lat, self._lon) = (m.lat / 1.0e7, m.lon / 1.0e7) - self._notify_attribute_listeners('location') + self.notify_attribute_listeners('location') (self._vx, self._vy, self._vz) = (m.vx / 100.0, m.vy / 100.0, m.vz / 100.0) - self._notify_attribute_listeners('velocity') + self.notify_attribute_listeners('velocity') self._north = None self._east = None @@ -601,7 +601,7 @@ def listener(self, name, m): self._north = m.x self._east = m.y self._down = m.z - self._notify_attribute_listeners('local_position') + self.notify_attribute_listeners('local_position') self._pitch = None self._yaw = None @@ -618,7 +618,7 @@ def listener(self, name, m): self._pitchspeed = m.pitchspeed self._yawspeed = m.yawspeed self._rollspeed = m.rollspeed - self._notify_attribute_listeners('attitude') + self.notify_attribute_listeners('attitude') self._heading = None self._alt = None @@ -628,13 +628,13 @@ def listener(self, name, m): @self.on_message('VFR_HUD') def listener(self, name, m): self._heading = m.heading - self._notify_attribute_listeners('heading') + self.notify_attribute_listeners('heading') self._alt = m.alt - self._notify_attribute_listeners('location') + self.notify_attribute_listeners('location') self._airspeed = m.airspeed - self._notify_attribute_listeners('airspeed') + self.notify_attribute_listeners('airspeed') self._groundspeed = m.groundspeed - self._notify_attribute_listeners('groundspeed') + self.notify_attribute_listeners('groundspeed') self._rngfnd_distance = None self._rngfnd_voltage = None @@ -643,7 +643,7 @@ def listener(self, name, m): def listener(self, name, m): self._rngfnd_distance = m.distance self._rngfnd_voltage = m.voltage - self._notify_attribute_listeners('rangefinder') + self.notify_attribute_listeners('rangefinder') self._mount_pitch = None self._mount_yaw = None @@ -654,7 +654,7 @@ def listener(self, name, m): self._mount_pitch = m.pointing_a / 100 self._mount_roll = m.pointing_b / 100 self._mount_yaw = m.pointing_c / 100 - self._notify_attribute_listeners('mount') + self.notify_attribute_listeners('mount') self._rc_readback = {} @@ -683,7 +683,7 @@ def listener(self, name, m): self._voltage = m.voltage_battery self._current = m.current_battery self._level = m.battery_remaining - self._notify_attribute_listeners('battery') + self.notify_attribute_listeners('battery') self._eph = None self._epv = None @@ -696,7 +696,7 @@ def listener(self, name, m): self._epv = m.epv self._satellites_visible = m.satellites_visible self._fix_type = m.fix_type - self._notify_attribute_listeners('gps_0') + self.notify_attribute_listeners('gps_0') self._current_waypoint = 0 @@ -717,7 +717,7 @@ def listener(self, name, m): # boolean: EKF's predicted horizontal position (absolute) estimate is good self._ekf_predposhorizabs = (m.flags & ardupilotmega.EKF_PRED_POS_HORIZ_ABS) > 0 - self._notify_attribute_listeners('ekf_ok') + self.notify_attribute_listeners('ekf_ok') self._flightmode = 'AUTO' self._armed = False @@ -726,10 +726,10 @@ def listener(self, name, m): @self.on_message('HEARTBEAT') def listener(self, name, m): self._armed = (m.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED) != 0 - self._notify_attribute_listeners('armed') + self.notify_attribute_listeners('armed') self._flightmode = {v: k for k, v in self._master.mode_mapping().items()}[m.custom_mode] self._system_status = m.system_status - self._notify_attribute_listeners('mode') + self.notify_attribute_listeners('mode') # Waypoints. @@ -762,7 +762,7 @@ def listener(self, name, msg): self._master.waypoint_request_send(msg.seq + 1) else: self._wp_loaded = True - self._notify_attribute_listeners('commands') + self.notify_attribute_listeners('commands') # Waypoint send to master @self.on_message(['WAYPOINT_REQUEST', 'MISSION_REQUEST']) @@ -795,7 +795,7 @@ def listener(_): if self._params_start: if None not in self._params_set and not self._params_loaded: self._params_loaded = True - self._notify_attribute_listeners('parameters') + self.notify_attribute_listeners('parameters') if not self._params_loaded and time.time() - self._params_last > self._params_duration: c = 0 @@ -915,7 +915,7 @@ def remove_message_listener(self, name, fn): if len(self._message_listeners[name]) == 0: del self._message_listeners[name] - def _notify_message_listeners(self, name, msg): + def notify_message_listeners(self, name, msg): for fn in self._message_listeners.get(name, []): fn(self, name, msg) for fn in self._message_listeners.get('*', []): diff --git a/examples/create_attribute/create_attribute.py b/examples/create_attribute/create_attribute.py index 030d19153..acd40da1b 100644 --- a/examples/create_attribute/create_attribute.py +++ b/examples/create_attribute/create_attribute.py @@ -97,7 +97,7 @@ def listener(self, name, message): self.raw_imu.zmag=message.zmag # Notify all observers of new message. - self._notify_attribute_listeners('raw_imu') + self.notify_attribute_listeners('raw_imu') """ From 4c71279908d1623b31804be8be87d6095db56438 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 6 Nov 2015 16:15:15 -0800 Subject: [PATCH 151/475] Passes attribute value into listener. --- dronekit/lib/__init__.py | 42 +++++++++++++++++----------------- dronekit/test/sitl/test_110.py | 2 +- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 1fdf627a1..6e62b3c3e 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -339,7 +339,7 @@ def remove_attribute_listener(self, attr_name, observer): if len(l) == 0: del self.__observers[attr_name] - def notify_attribute_listeners(self, attr_name): + def notify_attribute_listeners(self, attr_name, value): """ Internal function. Do not use. @@ -348,9 +348,9 @@ def notify_attribute_listeners(self, attr_name): .. INTERNAL NOTE: (For subclass use only) """ for fn in self.__observers.get(attr_name, []): - fn(self, attr_name) + fn(self, attr_name, value) for fn in self.__observers.get('*', []): - fn(self, attr_name) + fn(self, attr_name, value) def on_attribute(self, name): """ @@ -569,7 +569,7 @@ def __init__(self, handler): self._default_ready_attrs = ['parameters', 'gps_0', 'armed', 'mode', 'attitude'] @self.on_attribute('*') - def listener(_, name): + def listener(_, name, value): self._ready_attrs.add(name) # Attaches message listeners. @@ -588,9 +588,9 @@ def listener(_, msg): @self.on_message('GLOBAL_POSITION_INT') def listener(self, name, m): (self._lat, self._lon) = (m.lat / 1.0e7, m.lon / 1.0e7) - self.notify_attribute_listeners('location') + self.notify_attribute_listeners('location', self.location) (self._vx, self._vy, self._vz) = (m.vx / 100.0, m.vy / 100.0, m.vz / 100.0) - self.notify_attribute_listeners('velocity') + self.notify_attribute_listeners('velocity', self.velocity) self._north = None self._east = None @@ -601,7 +601,7 @@ def listener(self, name, m): self._north = m.x self._east = m.y self._down = m.z - self.notify_attribute_listeners('local_position') + self.notify_attribute_listeners('local_position', self.location.local_frame) self._pitch = None self._yaw = None @@ -618,7 +618,7 @@ def listener(self, name, m): self._pitchspeed = m.pitchspeed self._yawspeed = m.yawspeed self._rollspeed = m.rollspeed - self.notify_attribute_listeners('attitude') + self.notify_attribute_listeners('attitude', self.attitude) self._heading = None self._alt = None @@ -628,13 +628,13 @@ def listener(self, name, m): @self.on_message('VFR_HUD') def listener(self, name, m): self._heading = m.heading - self.notify_attribute_listeners('heading') + self.notify_attribute_listeners('heading', self.heading) self._alt = m.alt - self.notify_attribute_listeners('location') + self.notify_attribute_listeners('location', self.location) self._airspeed = m.airspeed - self.notify_attribute_listeners('airspeed') + self.notify_attribute_listeners('airspeed', self.airspeed) self._groundspeed = m.groundspeed - self.notify_attribute_listeners('groundspeed') + self.notify_attribute_listeners('groundspeed', self.groundspeed) self._rngfnd_distance = None self._rngfnd_voltage = None @@ -643,7 +643,7 @@ def listener(self, name, m): def listener(self, name, m): self._rngfnd_distance = m.distance self._rngfnd_voltage = m.voltage - self.notify_attribute_listeners('rangefinder') + self.notify_attribute_listeners('rangefinder', self.rangefinder) self._mount_pitch = None self._mount_yaw = None @@ -654,7 +654,7 @@ def listener(self, name, m): self._mount_pitch = m.pointing_a / 100 self._mount_roll = m.pointing_b / 100 self._mount_yaw = m.pointing_c / 100 - self.notify_attribute_listeners('mount') + self.notify_attribute_listeners('mount', self.mount_status) self._rc_readback = {} @@ -683,7 +683,7 @@ def listener(self, name, m): self._voltage = m.voltage_battery self._current = m.current_battery self._level = m.battery_remaining - self.notify_attribute_listeners('battery') + self.notify_attribute_listeners('battery', self.battery) self._eph = None self._epv = None @@ -696,7 +696,7 @@ def listener(self, name, m): self._epv = m.epv self._satellites_visible = m.satellites_visible self._fix_type = m.fix_type - self.notify_attribute_listeners('gps_0') + self.notify_attribute_listeners('gps_0', self.gps_0) self._current_waypoint = 0 @@ -717,7 +717,7 @@ def listener(self, name, m): # boolean: EKF's predicted horizontal position (absolute) estimate is good self._ekf_predposhorizabs = (m.flags & ardupilotmega.EKF_PRED_POS_HORIZ_ABS) > 0 - self.notify_attribute_listeners('ekf_ok') + self.notify_attribute_listeners('ekf_ok', self.ekf_ok) self._flightmode = 'AUTO' self._armed = False @@ -726,10 +726,10 @@ def listener(self, name, m): @self.on_message('HEARTBEAT') def listener(self, name, m): self._armed = (m.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED) != 0 - self.notify_attribute_listeners('armed') + self.notify_attribute_listeners('armed', self.armed) self._flightmode = {v: k for k, v in self._master.mode_mapping().items()}[m.custom_mode] self._system_status = m.system_status - self.notify_attribute_listeners('mode') + self.notify_attribute_listeners('mode', self.mode) # Waypoints. @@ -762,7 +762,7 @@ def listener(self, name, msg): self._master.waypoint_request_send(msg.seq + 1) else: self._wp_loaded = True - self.notify_attribute_listeners('commands') + self.notify_attribute_listeners('commands', self.commands) # Waypoint send to master @self.on_message(['WAYPOINT_REQUEST', 'MISSION_REQUEST']) @@ -795,7 +795,7 @@ def listener(_): if self._params_start: if None not in self._params_set and not self._params_loaded: self._params_loaded = True - self.notify_attribute_listeners('parameters') + self.notify_attribute_listeners('parameters', self.parameters) if not self._params_loaded and time.time() - self._params_last > self._params_duration: c = 0 diff --git a/dronekit/test/sitl/test_110.py b/dronekit/test/sitl/test_110.py index bccc184c5..98c4e567e 100644 --- a/dronekit/test/sitl/test_110.py +++ b/dronekit/test/sitl/test_110.py @@ -22,7 +22,7 @@ def test_110(connpath): time.sleep(3) # Define example callback for mode - def armed_callback(vehicle, attribute): + def armed_callback(vehicle, attribute, value): armed_callback.called += 1 armed_callback.called = 0 From 2dcfd0e60803dfbf2b9ea89e541f8b9f405f4a6a Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 9 Nov 2015 15:20:38 +1100 Subject: [PATCH 152/475] Fixes attribute/message callback docs for #426 --- docs/examples/create_attribute.rst | 15 +- docs/examples/vehicle_state.rst | 42 ++++-- docs/guide/mavlink_messages.rst | 31 ++-- docs/guide/migrating.rst | 51 +++++-- docs/guide/vehicle_state_and_parameters.rst | 76 +++++++--- dronekit/lib/__init__.py | 134 ++++++++++++------ examples/create_attribute/create_attribute.py | 15 +- examples/vehicle_state/vehicle_state.py | 60 +++++++- 8 files changed, 311 insertions(+), 113 deletions(-) diff --git a/docs/examples/create_attribute.rst b/docs/examples/create_attribute.rst index a7c2f0613..e2c37d8a4 100644 --- a/docs/examples/create_attribute.rst +++ b/docs/examples/create_attribute.rst @@ -111,7 +111,7 @@ representation for printing the object. :param zmag: Z Magnetic field (milli tesla) """ - def __init__(self, time_boot_us, xacc, yacc, zacc, xygro, ygyro, zgyro, xmag, ymag, zmag): + def __init__(self, time_boot_us=None, xacc=None, yacc=None, zacc=None, xygro=None, ygyro=None, zgyro=None, xmag=None, ymag=None, zmag=None): """ RawIMU object constructor. """ @@ -140,8 +140,8 @@ All values in the new attribute should be set to ``None`` so that it is obvious # Connect to the Vehicle passed in as args.connect vehicle = connect(args.connect, wait_ready=True) - #Create an Vehicle.raw_imu object and set all values to None. - vehicle.raw_imu=RawIMU(None,None,None,None,None,None,None,None,None,None) + #Create an Vehicle.raw_imu object with values set to `None`. + vehicle.raw_imu=RawIMU() We create a listener using the :py:func:`Vehicle.on_message() ` decorator as shown below. The listener is called for messages that contain the string "RAW_IMU", @@ -165,8 +165,8 @@ the attribute and then notifies all observers. self.raw_imu.ymag=message.ymag self.raw_imu.zmag=message.zmag - # Notify all observers of new message. - self.notify_attribute_listeners('raw_imu') + # Notify all observers of new message with new value + self.notify_attribute_listeners('raw_imu', self.raw_imu) .. note:: @@ -182,8 +182,9 @@ You can query the attribute to get any of its members, and even add an observer .. code:: python #Callback to print the raw_imu - def raw_imu_callback(self, attr_name): - print self.raw_imu + def raw_imu_callback(self, attr_name, msg): + #msg is the value/attribute that was updated. + print msg #Add observer for the vehicle's current location diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index 6ab011add..039b4e0b8 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -49,31 +49,30 @@ On the command prompt you should see (something like): .. code:: bash - Connecting to vehicle on: 127.0.0.1:14550 >>> APM:Copter V3.3 (d6053245) >>> Frame: QUAD Accumulating vehicle attribute messages Get all vehicle attribute values: - Global Location: LocationGlobal:lat=-35.3632585,lon=149.165227,alt=362.0,is_relative=False + Global Location: LocationGlobal:lat=-35.3632361,lon=149.1652374,alt=361.989990234,is_relative=False Local Location: LocationLocal:north=None,east=None,down=None - Attitude: Attitude:pitch=-0.00352983362973,yaw=-0.0589601770043,roll=-0.00761049194261 - Velocity: [0.02, -0.02, 0.0] + Attitude: Attitude:pitch=-0.0078572165221,yaw=-0.352846503258,roll=0.00523957656696 + Velocity: [-0.02, 0.01, 0.0] GPS: GPSInfo:fix=3,num_sat=10 Groundspeed: 0.0 Airspeed: 0.0 Mount status: [None, None, None] - Battery: Battery:voltage=12.587,current=0.0,level=98 + Battery: Battery:voltage=12.587,current=0.0,level=95 Rangefinder: Rangefinder: distance=None, voltage=None Rangefinder distance: None Rangefinder voltage: None Mode: STABILIZE Armed: False - Home Location: LocationGlobal:lat=-35.3632583618,lon=149.165222168,alt=222.0,is_relative=False + Home Location: LocationGlobal:lat=-35.3632392883,lon=149.165237427,alt=222.0,is_relative=False Set new home location - New Home Location (altitude should be 222): LocationGlobal:lat=-35.3632583618,lon=149.165222168,alt=222.0,is_relative=False + New Home Location (altitude should be 222): LocationGlobal:lat=-35.3632354736,lon=149.165237427,alt=222.0,is_relative=False Set Vehicle.mode=GUIDED (currently: STABILIZE) Waiting for mode change ... @@ -87,15 +86,42 @@ On the command prompt you should see (something like): Set mode=STABILIZE (currently: GUIDED) Wait 2s so callback invoked before observer removed CALLBACK: Mode changed to VehicleMode:STABILIZE - CALLBACK: Mode changed to VehicleMode:STABILIZE Remove Vehicle.mode observer + Add attribute callback/observer `mode` attribute using decorator + Set mode=GUIDED (currently: STABILIZE) + Wait 2s so callback invoked before observer removed + CALLBACK: Mode changed to VehicleMode:GUIDED + + Attempt to remove observer added with `on_attribute` decorator (should fail) + Exception: Cannot add observer added using decorator + + Add attribute calback detecting any attribute change + Wait 1s so callback invoked before observer removed + CALLBACK: (battery): Battery:voltage=12.538,current=3.48,level=95 + CALLBACK: (gps_0): GPSInfo:fix=3,num_sat=10 + CALLBACK: (location): LocationGlobal:lat=-35.3632361,lon=149.1652379,alt=361.989990234,is_relative=False + CALLBACK: (velocity): [-0.01, 0.03, 0.0] + CALLBACK: (local_position): LocationLocal:north=2.78085613251,east=0.730665147305,down=0.00156301062088 + CALLBACK: (attitude): Attitude:pitch=-0.00780974514782,yaw=-0.361094027758,roll=0.00564418500289 + CALLBACK: (heading): 339 + CALLBACK: (location): LocationGlobal:lat=-35.3632361,lon=149.1652379,alt=361.989990234,is_relative=False + CALLBACK: (airspeed): 0.019999999553 + CALLBACK: (groundspeed): 0.019999999553 + CALLBACK: (ekf_ok): True + CALLBACK: (armed): True + CALLBACK: (mode): VehicleMode:GUIDED + ... + CALLBACK: (ekf_ok): True + Remove Vehicle attribute observer + Read vehicle param 'THR_MIN': 130.0 Write vehicle param 'THR_MIN' : 10 Read new value of param 'THR_MIN': 10.0 Reset vehicle attributes/parameters and exit >>> DISARMING MOTORS + CALLBACK: Mode changed to VehicleMode:STABILIZE Close vehicle object Completed diff --git a/docs/guide/mavlink_messages.rst b/docs/guide/mavlink_messages.rst index 9ee886657..67d3d0922 100644 --- a/docs/guide/mavlink_messages.rst +++ b/docs/guide/mavlink_messages.rst @@ -8,8 +8,7 @@ Some useful MAVLink messages sent by the autopilot are not (yet) directly availa through the :ref:`observable attributes ` in :py:class:`Vehicle `. This topic shows how you can intercept specific MAVLink messages by defining a listener callback function -using the :py:func:`Vehicle.on_message() ` -decorator. +using the :py:func:`Vehicle.on_message() ` decorator. .. tip:: @@ -27,7 +26,7 @@ The :py:func:`Vehicle.on_message() ` decorator set a particular function as the callback handler for a particular message type. You can create listeners for as many messages as you like, or even multiple listeners for the same message. -For example, code snippet below shows how to set a listener for the ``RANGEFINDER`` message: +For example, the code snippet below shows how to set a listener for the ``RANGEFINDER`` message: .. code:: python @@ -39,7 +38,9 @@ For example, code snippet below shows how to set a listener for the ``RANGEFINDE .. tip:: Every single listener can have the same name/prototpye as above ("``listener``") because - Python does not notice these decorated functions as having the same name in the same scope. + Python does not notice the decorated functions are in the same scope. + + Unfortunately this also means that you can't unregister a callback created using this method. The messages are `classes `_ from the `pymavlink `_ library. @@ -62,11 +63,25 @@ function might look like this: print 'voltage: %s' % message.voltage +Watching all messages +===================== + +You can register a callback for *all messages* by setting the message name as the wildcard string ('``*``'): + +.. code:: python + + #Create a message listener for all messages. + @vehicle.on_message('*') + def listener(self, name, message): + print 'message: %s' % message -Clearing the observer -===================== +Removing an observer +==================== -The observer is unset by calling :py:func:`Vehicle.remove_message_listener `. +Callbacks registered using the :py:func:`Vehicle.on_message() ` decorator *cannot be removed*. +This is generally not a problem, because in most cases you're interested in messages for the lifetime of a session. -The observer will also be removed when the thread exits. +If you do need to be able to remove messages you can instead add the callback using +:py:func:`Vehicle.add_message_listener `, and then remove it by calling +:py:func:`Vehicle.remove_message_listener `. diff --git a/docs/guide/migrating.rst b/docs/guide/migrating.rst index 452efa7f0..5c9a4415f 100644 --- a/docs/guide/migrating.rst +++ b/docs/guide/migrating.rst @@ -174,27 +174,28 @@ This code must be replaced with the DroneKit-Python 2.x :py:attr:`Vehicle.home_l :py:attr:`Vehicle.home_location `. -Debugging -========= - -DroneKit-Python 1.x scripts were run in the context of a MAVProxy. This made them difficult to debug because you had to -instrument your code in order to launch the debugger, and debug messages were interleaved with MAVProxy output. - -Debugging on DroneKit-Python 2.x is much easier. Apps are now just standalone scripts, and can be debugged -using standard Python methods (including the debugger/IDE of your choice). Observing attribute changes --------------------------- -The DroneKit-Python 1.x observer functions ``vehicle.add_attribute_observer`` and ``Vehicle.remove_attribute_observer`` -have been replaced by :py:func:`Vehicle.add_attribute_listener() ` -and :py:func:`remove_attribute_listener() `, respectively. +The DroneKit-Python 1.x observer function ``vehicle.add_attribute_observer`` has been replaced by +:py:func:`Vehicle.add_attribute_listener() ` or +:py:func:`Vehicle.on_attribute() ` in DKYP2.x, and ``Vehicle.remove_attribute_observer`` +has been repaced by :py:func:`remove_attribute_listener() `. + +The main difference is that the callback function now takes three arguments (the vehicle object, attribute name, attribute value) +rather than just the attribute name. This allows you to more easily write callbacks that support attribute-specific and +vehicle-specific handling and means that you can get the new value from the callback attribute rather than by re-querying +the vehicle. -The functions are used in a very similar way, the main difference being that the callback function now takes two arguments -(the vehicle and the attribute name) rather than just the attribute name. +The difference between :py:func:`Vehicle.add_attribute_listener() ` and +:py:func:`Vehicle.on_attribute() ` is that attribute listeners added using +:py:func:`Vehicle.on_attribute() ` cannot be removed (but ``on_attribute()`` does have +a more elegant syntax). See :ref:`vehicle_state_observe_attributes` for more information. + Intercepting MAVLink Messages ----------------------------- @@ -202,7 +203,27 @@ DroneKit-Python 1.x used ``Vehicle.set_mavlink_callback()`` and ``Vehicle.unset_ to set/unset a callback function that was invoked for every single mavlink message. In DKPY2 this has been replaced by the :py:func:`Vehicle.on_message() ` -decorator, which allows you to specify a callback function that will be invoked for a single message. The same -mechanism is used internally for message capture and to create ``Vehicle`` attributes. +decorator, which allows you to specify a callback function that will be invoked for a single message +(or all messages, by specifying the message name as the wildcard string '``*``'). + +.. tip:: + + :py:func:`Vehicle.on_message() ` is used in core DroneKit code for + message capture and to create ``Vehicle`` attributes. + + The API also adds :py:func:`Vehicle.add_message_listener() ` + and :py:func:`Vehicle.remove_message_listener() `. + These can be used instead of :py:func:`Vehicle.on_message() ` when you need to be + able to *remove* an added listener. See :ref:`mavlink_messages` for more information. + + +Debugging +========= + +DroneKit-Python 1.x scripts were run in the context of a MAVProxy. This made them difficult to debug because you had to +instrument your code in order to launch the debugger, and debug messages were interleaved with MAVProxy output. + +Debugging on DroneKit-Python 2.x is much easier. Apps are now just standalone scripts, and can be debugged +using standard Python methods (including the debugger/IDE of your choice). diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index a87e5a3fa..67053896a 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -139,31 +139,36 @@ You can observe any of the attributes (except for :py:attr:`Vehicle.home_locatio :py:attr:`Vehicle.parameters `) and will receive notification every time a value is received from the connected vehicle. This allows you to monitor changes to velocity and other vehicle state without the need for polling. -Observers are added using :py:func:`Vehicle.add_attribute_listener() `, -specifying the name of the attribute to observe and a callback function. -Observers are removed using :py:func:`remove_attribute_listener() `. +Observers are added using :py:func:`Vehicle.add_attribute_listener() ` or the +:py:func:`Vehicle.on_attribute() ` decorator method. The main difference between these methods +is that only attribute callbacks added with :py:func:`Vehicle.add_attribute_listener() ` +can be removed (see :py:func:`remove_attribute_listener() `). -The ``observer`` callback function is invoked with the ``self`` and ``attr_name`` arguments: +The ``observer`` callback function is invoked with the following arguments: -* The ``attr_name`` (attribute name) is needed if the same callback is used for watching several attributes. -* The ``self`` attribute is the associated :py:class:`Vehicle`. It is needed if you want to - implement vehicle-specific callback handling (by comparing it to a global vehicle handle). - -The code snippet below shows how to add (and remove) a callback function to observe location changes -(:py:attr:`Vehicle.location.global_frame `). +* ``self`` - the associated :py:class:`Vehicle`. This may be compared to a global vehicle handle + to implement vehicle-specific callback handling (if needed). +* ``attr_name`` - the attribute name. This can be used to infer which attribute has triggered + if the same callback is used for watching several attributes. +* ``msg`` - the attribute value (so you don't need to re-query the vehicle object). + +The code snippet below shows how to add (and remove) a callback function to observe changes +in :py:attr:`Vehicle.location.global_frame ` using +:py:func:`Vehicle.add_attribute_listener() `. The two second ``sleep()`` is required because otherwise the observer might be removed before the the callback is first run. -.. code:: python +.. code-block:: python + :emphasize-lines: 7 - #Callback to print the location in global and local frames - def location_callback(self, attr_name): - print "Location (Global): ", self.location.global_frame - print "Location (Local): ", self.location.local_frame + #Callback to print the location in global frames. 'value' is the updated value + def location_callback(self, attr_name, value): + print "Location (Global): ", value + - # Add a callback. The first parameter the name of the observed attribute (a string). - vehicle.add_attribute_listener('location', location_callback) + # Add a callback `location_callback` for the `global_frame` attribute. + vehicle.add_attribute_listener('global_frame', location_callback) # Wait 2s so callback can be notified before the observer is removed time.sleep(2) @@ -171,16 +176,22 @@ callback is first run. # Remove observer - specifying the attribute and previously registered callback function vehicle.remove_message_listener('location', location_callback) - -The callback is triggered every time a message is received from the vehicle (whether or not the observed attribute changes). + +Callbacks are triggered every time a message is received from the vehicle (whether or not the observed attribute changes). Callback code may therefore choose to cache the result and only report changes. -For example, the following code can be used in the callback to only print output when the value of -:py:attr:`Vehicle.rangefinder ` changes. -.. code:: python +The example below shows how you can declare an attribute callback using the +:py:func:`Vehicle.on_attribute() ` decorator function. This stores the result of the +previous callback and only prints the output when there is a signficant change in :py:attr:`Vehicle.rangefinder `. + + +.. code-block:: python + :emphasize-lines: 3,4 + last_rangefinder_distance=0 + @vehicle.on_attribute('rangefinder') def rangefinder_callback(self,attr_name): #attr_name not used here. global last_rangefinder_distance @@ -189,7 +200,26 @@ For example, the following code can be used in the callback to only print output last_rangefinder_distance = round(self.rangefinder.distance, 1) print " Rangefinder (metres): %s" % last_rangefinder_distance - vehicle.add_attribute_listener('rangefinder', rangefinder_callback) + +The examples above show how you can monitor a single attribute. You can pass the special name ('``*``') to specify a +callback that will be called for any/all attribute changes: + +.. code-block:: python + + # Demonstrate getting callback on any attribute change + def wildcard_callback(self, attr_name, value): + print " CALLBACK: (%s): %s" % (attr_name,value) + + print "\nAdd attribute calback detecting any attribute change" + vehicle.add_attribute_listener('*', wildcard_callback) + + + print " Wait 1s so callback invoked before observer removed" + time.sleep(1) + + print " Remove Vehicle attribute observer" + # Remove observer added with `add_attribute_listener()` + vehicle.remove_attribute_listener('*', wildcard_callback) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 6e62b3c3e..e63d51b88 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -274,40 +274,42 @@ def __init__(self): """ Provides callback based notification on attribute changes. - The argument list for observer is ``observer(object, attr_name)``. + The argument list for observer is ``observer(object, attr_name, attribute_value)``. """ def add_attribute_listener(self, attr_name, observer): """ - Add an attribute listener. + Add an attribute listener callback. - The ``observer`` callback function is called with the ``self`` and ``attr_name`` - arguments: + The callback function (``observer``) is invoked every time the associated attribute is updated + from the vehicle (the attribute value may not have *changed*). The callback can be removed + using :py:func:`remove_attribute_listener`. - * The ``attr_name`` (attribute name) can be used to infer which attribute has triggered + .. note:: + + The :py:func:`on_attribute` decorator performs the same operation as this method, but with + a more elegant syntax. Use ``add_attribute_listener`` by preference if you will need to remove + the observer. + + The callback arguments are: + + * ``self`` - the associated :py:class:`Vehicle`. This may be compared to a global vehicle handle + to implement vehicle-specific callback handling (if needed). + * ``attr_name`` - the attribute name. This can be used to infer which attribute has triggered if the same callback is used for watching several attributes. - * The ``self`` attribute is the associated :py:class:`Vehicle`. If needed, it can be compared - to a global vehicle handle to implement vehicle-specific callback handling. + * ``msg`` - the attribute value (so you don't need to re-query the vehicle object). - The example below shows how to get callbacks for location changes: + The example below shows how to get callbacks for (global) location changes: .. code:: python - #Callback to print the location in global and local frames - def location_callback(self, attr_name): - print "Location (Global): ", self.location.global_frame - print "Location (Local): ", self.location.local_frame + #Callback to print the location in global frame + def location_callback(self, attr_name, msg): + print "Location (Global): ", msg #Add observer for the vehicle's current location - vehicle.add_attribute_listener('location', location_callback) - - - .. note:: - - The callback function is invoked every time the associated attribute is updated - from the vehicle (the attribute value may not have *changed*). - The callback can be removed using :py:func:`remove_attribute_listener`. + vehicle.add_attribute_listener('global_frame', location_callback) - :param String attr_name: The attribute to watch. + :param String attr_name: The name of the attribute to watch (or '*' to watch all attributes). :param observer: The callback to invoke when a change in the attribute is detected. """ @@ -329,7 +331,7 @@ def remove_attribute_listener(self, attr_name, observer): vehicle.remove_attribute_listener('global_frame', location_callback) - :param String attr_name: The attribute name that is to have an observer removed. + :param String attr_name: The attribute name that is to have an observer removed (or '*' to remove an 'all attribute' observer). :param observer: The callback function to remove. """ @@ -341,11 +343,13 @@ def remove_attribute_listener(self, attr_name, observer): def notify_attribute_listeners(self, attr_name, value): """ - Internal function. Do not use. - - This method calls observers when the named attribute has changed. - - .. INTERNAL NOTE: (For subclass use only) + This method calls attribute observers when the named attribute has changed. + + It should be called in message listeners after updating an attribute with new information + from the vehicle. + + :param String attr_name: The name of the attribute that has been updated. + :param value: The current value of the attribute that has been updated. """ for fn in self.__observers.get(attr_name, []): fn(self, attr_name, value) @@ -356,21 +360,33 @@ def on_attribute(self, name): """ Decorator for attribute listeners. - This is used to create/define new attribute listenters. After using this method you can - register an observer for the attribute using :py:func:`add_attribute_listener`. + The decorated ``observer`` callback function is invoked every time the associated attribute is updated + from the vehicle (the attribute value may not have *changed*). - .. note:: + The callback arguments are: - The in-built attributes already have listeners (created using this method). The - method is public so that you can use it to add listeners to *new* attributes. + * ``self`` - the associated :py:class:`Vehicle`. This may be compared to a global vehicle handle + to implement vehicle-specific callback handling (if needed). + * ``attr_name`` - the attribute name. This can be used to infer which attribute has triggered + if the same callback is used for watching several attributes. + * ``msg`` - the attribute value (so you don't need to re-query the vehicle object). + + .. note:: - The example below shows how you can create a listener for the attitude attribute. + There is no way to remove an attribute listener added with this decorator. Use + :py:func:`add_attribute_listener` if you need to be able to remove + the :py:func:`attribute listener `. + + The code fragment below shows how you can create a listener for the attitude attribute. .. code:: python @vehicle.on_attribute('attitude') def attitude_listener(self, name, msg): - pass + print '%s attribute is: %s' % (name, msg) + + :param String attr_name: The name of the attribute to watch (or '*' to watch all attributes). + :param observer: The callback to invoke when a change in the attribute is detected. """ def decorator(fn): if isinstance(name, list): @@ -867,15 +883,21 @@ def listener(self, name, msg): def on_message(self, name): """ - Decorator for message listeners. + Decorator for message listener callback functions. + + .. tip:: - A decorated message listener is called with three arguments every time the + This is the most elegant way to define message listener callback functions. + Use :py:func:`add_message_listener` only if you need to be able to + :py:func:`remove the listener ` later. + + A decorated message listener function is called with three arguments every time the specified message is received: * ``self`` - the current vehicle. * ``name`` - the name of the message that was intercepted. - * ``message`` - the actual message, a `pymavlink `_ - `class `_. + * ``message`` - the actual message (a `pymavlink `_ + `class `_). For example, in the fragment below ``my_method`` will be called for every heartbeat message: @@ -885,7 +907,7 @@ def on_message(self, name): def my_method(self, name, msg): pass - :param String name: The name of the message to be intercepted by the decorated listener function. + :param String name: The name of the message to be intercepted by the decorated listener function (or '*' to get all messages). """ def decorator(fn): if isinstance(name, list): @@ -897,7 +919,33 @@ def decorator(fn): def add_message_listener(self, name, fn): """ - Adds a message listener. + Adds a message listener function that will be called every time the specified message is received. + + .. tip:: + + We recommend you use :py:func:`on_message` instead of this method as it has a more elegant syntax. + This method is only preferred if you need to be able to + :py:func:`remove the listener `. + + The callback function must have three arguments: + + * ``self`` - the current vehicle. + * ``name`` - the name of the message that was intercepted. + * ``message`` - the actual message (a `pymavlink `_ + `class `_). + + For example, in the fragment below ``my_method`` will be called for every heartbeat message: + + .. code:: python + + #Callback method for new messages + def my_method(self, name, msg): + pass + + vehicle.add_message_listener('HEARTBEAT',my_method) + + :param String name: The name of the message to be intercepted by the listener function (or '*' to get all messages). + :param fn: The listener function that will be called if a message is received. """ name = str(name) if name not in self._message_listeners: @@ -907,7 +955,11 @@ def add_message_listener(self, name, fn): def remove_message_listener(self, name, fn): """ - Removes a message listener (that was added using :py:func:`message_listener`) + Removes a message listener (that was previously added using :py:func:`add_message_listener`). + + :param String name: The name of the message for which the listener is to be removed (or '*' to remove an 'all messages' observer). + :param fn: The listener callback function to remove. + """ name = str(name) if name in self._message_listeners: diff --git a/examples/create_attribute/create_attribute.py b/examples/create_attribute/create_attribute.py index acd40da1b..9b138f12b 100644 --- a/examples/create_attribute/create_attribute.py +++ b/examples/create_attribute/create_attribute.py @@ -47,7 +47,7 @@ class RawIMU(object): :param ymag: Y Magnetic field (milli tesla) :param zmag: Z Magnetic field (milli tesla) """ - def __init__(self, time_boot_us, xacc, yacc, zacc, xygro, ygyro, zgyro, xmag, ymag, zmag): + def __init__(self, time_boot_us=None, xacc=None, yacc=None, zacc=None, xygro=None, ygyro=None, zgyro=None, xmag=None, ymag=None, zmag=None): """ RawIMU object constructor. """ @@ -70,8 +70,8 @@ def __str__(self): -#Create an Vehicle.raw_imu object and set all values to None. -vehicle.raw_imu=RawIMU(None,None,None,None,None,None,None,None,None,None) +#Create an Vehicle.raw_imu object with initial values set to None. +vehicle.raw_imu=RawIMU() @@ -96,8 +96,8 @@ def listener(self, name, message): self.raw_imu.ymag=message.ymag self.raw_imu.zmag=message.zmag - # Notify all observers of new message. - self.notify_attribute_listeners('raw_imu') + # Notify all observers of new message (with new value) + self.notify_attribute_listeners('raw_imu', self.raw_imu) """ @@ -105,8 +105,9 @@ def listener(self, name, message): """ #Callback to print the raw_imu -def raw_imu_callback(self,rawimu): - print self.raw_imu +def raw_imu_callback(self,rawimu,msg): + #msg is the attribute/value that changed + print msg #Add observer for the vehicle's current location diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index e3ac58a22..9c63a16da 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -105,13 +105,14 @@ # Add and remove and attribute callbacks (using mode as example) -def mode_callback(self, attr_name): +def mode_callback(self, attr_name, value): # `attr_name` is the observed attribute (used if callback is used for multiple attributes) - # `self` is the associated vehicle object (used if callback behaviouris different for multiple vehicles) - print " CALLBACK: Mode changed to", self.mode + # `attr_name` - the observed attribute (used if callback is used for multiple attributes) + # `value` is the updated attribute value. + print " CALLBACK: Mode changed to", value print "\nAdd attribute callback/observer on `vehicle` for `mode` attribute" -vehicle.add_attribute_listener('mode', mode_callback) +vehicle.add_attribute_listener('mode', mode_callback) print " Set mode=STABILIZE (currently: %s)" % vehicle.mode.name @@ -125,6 +126,57 @@ def mode_callback(self, attr_name): vehicle.remove_attribute_listener('mode', mode_callback) + +# Add mode attribute callback using decorator (callbacks added this way cannot be removed). +print "\nAdd attribute callback/observer `mode` attribute using decorator" +last_published_mode='' +@vehicle.on_attribute('mode') +def mode_decorated_callback(self, attr_name, value): + # `attr_name` - the observed attribute (used if callback is used for multiple attributes) + # `self` - the associated vehicle object (used if a callback is different for multiple vehicles) + # `value` is the updated attribute value. + global last_published_mode + # Only publish when mode changes + if value!=last_published_mode: + print " CALLBACK: Mode changed to", value + last_published_mode=value + + +print " Set mode=GUIDED (currently: %s)" % vehicle.mode.name +vehicle.mode = VehicleMode("GUIDED") + +print " Wait 2s so callback invoked before observer removed" +time.sleep(2) + +print "\n Attempt to remove observer added with `on_attribute` decorator (should fail)" +try: + vehicle.remove_attribute_listener('mode', mode_decorated_callback) +except: + print " Exception: Cannot add observer added using decorator" + + + +# Demonstrate getting callback on any attribute change +def wildcard_callback(self, attr_name, value): + # `attr_name` - attribute name (useful if callback is used for multiple attributes) + # `self` - associated vehicle object (used if callback behaviour is different for multiple vehicles) + # `value` - updated attribute value. + print " CALLBACK: (%s): %s" % (attr_name,value) + +print "\nAdd attribute calback detecting any attribute change" +vehicle.add_attribute_listener('*', wildcard_callback) + + +print " Wait 1s so callback invoked before observer removed" +time.sleep(1) + +print " Remove Vehicle attribute observer" +# Remove observer added with `add_attribute_listener()` +vehicle.remove_attribute_listener('*', wildcard_callback) + + + + # Get/Set Vehicle Parameters print "\nRead vehicle param 'THR_MIN': %s" % vehicle.parameters['THR_MIN'] print "Write vehicle param 'THR_MIN' : 10" From 32f14fdaacbb4e5ba01a26e3ff26a710df06420c Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 9 Nov 2015 16:02:06 +1100 Subject: [PATCH 153/475] Tidy example in response to #420 comment --- examples/create_attribute/create_attribute.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/create_attribute/create_attribute.py b/examples/create_attribute/create_attribute.py index 9b138f12b..69d4f966f 100644 --- a/examples/create_attribute/create_attribute.py +++ b/examples/create_attribute/create_attribute.py @@ -105,7 +105,7 @@ def listener(self, name, message): """ #Callback to print the raw_imu -def raw_imu_callback(self,rawimu,msg): +def raw_imu_callback(self,attr_name,msg): #msg is the attribute/value that changed print msg From f5e71145114b90485b4e8525b167972e79377194 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 9 Nov 2015 17:03:58 +1100 Subject: [PATCH 154/475] Add attributes docs for system_status, heading as per #305 --- docs/examples/vehicle_state.rst | 2 ++ docs/guide/migrating.rst | 11 +++++++++++ docs/guide/vehicle_state_and_parameters.rst | 9 ++++++--- examples/vehicle_state/vehicle_state.py | 2 ++ 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index 039b4e0b8..d92dc2522 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -67,6 +67,8 @@ On the command prompt you should see (something like): Rangefinder: Rangefinder: distance=None, voltage=None Rangefinder distance: None Rangefinder voltage: None + System status: 3 + Heading: 341 Mode: STABILIZE Armed: False Home Location: LocationGlobal:lat=-35.3632392883,lon=149.165237427,alt=222.0,is_relative=False diff --git a/docs/guide/migrating.rst b/docs/guide/migrating.rst index 5c9a4415f..f294357de 100644 --- a/docs/guide/migrating.rst +++ b/docs/guide/migrating.rst @@ -160,6 +160,8 @@ Instead, use normal Python methods for getting file system information: import os.path full_directory_path_of_current_script = os.path.dirname(os.path.abspath(__file__)) + +.. _migrating_dkpy2_0_heading: Home location ------------- @@ -219,6 +221,15 @@ decorator, which allows you to specify a callback function that will be invoked See :ref:`mavlink_messages` for more information. +New attributes +-------------- + +In addition to the :ref:`home_location `, a few more attributes have been added, +including: +:py:func:`Vehicle.system_status ` and +:py:func:`Vehicle.heading `. + + Debugging ========= diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index 67053896a..3805c13ce 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -31,6 +31,8 @@ Vehicle state information is exposed through vehicle *attributes*. DroneKit-Pyth :py:attr:`Vehicle.battery `, :py:attr:`Vehicle.rangefinder `, :py:attr:`Vehicle.home_location `, +:py:func:`Vehicle.system_status `, +:py:func:`Vehicle.heading `, :py:attr:`Vehicle.armed `, :py:attr:`Vehicle.mode `. @@ -51,8 +53,8 @@ from the other attributes, and is :ref:`discussed in its own section below Date: Mon, 9 Nov 2015 17:12:54 +1100 Subject: [PATCH 155/475] Addition file changes (this should have been part of last commit) --- dronekit/lib/__init__.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index e63d51b88..c090c4886 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1052,10 +1052,29 @@ def armed(self, value): @property def system_status(self): + """ + System status flag according to the MAVLink + `MAV_STATE `_ enum. + + States include: + + * ``MAV_STATE_UNINIT`` (0): Uninitialized system, state is unknown. + * ``MAV_STATE_BOOT`` (1): System is booting up. + * ``MAV_STATE_CALIBRATING`` (2): System is calibrating and not flight-ready. + * ``MAV_STATE_STANDBY`` (3): System is grounded and on standby. It can be launched any time. + * ``MAV_STATE_ACTIVE`` (4): System is active and might be already airborne. Motors are engaged. + * ``MAV_STATE_CRITICAL`` (5): System is in a non-normal flight mode. It can however still navigate. + * ``MAV_STATE_EMERGENCY`` (6): System is in a non-normal flight mode. It lost control over parts + or over the whole airframe. It is in mayday and going down. + * ``MAV_STATE_POWEROFF`` (7): System just initialized its power-down sequence, will shut down now. + """ return self._system_status @property def heading(self): + """ + Current heading in degrees (0..360, where North = 0). + """ return self._heading @property From bfb9001e72c83daff9f713c5ff4d3da517fa5347 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 9 Nov 2015 10:57:27 -0800 Subject: [PATCH 156/475] Updates AppVeyor configuration. --- appveyor.yml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index e49df033b..cddc95e06 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,7 +1,6 @@ environment: - global: - SITL_SPEEDUP: 10 - SITL_RATE: 200 + SITL_SPEEDUP: 10 + SITL_RATE: 200 cache: - "c:\\Users\\appveyor\\.pip-wheelhouse" @@ -31,10 +30,3 @@ build_script: clone_depth: 10 test: 'off' -branches: - only: - - master - - major - - minor - - patch - - /^v\d+\.\d+\.\d+$/ From 6a9125184d29f441b89af66ac7fee5e1a70d475e Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 6 Nov 2015 16:46:49 -0800 Subject: [PATCH 157/475] Supports cached home_location. --- dronekit/lib/__init__.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index c090c4886..21b3cade6 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -749,6 +749,7 @@ def listener(self, name, m): # Waypoints. + self._home_location = None self._wploader = mavwp.MAVWPLoader() self._wp_loaded = True self._wp_uploaded = None @@ -765,6 +766,10 @@ def listener(self, name, msg): @self.on_message(['WAYPOINT', 'MISSION_ITEM']) def listener(self, name, msg): if not self._wp_loaded: + if msg.seq == 0: + if not (msg.x == 0 and msg.y == 0 and msg.z == 0): + self._home_location = LocationGlobal(msg.x, msg.y, msg.z, is_relative=False) + if msg.seq > self._wploader.count(): # Unexpected waypoint pass @@ -1141,9 +1146,7 @@ def home_location(self): The attribute is not writeable or observable. """ - loc = self._wploader.wp(0) - if loc: - return LocationGlobal(loc.x, loc.y, loc.z, is_relative=False) + return copy.copy(self._home_location) @home_location.setter def home_location(self, pos): @@ -1154,6 +1157,14 @@ def home_location(self, pos): If the GPS values differ heavily from EKF values, setting this value will fail silently. """ + + if not isinstance(pos, LocationGlobal): + raise Exception('Excepting home_location to be set to a LocationGlobal.') + + # Set cached home location. + self._home_location = copy.copy(pos) + + # Send MAVLink update. self.send_mavlink(self.message_factory.command_long_encode( 0, 0, # target system, target component mavutil.mavlink.MAV_CMD_DO_SET_HOME, # command From 0592320036742a9c93b47a999fd6cb61888ed750 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 9 Nov 2015 18:51:07 +1100 Subject: [PATCH 158/475] Changes documentation in line with new home_location behaviour --- docs/examples/vehicle_state.rst | 9 ++++-- docs/guide/vehicle_state_and_parameters.rst | 27 ++++++++++++++---- dronekit/lib/__init__.py | 25 ++++++++++++----- examples/vehicle_state/vehicle_state.py | 31 ++++++++------------- 4 files changed, 58 insertions(+), 34 deletions(-) diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index d92dc2522..9ec84250d 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -71,10 +71,15 @@ On the command prompt you should see (something like): Heading: 341 Mode: STABILIZE Armed: False - Home Location: LocationGlobal:lat=-35.3632392883,lon=149.165237427,alt=222.0,is_relative=False + Waiting for home location ... + ... + Waiting for home location ... + + Home location: LocationGlobal:lat=-35.3632621765,lon=149.165237427,alt=583.989990234,is_relative=False Set new home location - New Home Location (altitude should be 222): LocationGlobal:lat=-35.3632354736,lon=149.165237427,alt=222.0,is_relative=False + New Home Location (from attribute - altitude should be 222): LocationGlobal:lat=-35.363261,lon=149.1652299,alt=222,is_relative=False + New Home Location (from vehicle - altitude should be 222): LocationGlobal:lat=-35.3632621765,lon=149.165237427,alt=222.0,is_relative=False Set Vehicle.mode=GUIDED (currently: STABILIZE) Waiting for mode change ... diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index 3805c13ce..9cd91579f 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -238,7 +238,8 @@ waypoints is set relative to this position. :py:attr:`Vehicle.home_location ` has the following behaviour: -* In order to *get* the current value you must first download :py:attr:`Vehicle.commands `, as shown: +* In order to *get* the current value (in a :py:class:`LocationGlobal ` object) you must first download + :py:attr:`Vehicle.commands `, as shown: .. code:: python @@ -247,9 +248,21 @@ waypoints is set relative to this position. cmds.wait_ready() print " Home Location: %s" % vehicle.home_location - The returned value is a :py:class:`LocationGlobal ` object - (or ``None`` before you download the commands). If the location has not been set, then - the returned value's attributes will all be set to zero. + The returned value is ``None`` before you download the commands or if the ``home_location`` has not yet been set by the autopilot. + For this reason our example code checks that the value exists (in a loop) before writing it. + + .. code:: python + + # Get Vehicle Home location - will be `None` until first set by autopilot + while not vehicle.home_location: + cmds = vehicle.commands + cmds.download() + cmds.wait_ready() + if not vehicle.home_location: + print " Waiting for home location ..." + + # We have a home location. + print "\n Home location: %s" % vehicle.home_location * The attribute can be *set* to a :py:class:`LocationGlobal ` object (the code fragment below sets it to the current location): @@ -260,9 +273,11 @@ waypoints is set relative to this position. There are some caveats: - * You must download the commands again to read the changed ``home_location``. - * The autopilot must first set the value (on startup) before it can be changed by DroneKit-Python code. + * You must be able to read a non-``None`` value before you can write it + (the autopilot has to set the value initially before it can be written or read). * The new location must be within 50 km of the EKF origin or setting the value will silently fail. + * The value is cached in the ``home_location``. If the variable can potentially change on the vehicle + you will need to re-download the ``Vehicle.commands`` in order to confirm the value. * The attribute is not observable. diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 21b3cade6..2ebc5e3c6 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1123,12 +1123,11 @@ def channel_readback(self): @property def home_location(self): """ - The current home location in a :py:class:`LocationGlobal`. + The current home location in a :py:class:`LocationGlobal`. - This value is initially set by the autopilot as the location of first GPS Lock. - The attribute has a value of ``None`` until :py:func:`Vehicle.commands` has been downloaded. - If the attribute is queried before the home location is set the returned `LocationGlobal` - will have zero values for its member attributes. + To get the attribute you must first download the :py:func:`Vehicle.commands`. + The attribute has a value of ``None`` until :py:func:`Vehicle.commands` has been downloaded + **and** the autopilot has set an initial home location (typically where the vehicle first gets GPS lock). .. code-block:: python @@ -1143,7 +1142,16 @@ def home_location(self): # Get the home location home = vehicle.home_location - The attribute is not writeable or observable. + The ``home_location`` is not observable. + + The attribute can be written (in the same way as any other attribute) after it has successfully + been populated from the vehicle. The value sent to the vehicle is cached in the attribute + (and can potentially get out of date if you don't re-download ``Vehicle.commands``): + + .. warning:: + + Setting the value will fail silently if the specified location is more than 50km from the EKF origin. + """ return copy.copy(self._home_location) @@ -1152,10 +1160,13 @@ def home_location(self): def home_location(self, pos): """ Sets the home location to that of a ``LocationGlobal`` object. + + The value cannot be set until it has successfully been read from the vehicle. After being + set the value is cached in the home_location attribute and does not have to be re-read. .. note:: - If the GPS values differ heavily from EKF values, setting this value will fail silently. + Setting the value will fail silently if the specified location is more than 50km from the EKF origin. """ if not isinstance(pos, LocationGlobal): diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 9791ac933..ba479b8a9 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -52,38 +52,31 @@ print " Armed: %s" % vehicle.armed # settable -# Get Vehicle Home location -# Note: home_location attributes will be 0.0 if the autopilot has not yet set the home location. -cmds = vehicle.commands -cmds.download() -cmds.wait_ready() -print " Home Location: %s" % vehicle.home_location - - -# Set vehicle home_location, mode, and armed attributes (the only settable attributes) -print "\nSet new home location" - -# Home location must first have been set by the autopilot before we can set it. -while vehicle.home_location.lat == 0.0: +# Get Vehicle Home location - will be `None` until first set by autopilot +while not vehicle.home_location: cmds = vehicle.commands cmds.download() cmds.wait_ready() - if vehicle.home_location.lat == 0.0: - print " Waiting for home location: %s" % vehicle.home_location - else: - print "\n Autopilot set home location: %s" % vehicle.home_location - + if not vehicle.home_location: + print " Waiting for home location ..." +# We have a home location, so print it! +print "\n Home location: %s" % vehicle.home_location + +# Set vehicle home_location, mode, and armed attributes (the only settable attributes) + +print "\nSet new home location" # Home location must be within 50km of EKF home location (or setting will fail silently) # In this case, just set value to current location with an easily recognisable altitude (222) my_location_alt=vehicle.location.global_frame my_location_alt.alt=222 vehicle.home_location=my_location_alt +print " New Home Location (from attribute - altitude should be 222): %s" % vehicle.home_location #Confirm it is written out (note that you must re-download commands) cmds = vehicle.commands cmds.download() cmds.wait_ready() -print " New Home Location (altitude should be 222): %s" % vehicle.home_location +print " New Home Location (from vehicle - altitude should be 222): %s" % vehicle.home_location print "\nSet Vehicle.mode=GUIDED (currently: %s)" % vehicle.mode.name From e845e850715b38597c9c696f6011c6cf7a1389f1 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 9 Nov 2015 14:13:44 -0800 Subject: [PATCH 159/475] 2.0.0rc9 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 98d2207fd..4172267f5 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.0.0rc8' +version = '2.0.0rc9' setup(name='dronekit', zip_safe=True, From 9597b83636217cf8bee410349fd1d7e3fba96e5a Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 9 Nov 2015 13:25:21 -0800 Subject: [PATCH 160/475] Updates Create Attribute example. --- examples/create_attribute/create_attribute.py | 98 ++----------------- examples/create_attribute/my_vehicle.py | 84 ++++++++++++++++ 2 files changed, 94 insertions(+), 88 deletions(-) create mode 100644 examples/create_attribute/my_vehicle.py diff --git a/examples/create_attribute/create_attribute.py b/examples/create_attribute/create_attribute.py index 69d4f966f..0a4ac305c 100644 --- a/examples/create_attribute/create_attribute.py +++ b/examples/create_attribute/create_attribute.py @@ -10,10 +10,10 @@ Full documentation is provided at http://python.dronekit.io/examples/create_attribute.html """ -from dronekit import connect -from dronekit.lib import VehicleMode +from dronekit import connect, Vehicle, VehicleMode from pymavlink import mavutil import time +from my_vehicle import MyVehicle #Set up option parsing to get connection string @@ -23,94 +23,17 @@ help="vehicle connection target. Default '127.0.0.1:14550'") args = parser.parse_args() - -# Connect to the Vehicle +# Connect to our custom vehicle_class MyVehicle print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, wait_ready=True) - - -class RawIMU(object): - """ - The RAW IMU readings for the usual 9DOF sensor setup. - This contains the true raw values without any scaling to allow data capture and system debugging. - - The message definition is here: https://pixhawk.ethz.ch/mavlink/#RAW_IMU - - :param time_boot_us: Timestamp (microseconds since system boot). #Note, not milliseconds as per spec - :param xacc: X acceleration (mg) - :param yacc: Y acceleration (mg) - :param zacc: Z acceleration (mg) - :param xgyro: Angular speed around X axis (millirad /sec) - :param ygyro: Angular speed around Y axis (millirad /sec) - :param zgyro: Angular speed around Z axis (millirad /sec) - :param xmag: X Magnetic field (milli tesla) - :param ymag: Y Magnetic field (milli tesla) - :param zmag: Z Magnetic field (milli tesla) - """ - def __init__(self, time_boot_us=None, xacc=None, yacc=None, zacc=None, xygro=None, ygyro=None, zgyro=None, xmag=None, ymag=None, zmag=None): - """ - RawIMU object constructor. - """ - self.time_boot_us = time_boot_us - self.xacc = xacc - self.yacc = yacc - self.zacc = zacc - self.xgyro = zgyro - self.ygyro = ygyro - self.zgyro = zgyro - self.xmag = xmag - self.ymag = ymag - self.zmag = zmag - - def __str__(self): - """ - String representation used to print the RawIMU object. - """ - return "RAW_IMU: time_boot_us={},xacc={},yacc={},zacc={},xgyro={},ygyro={},zgyro={},xmag={},ymag={},zmag={}".format(self.time_boot_us, self.xacc, self.yacc,self.zacc,self.xgyro,self.ygyro,self.zgyro,self.xmag,self.ymag,self.zmag) +vehicle = connect(args.connect, wait_ready=True, vehicle_class=MyVehicle) - +# Add observer for the custom attribute -#Create an Vehicle.raw_imu object with initial values set to None. -vehicle.raw_imu=RawIMU() - +def raw_imu_callback(self, attr_name, value): + # attr_name == 'raw_imu' + # value == vehicle.raw_imu + print value - -#Create a message listener using the decorator. -@vehicle.on_message('RAW_IMU') -def listener(self, name, message): - """ - The listener is called for messages that contain the string specified in the decorator, - passing the vehicle, message name, and the message. - - The listener writes the message to the (newly attached) ``vehicle.raw_imu`` object - and notifies observers. - """ - self.raw_imu.time_boot_us=message.time_usec - self.raw_imu.xacc=message.xacc - self.raw_imu.yacc=message.yacc - self.raw_imu.zacc=message.zacc - self.raw_imu.xgyro=message.xgyro - self.raw_imu.ygyro=message.ygyro - self.raw_imu.zgyro=message.zgyro - self.raw_imu.xmag=message.xmag - self.raw_imu.ymag=message.ymag - self.raw_imu.zmag=message.zmag - - # Notify all observers of new message (with new value) - self.notify_attribute_listeners('raw_imu', self.raw_imu) - - -""" -From this point vehicle.raw_imu can be used just like any other attribute. -""" - -#Callback to print the raw_imu -def raw_imu_callback(self,attr_name,msg): - #msg is the attribute/value that changed - print msg - - -#Add observer for the vehicle's current location vehicle.add_attribute_listener('raw_imu', raw_imu_callback) print 'Display RAW_IMU messages for 5 seconds and then exit.' @@ -118,7 +41,6 @@ def raw_imu_callback(self,attr_name,msg): #The message listener can be unset using ``vehicle.remove_message_listener`` - #Close vehicle object before exiting script print "Close vehicle object" -vehicle.close() \ No newline at end of file +vehicle.close() diff --git a/examples/create_attribute/my_vehicle.py b/examples/create_attribute/my_vehicle.py new file mode 100644 index 000000000..887c99189 --- /dev/null +++ b/examples/create_attribute/my_vehicle.py @@ -0,0 +1,84 @@ +""" +my_vehicle.py: + +Custom Vehicle subclass to add IMU data. +""" + +from dronekit import connect, Vehicle, VehicleMode +from pymavlink import mavutil +import time + +class RawIMU(object): + """ + The RAW IMU readings for the usual 9DOF sensor setup. + This contains the true raw values without any scaling to allow data capture and system debugging. + + The message definition is here: https://pixhawk.ethz.ch/mavlink/#RAW_IMU + + :param time_boot_us: Timestamp (microseconds since system boot). #Note, not milliseconds as per spec + :param xacc: X acceleration (mg) + :param yacc: Y acceleration (mg) + :param zacc: Z acceleration (mg) + :param xgyro: Angular speed around X axis (millirad /sec) + :param ygyro: Angular speed around Y axis (millirad /sec) + :param zgyro: Angular speed around Z axis (millirad /sec) + :param xmag: X Magnetic field (milli tesla) + :param ymag: Y Magnetic field (milli tesla) + :param zmag: Z Magnetic field (milli tesla) + """ + def __init__(self, time_boot_us=None, xacc=None, yacc=None, zacc=None, xygro=None, ygyro=None, zgyro=None, xmag=None, ymag=None, zmag=None): + """ + RawIMU object constructor. + """ + self.time_boot_us = time_boot_us + self.xacc = xacc + self.yacc = yacc + self.zacc = zacc + self.xgyro = zgyro + self.ygyro = ygyro + self.zgyro = zgyro + self.xmag = xmag + self.ymag = ymag + self.zmag = zmag + + def __str__(self): + """ + String representation used to print the RawIMU object. + """ + return "RAW_IMU: time_boot_us={},xacc={},yacc={},zacc={},xgyro={},ygyro={},zgyro={},xmag={},ymag={},zmag={}".format(self.time_boot_us, self.xacc, self.yacc,self.zacc,self.xgyro,self.ygyro,self.zgyro,self.xmag,self.ymag,self.zmag) + + +class MyVehicle(Vehicle): + def __init__(self, *args): + super(MyVehicle, self).__init__(*args) + + # Create an Vehicle.raw_imu object with initial values set to None. + self._raw_imu = RawIMU() + + # Create a message listener using the decorator. + @self.on_message('RAW_IMU') + def listener(self, name, message): + """ + The listener is called for messages that contain the string specified in the decorator, + passing the vehicle, message name, and the message. + + The listener writes the message to the (newly attached) ``vehicle.raw_imu`` object + and notifies observers. + """ + self._raw_imu.time_boot_us=message.time_usec + self._raw_imu.xacc=message.xacc + self._raw_imu.yacc=message.yacc + self._raw_imu.zacc=message.zacc + self._raw_imu.xgyro=message.xgyro + self._raw_imu.ygyro=message.ygyro + self._raw_imu.zgyro=message.zgyro + self._raw_imu.xmag=message.xmag + self._raw_imu.ymag=message.ymag + self._raw_imu.zmag=message.zmag + + # Notify all observers of new message (with new value) + self.notify_attribute_listeners('raw_imu', self._raw_imu) + + @property + def raw_imu(self): + return self._raw_imu From 5f3f223de71a0947065871623b2549cb8ebe6637 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 6 Nov 2015 17:13:23 -0800 Subject: [PATCH 161/475] Adds is_armable check. --- dronekit/lib/__init__.py | 7 ++++++ dronekit/test/sitl/test_goto.py | 32 ++++++++---------------- dronekit/test/sitl/test_localposition.py | 32 ++++++++---------------- examples/simple_goto/simple_goto.py | 7 ++---- 4 files changed, 31 insertions(+), 47 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 2ebc5e3c6..da129bcd2 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1055,6 +1055,13 @@ def armed(self, value): else: self._master.arducopter_disarm() + @property + def is_armable(self): + # check that mode is not INITIALSING + # check that we have a GPS fix + # check that EKF pre-arm is complete + return self.mode != 'INITIALISING' and self.gps_0.fix_type > 1 and self._ekf_predposhorizabs + @property def system_status(self): """ diff --git a/dronekit/test/sitl/test_goto.py b/dronekit/test/sitl/test_goto.py index 0439ecf05..fb3468a78 100644 --- a/dronekit/test/sitl/test_goto.py +++ b/dronekit/test/sitl/test_goto.py @@ -27,43 +27,33 @@ def arm_and_takeoff(aTargetAltitude): Arms vehicle and fly to aTargetAltitude. """ - # print "Basic pre-arm checks" # Don't let the user try to fly autopilot is booting - if vehicle.mode.name == "INITIALISING": - # print "Waiting for vehicle to initialise" - time.sleep(1) - while vehicle.gps_0.fix_type < 2: - # print "Waiting for GPS...:", vehicle.gps_0.fix_type + i = 60 + while not vehicle.is_armable and i > 0: time.sleep(1) - - # print "Arming motors" - # Copter should arm in GUIDED mode - vehicle.mode = VehicleMode("GUIDED") + i = i - 1 + assert_equals(vehicle.is_armable, True) + # Copter should arm in GUIDED mode + vehicle.mode = VehicleMode("GUIDED") i = 60 while vehicle.mode.name != 'GUIDED' and i > 0: # print " Waiting for guided %s seconds..." % (i,) time.sleep(1) i = i - 1 + assert_equals(vehicle.mode.name, 'GUIDED') - # EKF warmup. Await that EKF's predicted horizontal position (absolute) estimate is good - while not vehicle._ekf_predposhorizabs: - time.sleep(1) - + # Arm copter. vehicle.armed = True - i = 60 while not vehicle.armed and vehicle.mode.name == 'GUIDED' and i > 0: # print " Waiting for arming %s seconds..." % (i,) time.sleep(1) i = i - 1 + assert_equals(vehicle.armed, True) - # Failure will result in arming but immediately landing - assert vehicle.armed - assert_equals(vehicle.mode.name, 'GUIDED') - - # print "Taking off!" - vehicle.commands.takeoff(aTargetAltitude) # Take off to target altitude + # Take off to target altitude + vehicle.commands.takeoff(aTargetAltitude) # Wait until the vehicle reaches a safe height before # processing the goto (otherwise the command after diff --git a/dronekit/test/sitl/test_localposition.py b/dronekit/test/sitl/test_localposition.py index 844677484..ebf433f23 100644 --- a/dronekit/test/sitl/test_localposition.py +++ b/dronekit/test/sitl/test_localposition.py @@ -18,43 +18,33 @@ def arm_and_takeoff(aTargetAltitude): Arms vehicle and fly to aTargetAltitude. """ - # print "Basic pre-arm checks" # Don't let the user try to fly autopilot is booting - if vehicle.mode.name == "INITIALISING": - # print "Waiting for vehicle to initialise" - time.sleep(1) - while vehicle.gps_0.fix_type < 2: - # print "Waiting for GPS...:", vehicle.gps_0.fix_type + i = 60 + while not vehicle.is_armable and i > 0: time.sleep(1) - - # print "Arming motors" - # Copter should arm in GUIDED mode - vehicle.mode = VehicleMode("GUIDED") + i = i - 1 + assert_equals(vehicle.is_armable, True) + # Copter should arm in GUIDED mode + vehicle.mode = VehicleMode("GUIDED") i = 60 while vehicle.mode.name != 'GUIDED' and i > 0: # print " Waiting for guided %s seconds..." % (i,) time.sleep(1) i = i - 1 + assert_equals(vehicle.mode.name, 'GUIDED') - # EKF warmup. Await that EKF's predicted horizontal position (absolute) estimate is good - while not vehicle._ekf_predposhorizabs: - time.sleep(1) - + # Arm copter. vehicle.armed = True - i = 60 while not vehicle.armed and vehicle.mode.name == 'GUIDED' and i > 0: # print " Waiting for arming %s seconds..." % (i,) time.sleep(1) i = i - 1 + assert_equals(vehicle.armed, True) - # Failure will result in arming but immediately landing - assert vehicle.armed - assert_equals(vehicle.mode.name, 'GUIDED') - - # print "Taking off!" - vehicle.commands.takeoff(aTargetAltitude) # Take off to target altitude + # Take off to target altitude + vehicle.commands.takeoff(aTargetAltitude) # Wait until the vehicle reaches a safe height before # processing the goto (otherwise the command after diff --git a/examples/simple_goto/simple_goto.py b/examples/simple_goto/simple_goto.py index c69a73ee5..1bf910992 100644 --- a/examples/simple_goto/simple_goto.py +++ b/examples/simple_goto/simple_goto.py @@ -33,11 +33,8 @@ def arm_and_takeoff(aTargetAltitude): print "Basic pre-arm checks" # Don't let the user try to fly autopilot is booting - if vehicle.mode.name == "INITIALISING": - print "Waiting for vehicle to initialise" - time.sleep(1) - while vehicle.gps_0.fix_type < 2: - print "Waiting for GPS...:", vehicle.gps_0.fix_type + while not vehicle.is_armable: + print " Waiting for vehicle to initialise..." time.sleep(1) From c2c9240cc1097eba4485fdaaf8af53f7f3f7ff70 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 10 Nov 2015 13:05:52 +1100 Subject: [PATCH 162/475] Updates to docs for is_armable attribute. Update to two main examples. --- docs/examples/simple_goto.rst | 30 ++++++++++----- docs/examples/vehicle_state.rst | 1 + docs/guide/migrating.rst | 7 +++- docs/guide/taking_off.rst | 42 ++++++++++++++------- docs/guide/vehicle_state_and_parameters.rst | 2 + dronekit/lib/__init__.py | 6 +++ examples/simple_goto/simple_goto.py | 2 +- examples/vehicle_state/vehicle_state.py | 1 + 8 files changed, 65 insertions(+), 26 deletions(-) diff --git a/docs/examples/simple_goto.rst b/docs/examples/simple_goto.rst index 1b72ce8b3..496df27de 100644 --- a/docs/examples/simple_goto.rst +++ b/docs/examples/simple_goto.rst @@ -70,12 +70,19 @@ On the command prompt you should see (something like): >>> APM:Copter V3.4-dev (e0810c2e) >>> Frame: QUAD Basic pre-arm checks - Waiting for GPS...: None - ... - Waiting for GPS...: None + Waiting for vehicle to initialise... + Waiting for vehicle to initialise... + Waiting for vehicle to initialise... + Waiting for vehicle to initialise... + Waiting for vehicle to initialise... Arming motors Waiting for arming... + Waiting for arming... + Waiting for arming... >>> ARMING MOTORS + >>> GROUND START + Waiting for arming... + Waiting for arming... >>> Initialising APM... Taking off! Altitude: 0.0 @@ -93,14 +100,16 @@ On the command prompt you should see (something like): .. tip:: - If you get stuck in ``Waiting for arming...`` it is very likely that the vehicle did not pass all pre-arm checks. - On a real device you can view the controller LEDs to determine possible causes. On the Simulator console you - can disable the checks if needed: + The code waits on :py:func:`Vehicle.is_armable `, so you shouldn't get stuck in ``Waiting for arming...``. + If you do, then: + + * On a real device you can view the controller LEDs to determine possible causes. + * On the Simulator console you can disable the checks if needed: - .. code-block:: bash + .. code-block:: bash - STABILIZE>param load ../Tools/autotest/copter_params.parm - STABILIZE>param set ARMING_CHECK 0 + STABILIZE>param load ../Tools/autotest/copter_params.parm + STABILIZE>param set ARMING_CHECK 0 How does it work? @@ -111,7 +120,8 @@ The code has three distinct sections: arming and takeoff, flight to two location Takeoff ------- -To launch *Copter* you need to set the mode to ``GUIDED``, arm the vehicle, and then call +To launch *Copter* you need to first check that the vehicle :py:func:`Vehicle.is_armable `. +Then set the mode to ``GUIDED``, arm the vehicle, and call :py:func:`Vehicle.commands.takeoff() `. The takeoff code in this example is explained in the guide topic :ref:`taking-off`. diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index 9ec84250d..16d3c2750 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -67,6 +67,7 @@ On the command prompt you should see (something like): Rangefinder: Rangefinder: distance=None, voltage=None Rangefinder distance: None Rangefinder voltage: None + Is Armable?: True System status: 3 Heading: 341 Mode: STABILIZE diff --git a/docs/guide/migrating.rst b/docs/guide/migrating.rst index f294357de..6c8b1c60b 100644 --- a/docs/guide/migrating.rst +++ b/docs/guide/migrating.rst @@ -226,8 +226,11 @@ New attributes In addition to the :ref:`home_location `, a few more attributes have been added, including: -:py:func:`Vehicle.system_status ` and -:py:func:`Vehicle.heading `. +:py:func:`Vehicle.system_status `, +:py:func:`Vehicle.heading `, +:py:func:`Vehicle.mount_status `, +:py:func:`Vehicle.ekf_ok `, +:py:func:`Vehicle.is_armable `. Debugging diff --git a/docs/guide/taking_off.rst b/docs/guide/taking_off.rst index 5f58072f3..242fca390 100644 --- a/docs/guide/taking_off.rst +++ b/docs/guide/taking_off.rst @@ -19,6 +19,9 @@ and then call :py:func:`Vehicle.commands.takeoff() `_ waypoint in your mission (you can run a mission by switching to ``AUTO`` mode after you're in the air). + + By contrast, Plane apps take off using the ``MAV_CMD_NAV_TAKEOFF`` command in a mission. Plane should first arm and then change to + ``AUTO`` mode to start the mission. The code below shows a function to arm a Copter, take off, and fly to a specified altitude. This is taken from :ref:`example_simple_goto`. @@ -33,12 +36,9 @@ The code below shows a function to arm a Copter, take off, and fly to a specifie """ print "Basic pre-arm checks" - # Don't let the user try to fly autopilot is booting - if vehicle.mode.name == "INITIALISING": - print "Waiting for vehicle to initialise" - time.sleep(1) - while vehicle.gps_0.fix_type < 2: - print "Waiting for GPS...:", vehicle.gps_0.fix_type + # Don't let the user try to arm until autopilot is ready + while not vehicle.is_armable: + print " Waiting for vehicle to initialise..." time.sleep(1) print "Arming motors" @@ -72,16 +72,32 @@ The function first performs some pre-arm checks. until the vehicle has passed a series of pre-arm checks to ensure that it is safe to fly. DroneKit-Python can't check every possible symptom that might prevent arming, but we can confirm that the -vehicle has booted and has a GPS lock: +vehicle has booted, EKF is ready, and it has a GPS lock. These checks are encapsulated in the +:py:func:`Vehicle.is_armable ` attribute: .. code-block:: python - if v.mode.name == "INITIALISING": - print "Waiting for vehicle to initialise" - time.sleep(1) - while vehicle.gps_0.fix_type < 2: - print "Waiting for GPS...:", vehicle.gps_0.fix_type - time.sleep(1) + print "Basic pre-arm checks" + # Don't let the user try to arm until autopilot is ready + while not vehicle.is_armable: + print " Waiting for vehicle to initialise..." + time.sleep(1) + +.. note:: + + If you need more status information you can perform the following sorts of checks: + + .. code-block:: python + + if v.mode.name == "INITIALISING": + print "Waiting for vehicle to initialise" + time.sleep(1) + while vehicle.gps_0.fix_type < 2: + print "Waiting for GPS...:", vehicle.gps_0.fix_type + time.sleep(1) + + You should always do a final check on :py:func:`Vehicle.is_armable `! + Once the vehicle is ready we set the mode to ``GUIDED`` and arm it. We then wait until arming is confirmed before sending the :py:func:`takeoff ` command. diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index 9cd91579f..61f478a79 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -33,6 +33,7 @@ Vehicle state information is exposed through vehicle *attributes*. DroneKit-Pyth :py:attr:`Vehicle.home_location `, :py:func:`Vehicle.system_status `, :py:func:`Vehicle.heading `, +:py:func:`Vehicle.is_armable `, :py:attr:`Vehicle.armed `, :py:attr:`Vehicle.mode `. @@ -72,6 +73,7 @@ regularly updated from MAVLink messages sent by the vehicle). print "Rangefinder distance: %s" % vehicle.rangefinder.distance print "Rangefinder voltage: %s" % vehicle.rangefinder.voltage print "Heading: %s" % vehicle.heading + print "Is Armable?: %s" % vehicle.is_armable print "System status: %s" % vehicle.system_status print "Mode: %s" % vehicle.mode.name # settable print "Armed: %s" % vehicle.armed # settable diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index da129bcd2..c9a7e6c38 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1057,6 +1057,12 @@ def armed(self, value): @property def is_armable(self): + """ + Returns ``True`` if the vehicle is ready to arm, false otherwise. + + This attribute wraps a number of pre-arm checks, ensuring that the vehicle has booted, + has a good GPS fix, and that the EKF pre-arm is complete. + """ # check that mode is not INITIALSING # check that we have a GPS fix # check that EKF pre-arm is complete diff --git a/examples/simple_goto/simple_goto.py b/examples/simple_goto/simple_goto.py index 1bf910992..a0d5c8985 100644 --- a/examples/simple_goto/simple_goto.py +++ b/examples/simple_goto/simple_goto.py @@ -32,7 +32,7 @@ def arm_and_takeoff(aTargetAltitude): """ print "Basic pre-arm checks" - # Don't let the user try to fly autopilot is booting + # Don't let the user try to arm until autopilot is ready while not vehicle.is_armable: print " Waiting for vehicle to initialise..." time.sleep(1) diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index ba479b8a9..e90fbb71e 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -47,6 +47,7 @@ print " Rangefinder distance: %s" % vehicle.rangefinder.distance print " Rangefinder voltage: %s" % vehicle.rangefinder.voltage print " Heading: %s" % vehicle.heading +print " Is Armable?: %s" % vehicle.is_armable print " System status: %s" % vehicle.system_status print " Mode: %s" % vehicle.mode.name # settable print " Armed: %s" % vehicle.armed # settable From 9b9a51f193fdc68b4f0f2fbbc420665600c026f4 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 10 Nov 2015 21:07:51 +1100 Subject: [PATCH 163/475] Fix up documentation to go with new create_attribute example. Remove unnecessary imports from examples --- docs/examples/create_attribute.rst | 138 ++++++++++++------ examples/create_attribute/create_attribute.py | 6 +- examples/create_attribute/my_vehicle.py | 5 +- 3 files changed, 99 insertions(+), 50 deletions(-) diff --git a/docs/examples/create_attribute.rst b/docs/examples/create_attribute.rst index e2c37d8a4..d6e75eae3 100644 --- a/docs/examples/create_attribute.rst +++ b/docs/examples/create_attribute.rst @@ -4,10 +4,13 @@ Example: Create Attribute in App ================================ -This example shows how you can create attributes for MAVLink messages within your DroneKit-Python script and -use them in *in the same way* as the built-in :py:class:`Vehicle ` attributes. +This example shows how you can subclass :py:class:`Vehicle ` in order to support +new attributes for MAVLink messages within your DroneKit-Python script. The new class is defined in a +separate file (making re-use easy) and is very similar to the code used to implement the in-built attributes. +The new attributes are used *in the same way* as the built-in +:py:class:`Vehicle ` attributes. -It uses the :py:func:`Vehicle.on_message() ` decorator +The new class uses the :py:func:`Vehicle.on_message() ` decorator to set a function that is called to process a specific message, copy its values into an attribute, and notify observers. An observer is then set on the new attribute using :py:func:`Vehicle.add_attribute_listener() `. @@ -15,7 +18,7 @@ observers. An observer is then set on the new attribute using Additional information is provided in the guide topic :ref:`mavlink_messages`. .. tip:: - + This approach is useful when you urgently need to access messages that are not yet supported as :py:class:`Vehicle ` attributes. @@ -86,9 +89,20 @@ On the command prompt you should see (something like): How does it work? ================= -The example first defines a class for the attribute. This has members for each of the values in the message -(in this case `RAW_IMU `_). It provides an initialiser and a string -representation for printing the object. +Subclassing Vehicle +------------------- + +The example file **my_vehicle.py** defines a class for the new attribute (``RawIMU``) and a new vehicle subclass (``MyVehicle``). + +.. note:: + + The example uses the same documentation markup used by the native code, which can be generated into a document set using + Sphinx/autodoc. + + +``RawIMU`` has members for each of the values in the message +(in this case `RAW_IMU `_). It provides an initialiser that sets all the values to +``None`` and a string representation for printing the object. .. code:: python @@ -132,65 +146,99 @@ representation for printing the object. """ return "RAW_IMU: time_boot_us={},xacc={},yacc={},zacc={},xgyro={},ygyro={},zgyro={},xmag={},ymag={},zmag={}".format(self.time_boot_us, self.xacc, self.yacc,self.zacc,self.xgyro,self.ygyro,self.zgyro,self.xmag,self.ymag,self.zmag) -The script should then create an instance of the class and add it as an attribute to the vehicle object retrieved from the connection. -All values in the new attribute should be set to ``None`` so that it is obvious to users when no messages have been received. -.. code:: python - - # Connect to the Vehicle passed in as args.connect - vehicle = connect(args.connect, wait_ready=True) +``MyVehicle`` is a superclass of ``Vehicle`` (and hence inherits all its attributes). +This first creates a private instance of ``RawIMU``. - #Create an Vehicle.raw_imu object with values set to `None`. - vehicle.raw_imu=RawIMU() - We create a listener using the :py:func:`Vehicle.on_message() ` -decorator as shown below. The listener is called for messages that contain the string "RAW_IMU", +decorator. The listener is called for messages that contain the string "RAW_IMU", with arguments for the vehicle, message name, and the message. It copies the message information into the attribute and then notifies all observers. -.. code:: python - - #Create a message listener using the decorator. - @vehicle.on_message('RAW_IMU') - def listener(self, name, message): - #Copy the message contents into the raw_imu attribute - self.raw_imu.time_boot_us=message.time_usec - self.raw_imu.xacc=message.xacc - self.raw_imu.yacc=message.yacc - self.raw_imu.zacc=message.zacc - self.raw_imu.xgyro=message.xgyro - self.raw_imu.ygyro=message.ygyro - self.raw_imu.zgyro=message.zgyro - self.raw_imu.xmag=message.xmag - self.raw_imu.ymag=message.ymag - self.raw_imu.zmag=message.zmag - - # Notify all observers of new message with new value - self.notify_attribute_listeners('raw_imu', self.raw_imu) +.. code-block:: python + :emphasize-lines: 6, 9-10, 30 + + class MyVehicle(Vehicle): + def __init__(self, *args): + super(MyVehicle, self).__init__(*args) + + # Create an Vehicle.raw_imu object with initial values set to None. + self._raw_imu = RawIMU() + + # Create a message listener using the decorator. + @self.on_message('RAW_IMU') + def listener(self, name, message): + """ + The listener is called for messages that contain the string specified in the decorator, + passing the vehicle, message name, and the message. + + The listener writes the message to the (newly attached) ``vehicle.raw_imu`` object + and notifies observers. + """ + self._raw_imu.time_boot_us=message.time_usec + self._raw_imu.xacc=message.xacc + self._raw_imu.yacc=message.yacc + self._raw_imu.zacc=message.zacc + self._raw_imu.xgyro=message.xgyro + self._raw_imu.ygyro=message.ygyro + self._raw_imu.zgyro=message.zgyro + self._raw_imu.xmag=message.xmag + self._raw_imu.ymag=message.ymag + self._raw_imu.zmag=message.zmag + + # Notify all observers of new message (with new value) + self.notify_attribute_listeners('raw_imu', self._raw_imu) + + @property + def raw_imu(self): + return self._raw_imu + +At the end of the class we create the public properly ``raw_imu`` which client code may read and observe. .. note:: The decorator pattern means that you can have multiple listeners for a particular message or for different messages and they can all have the same function name/prototype (in this case ``listener(self, name, message``). - -From this point the ``Vehicle.raw_imu`` attribute can be treated the same as any other (inbuilt) attribute. -You can query the attribute to get any of its members, and even add an observer as shown: + +Using the Vehicle subclass +-------------------------- + +The **create_attribute.py** file first imports the ``MyVehicle`` class. + + +.. code-block:: python + :emphasize-lines: 2 + + from dronekit import connect, Vehicle + from my_vehicle import MyVehicle #Our custom vehicle class + import time +We then call ``connect()``, specifying this new class in the ``vehicle_class`` argument. + +.. code-block:: python + + # Connect to our custom vehicle_class `MyVehicle` at address `args.connect` + vehicle = connect(args.connect, wait_ready=True, vehicle_class=MyVehicle) + +``connect()`` returns a ``MyVehicle`` class which can be used in *exactly the same way* as ``Vehicle`` but with an +additional attribute ``raw_imu``. You can query the attribute to get any of its members, and even add an observer as shown: + .. code:: python - #Callback to print the raw_imu - def raw_imu_callback(self, attr_name, msg): - #msg is the value/attribute that was updated. - print msg + # Add observer for the custom attribute + def raw_imu_callback(self, attr_name, value): + # attr_name == 'raw_imu' + # value == vehicle.raw_imu + print value - #Add observer for the vehicle's current location vehicle.add_attribute_listener('raw_imu', raw_imu_callback) + Known issues ============ @@ -205,3 +253,5 @@ The full source code at documentation build-time is listed below (`current versi .. literalinclude:: ../../examples/create_attribute/create_attribute.py :language: python +.. literalinclude:: ../../examples/create_attribute/my_vehicle.py + :language: python \ No newline at end of file diff --git a/examples/create_attribute/create_attribute.py b/examples/create_attribute/create_attribute.py index 0a4ac305c..8b7e516c1 100644 --- a/examples/create_attribute/create_attribute.py +++ b/examples/create_attribute/create_attribute.py @@ -10,10 +10,10 @@ Full documentation is provided at http://python.dronekit.io/examples/create_attribute.html """ -from dronekit import connect, Vehicle, VehicleMode -from pymavlink import mavutil +from dronekit import connect, Vehicle +from my_vehicle import MyVehicle #Our custom vehicle class import time -from my_vehicle import MyVehicle + #Set up option parsing to get connection string diff --git a/examples/create_attribute/my_vehicle.py b/examples/create_attribute/my_vehicle.py index 887c99189..4570d1cdf 100644 --- a/examples/create_attribute/my_vehicle.py +++ b/examples/create_attribute/my_vehicle.py @@ -4,9 +4,8 @@ Custom Vehicle subclass to add IMU data. """ -from dronekit import connect, Vehicle, VehicleMode -from pymavlink import mavutil -import time +from dronekit import Vehicle + class RawIMU(object): """ From 3dca3ff86a945f77909b6b2461633152e7bbb31a Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 9 Nov 2015 16:32:32 -0800 Subject: [PATCH 164/475] Implements SystemStatus property. --- dronekit/__init__.py | 1 + dronekit/lib/__init__.py | 55 ++++++++++++++++++++++++-------- dronekit/test/sitl/test_state.py | 14 ++++++++ 3 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 dronekit/test/sitl/test_state.py diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 14710f283..0cb6de4cb 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -22,6 +22,7 @@ Command = dronekit.lib.Command CommandSequence = dronekit.lib.CommandSequence VehicleMode = dronekit.lib.VehicleMode +SystemStatus = dronekit.lib.SystemStatus LocationGlobal = dronekit.lib.LocationGlobal LocationLocal = dronekit.lib.LocationLocal CloudClient = dronekit.lib.CloudClient diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index c9a7e6c38..df0c81327 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -266,6 +266,26 @@ def __eq__(self, other): def __ne__(self, other): return self.name != other +class SystemStatus(object): + """ + This object is used to get and set the current "system status". + + .. py:attribute:: state + + The system state, as a ``string``. + """ + def __init__(self, state): + self.state = state + + def __str__(self): + return "SystemStatus:%s" % self.state + + def __eq__(self, other): + return self.state == other + + def __ne__(self, other): + return self.state != other + class HasObservers(object): def __init__(self): # A mapping from attr_name to a list of observers @@ -744,8 +764,9 @@ def listener(self, name, m): self._armed = (m.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED) != 0 self.notify_attribute_listeners('armed', self.armed) self._flightmode = {v: k for k, v in self._master.mode_mapping().items()}[m.custom_mode] - self._system_status = m.system_status self.notify_attribute_listeners('mode', self.mode) + self._system_status = m.system_status + self.notify_attribute_listeners('system_status', self.system_status) # Waypoints. @@ -1071,22 +1092,28 @@ def is_armable(self): @property def system_status(self): """ - System status flag according to the MAVLink - `MAV_STATE `_ enum. - - States include: + System status. Is a ``SystemStatus`` object with a ``state`` property of: - * ``MAV_STATE_UNINIT`` (0): Uninitialized system, state is unknown. - * ``MAV_STATE_BOOT`` (1): System is booting up. - * ``MAV_STATE_CALIBRATING`` (2): System is calibrating and not flight-ready. - * ``MAV_STATE_STANDBY`` (3): System is grounded and on standby. It can be launched any time. - * ``MAV_STATE_ACTIVE`` (4): System is active and might be already airborne. Motors are engaged. - * ``MAV_STATE_CRITICAL`` (5): System is in a non-normal flight mode. It can however still navigate. - * ``MAV_STATE_EMERGENCY`` (6): System is in a non-normal flight mode. It lost control over parts + * ``UNINIT``: Uninitialized system, state is unknown. + * ``BOOT``: System is booting up. + * ``CALIBRATING``: System is calibrating and not flight-ready. + * ``STANDBY``: System is grounded and on standby. It can be launched any time. + * ``ACTIVE``: System is active and might be already airborne. Motors are engaged. + * ``CRITICAL``: System is in a non-normal flight mode. It can however still navigate. + * ``EMERGENCY``: System is in a non-normal flight mode. It lost control over parts or over the whole airframe. It is in mayday and going down. - * ``MAV_STATE_POWEROFF`` (7): System just initialized its power-down sequence, will shut down now. + * ``POWEROFF``: System just initialized its power-down sequence, will shut down now. """ - return self._system_status + return { + 0: SystemStatus('UNINIT'), + 1: SystemStatus('BOOT'), + 2: SystemStatus('CALIBRATING'), + 3: SystemStatus('STANDBY'), + 4: SystemStatus('ACTIVE'), + 5: SystemStatus('CRITICAL'), + 6: SystemStatus('EMERGENCY'), + 7: SystemStatus('POWEROFF'), + }.get(self._system_status, None) @property def heading(self): diff --git a/dronekit/test/sitl/test_state.py b/dronekit/test/sitl/test_state.py new file mode 100644 index 000000000..e14f8ea16 --- /dev/null +++ b/dronekit/test/sitl/test_state.py @@ -0,0 +1,14 @@ +import time +import sys +import os +import socket +from dronekit import connect, VehicleMode, SystemStatus +from dronekit.test import with_sitl +from nose.tools import assert_equals + +@with_sitl +def test_state(connpath): + vehicle = connect(connpath, wait_ready=['system_status']) + + assert_equals(type(vehicle.system_status), SystemStatus) + assert_equals(type(vehicle.system_status.state), str) From 7c4cccd65bb7bdedcc4a0968f551c00662ecd234 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 10 Nov 2015 21:42:55 +1100 Subject: [PATCH 165/475] Update example to print vehicle.system_status.state --- docs/examples/vehicle_state.rst | 2 +- docs/guide/vehicle_state_and_parameters.rst | 2 +- examples/vehicle_state/vehicle_state.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index 16d3c2750..20afac94e 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -68,7 +68,7 @@ On the command prompt you should see (something like): Rangefinder distance: None Rangefinder voltage: None Is Armable?: True - System status: 3 + System status: STANDBY Heading: 341 Mode: STABILIZE Armed: False diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index 61f478a79..8e9bad3e8 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -74,7 +74,7 @@ regularly updated from MAVLink messages sent by the vehicle). print "Rangefinder voltage: %s" % vehicle.rangefinder.voltage print "Heading: %s" % vehicle.heading print "Is Armable?: %s" % vehicle.is_armable - print "System status: %s" % vehicle.system_status + print "System status: %s" % vehicle.system_status.state print "Mode: %s" % vehicle.mode.name # settable print "Armed: %s" % vehicle.armed # settable diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index e90fbb71e..58329df50 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -48,7 +48,7 @@ print " Rangefinder voltage: %s" % vehicle.rangefinder.voltage print " Heading: %s" % vehicle.heading print " Is Armable?: %s" % vehicle.is_armable -print " System status: %s" % vehicle.system_status +print " System status: %s" % vehicle.system_status.state print " Mode: %s" % vehicle.mode.name # settable print " Armed: %s" % vehicle.armed # settable From e2a928cb2a0ab135f6439e623318a84d9f7de233 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 9 Nov 2015 15:05:29 -0800 Subject: [PATCH 166/475] Adds test for #227. --- dronekit/test/sitl/test_waypoints.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/dronekit/test/sitl/test_waypoints.py b/dronekit/test/sitl/test_waypoints.py index eae9eff75..27abf327f 100644 --- a/dronekit/test/sitl/test_waypoints.py +++ b/dronekit/test/sitl/test_waypoints.py @@ -1,6 +1,7 @@ import time import math from dronekit import connect, VehicleMode, LocationGlobal, Command +from pymavlink import mavutil from dronekit.test import with_sitl from nose.tools import assert_not_equals, assert_equals @@ -112,3 +113,25 @@ def test_parameter(connpath): assert_equals(home.alt, vehicle.home_location.alt) vehicle.close() + +@with_sitl +def test_227(connpath): + """ + Tests race condition when downloading items + """ + + vehicle = connect(connpath, wait_ready=True) + + def assert_commands(count): + vehicle.commands.download() + vehicle.commands.wait_ready() + assert_equals(len(vehicle.commands), count) + + assert_commands(0) + + vehicle.commands.add(Command( 0, 0, 0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, + mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, + 0, 0, 0, 0, 10, 10, 10)) + vehicle.flush() # Send commands + + assert_commands(1) From de940b34c5368cef5e3c07db34875208c97187c2 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 10 Nov 2015 10:13:47 +1100 Subject: [PATCH 167/475] Fix typo in note about setting yaw --- docs/guide/copter/guided_mode.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/copter/guided_mode.rst b/docs/guide/copter/guided_mode.rst index 2fa224162..a467a27be 100644 --- a/docs/guide/copter/guided_mode.rst +++ b/docs/guide/copter/guided_mode.rst @@ -253,7 +253,7 @@ The command allows you to specify that whether the heading is an absolute angle * The yaw will return to the default (facing direction of travel) after you set the mode or change the command used for controlling movement. * `At time of writing `_ there is no *safe way* to return to the default yaw "face direction of travel" behaviour. - * After taking off, yaw commands are ignored until the first "movement" command has been received. If you need to + * After taking off, yaw commands are ignored until the first "movement" command has been received. If you need to yaw immediately following takeoff then send a command to "move" to your current position. * :ref:`guided_mode_copter_set_roi` may work to get yaw to track a particular point (depending on the gimbal setup). From 7cf5277dcfe47e01037ec0cbf0f7a5e5feda1f46 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 10 Nov 2015 10:28:54 +1100 Subject: [PATCH 168/475] Fixes connect docs as per #395. Makes the docs display --- dronekit/lib/__init__.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index df0c81327..882dd4db9 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1,3 +1,4 @@ +# DroneAPI module """ This is the API Reference for the DroneKit-Python API. @@ -38,11 +39,14 @@ :param String ip: Connection string for target address - e.g. 127.0.0.1:14550. :param Bool wait_ready: Wait until all :py:func:`Vehicle.parameters` have downloaded before the method returns (default is false) - :param status_printer: NA - :param Vehicle vehicle_class: NA - :param int rate: NA + :param status_printer: Method of signature ``def status_printer(txt)`` that prints STATUS_TEXT messages from the Vehicle and other diagnostic information. + By default the status information is printed to the command prompt in which the script is running. + :param Vehicle vehicle_class: The class that will be instantiated by the ``connect()`` method. + This can be any sub-class of ``Vehicle`` (and defaults to ``Vehicle``). + :param int rate: Data sream refresh rate. The default is 4Hz (4 updates per second). :param int baud: The baud rate for the connection. The default is 115200. - + + :returns: A connected :py:class:`Vehicle` object. ---- @@ -54,8 +58,6 @@ """ -# DroneAPI module - import threading, time, math, copy import CloudClient from pymavlink.dialects.v10 import ardupilotmega From 2ea5e4713f1ebed9549b27c01ba7c4e05b954909 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 10 Nov 2015 11:34:10 +1100 Subject: [PATCH 169/475] Document current parameter download strategy as per #352 --- docs/guide/vehicle_state_and_parameters.rst | 31 +++++++++++---------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index 8e9bad3e8..f4e81e658 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -300,26 +300,29 @@ waypoints is set relative to this position. Parameters ========== -Vehicle parameters provide the information used to configure the autopilot for the vehicle-specific hardware/capabilities. -These can be read and set using the :py:attr:`Vehicle.parameters ` +Vehicle parameters provide the information used to configure the autopilot for the vehicle-specific hardware/capabilities. +The available parameters for each platform are documented in the ardupilot wiki here: +`Copter Parameters `_, +`Plane Parameters `_, +`Rover Parameters `_ +(the lists are automatically generated from the latest ArduPilot source code, and may contain or omit parameters +in your vehicle). + +DroneKit downloads all parameters when you first connect to the UAV (forcing parameter reads to wait +until the download completes), and subsequently keeps the values updated by monitoring vehicle messages +for changes to individual parameters. This process ensures that it is always safe to read supported parameters, +and that their values will match the information on the vehicle. + +Parameters can be read and set using the :py:attr:`Vehicle.parameters ` attribute (a :py:class:`Parameters ` object). -.. tip:: - - `Copter Parameters `_, - `Plane Parameters `_, - and `Rover Parameters `_ list all the supported parameters for each platform. - The lists are automatically generated from the latest ArduPilot source code, and may contain parameters - that are not yet in the stable released versions of the code. - - Getting parameters ------------------ -The parameters are read using the parameter name as a key. Reads will generally succeed unless you attempt to read an unsupported parameter -(which results in a Key error exception). - +The parameters are read using the parameter name as a key. Reads will always succeed unless you attempt to access an unsupported parameter +(which will result in a ``KeyError`` exception). + The code example below shows how to set Minimum Throttle (THR_MIN) setting. On Copter and Rover (not Plane), this is the minimum PWM setting for the throttle at which the motors will keep spinning. From 3df7a99bcdf50b57508827d7856a0535d6c205f1 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 10 Nov 2015 11:52:52 +1100 Subject: [PATCH 170/475] Add ekf_ok attribute docs --- docs/examples/vehicle_state.rst | 1 + docs/guide/vehicle_state_and_parameters.rst | 2 ++ dronekit/lib/__init__.py | 3 +++ examples/vehicle_state/vehicle_state.py | 1 + 4 files changed, 7 insertions(+) diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index 20afac94e..3e0d4b136 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -64,6 +64,7 @@ On the command prompt you should see (something like): Airspeed: 0.0 Mount status: [None, None, None] Battery: Battery:voltage=12.587,current=0.0,level=95 + EKF OK?: True Rangefinder: Rangefinder: distance=None, voltage=None Rangefinder distance: None Rangefinder voltage: None diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index f4e81e658..181be2b41 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -30,6 +30,7 @@ Vehicle state information is exposed through vehicle *attributes*. DroneKit-Pyth :py:attr:`Vehicle.mount_status `, :py:attr:`Vehicle.battery `, :py:attr:`Vehicle.rangefinder `, +:py:attr:`Vehicle.ekf_ok `, :py:attr:`Vehicle.home_location `, :py:func:`Vehicle.system_status `, :py:func:`Vehicle.heading `, @@ -69,6 +70,7 @@ regularly updated from MAVLink messages sent by the vehicle). print "Airspeed: %s" % vehicle.airspeed print "Mount status: %s" % vehicle.mount_status print "Battery: %s" % vehicle.battery + print "EKF OK?: %s" % vehicle.ekf_ok print "Rangefinder: %s" % vehicle.rangefinder print "Rangefinder distance: %s" % vehicle.rangefinder.distance print "Rangefinder voltage: %s" % vehicle.rangefinder.voltage diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 882dd4db9..cdad082aa 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1138,6 +1138,9 @@ def mount_status(self): @property def ekf_ok(self): + """ + ``True`` if the EKF status is considered acceptable, ``False`` otherwise. + """ # legacy check for dronekit-python for solo # use same check that ArduCopter::system.pde::position_ok() is using if self.armed: diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 58329df50..9f8c92f1d 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -43,6 +43,7 @@ print " Airspeed: %s" % vehicle.airspeed print " Mount status: %s" % vehicle.mount_status print " Battery: %s" % vehicle.battery +print " EKF OK?: %s" % vehicle.ekf_ok print " Rangefinder: %s" % vehicle.rangefinder print " Rangefinder distance: %s" % vehicle.rangefinder.distance print " Rangefinder voltage: %s" % vehicle.rangefinder.voltage From 3085cdb5a531062eaacb70a3580171c314b00fa7 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 10 Nov 2015 12:03:21 +1100 Subject: [PATCH 171/475] Update migrating doc to make it clear that numpy is no longer a dependency and note that it may now be possible to use other python distributions --- docs/guide/migrating.rst | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/guide/migrating.rst b/docs/guide/migrating.rst index 6c8b1c60b..22013f816 100644 --- a/docs/guide/migrating.rst +++ b/docs/guide/migrating.rst @@ -14,12 +14,16 @@ The sections below outline the main migration areas. Installation ============ -DKPY 2.0 is installed from `pip` on all platforms - see :ref:`get-started` for more information. +DKPY 2.0 is now installed from `pip` on all platforms - see :ref:`get-started` for more information. + +Installation is generally simpler than on DK 1.x because there are far fewer dependencies (both MAVProxy and numpy +are no longer needed). .. note:: - The DroneKit-Python Windows installer is no longer needed. Installation is generally simpler - than on DK 1.x because MAVProxy is not a dependency. + * The DroneKit-Python Windows installer cannot be used for DKPY2.x (and is no longer needed). + * One implication of the reduced dependencies is that it should now be easier to use other Python distributions + (like ActivePython - although this has not been verified!) Launching scripts From 5b625efd6605c30bb7832d3c335d1beb3e136b51 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 10 Nov 2015 16:26:16 -0800 Subject: [PATCH 172/475] Prevents arming while already armed. --- dronekit/lib/__init__.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index cdad082aa..955f06e1a 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1073,10 +1073,11 @@ def armed(self): @armed.setter def armed(self, value): - if value: - self._master.arducopter_arm() - else: - self._master.arducopter_disarm() + if bool(value) != self._armed: + if value: + self._master.arducopter_arm() + else: + self._master.arducopter_disarm() @property def is_armable(self): From 9c18ed91a59fa167b5f050e1042f52b85ba95e6b Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 6 Nov 2015 14:42:55 -0800 Subject: [PATCH 173/475] Restores RC capability. --- dronekit/lib/__init__.py | 68 ++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 17 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 955f06e1a..3e57e8d29 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -418,6 +418,52 @@ def decorator(fn): self.add_attribute_listener(name, fn) return decorator +class Channels(dict): + """ + Implements RC object. + """ + + def __init__(self, vehicle, count): + self._count = count + self._readonly = False + self._overrides = {} + for k in range(0, count): + self[k + 1] = None + self._readonly = True + + @property + def count(self): + return self._count + + def __setitem__(self, key, value): + if self._readonly: + raise TypeError('__setitem__ is not supported on Channels object') + return dict.__setitem__(self, key, value) + + def __len__(self): + return self._count + + def _update_channel(self, channel, value): + # If we have channels on different ports, we expand the Channels + # object to support them. + channel = str(channel) + self._readonly = False + self[channel] = value + self._readonly = True + self._count = max(self._count, int(channel)) + + @property + def overrides(self): + return copy.copy(self._overrides) + + @overrides.setter + def overrides(self, newch): + self._overrides = {} + for k, v in newch.iteritems(): + if v: + self._overrides[str(k)] = v + self._master.mav.rc_channels_override_send(0, 0, *list(self._overrides.values())) + class Vehicle(HasObservers): """ The main vehicle API @@ -694,14 +740,15 @@ def listener(self, name, m): self._mount_yaw = m.pointing_c / 100 self.notify_attribute_listeners('mount', self.mount_status) - self._rc_readback = {} + # All keys are strings. + self._channels = Channels(self, 8) @self.on_message('RC_CHANNELS_RAW') def listener(self, name, m): def set_rc(chnum, v): '''Private utility for handling rc channel messages''' # use port to allow ch nums greater than 8 - self._rc_readback[str(m.port * 8 + chnum)] = v + self._channels._update_channel(str(m.port * 8 + chnum), v) set_rc(1, m.chan1_raw) set_rc(2, m.chan2_raw) @@ -1150,21 +1197,8 @@ def ekf_ok(self): return self._ekf_poshorizabs or self._ekf_predposhorizabs @property - def channel_override(self): - overrides = self.__rc.override - # Only return entries that have a non zero override - return dict((str(num + 1), overrides[num]) for num in range(8) if overrides[num] != 0) - - @channel_override.setter - def channel_override(self, newch): - overrides = self.__rc.override - for k, v in newch.iteritems(): - overrides[int(k) - 1] = v - self.__rc.set_override(overrides) - - @property - def channel_readback(self): - return copy.copy(self._rc_readback) + def channels(self): + return self._channels @property def home_location(self): From d867d713793521da3c14ace250b6fb610dfa56c3 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 9 Nov 2015 12:13:55 -0800 Subject: [PATCH 174/475] Adds tests and fixes dict objects in channels. --- dronekit/lib/__init__.py | 54 +++++++++++++++++++++++---- dronekit/test/sitl/test_channels.py | 58 +++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 7 deletions(-) create mode 100644 dronekit/test/sitl/test_channels.py diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 3e57e8d29..af67505b7 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -418,15 +418,50 @@ def decorator(fn): self.add_attribute_listener(name, fn) return decorator + +class ChannelsOverride(dict): + def __init__(self, vehicle): + self._vehicle = vehicle + self._count = 8 # Fixed by MAVLink + + def __getitem__(self, key): + return dict.__getitem__(self, str(key)) + + def __setitem__(self, key, value): + if not (int(key) >= 0 and int(key) < self._count): + raise Exception('Invalid channel index %s' % key) + if not value: + dict.__delitem__(self, str(key)) + else: + dict.__setitem__(self, str(key), value) + self._send() + + def __delitem__(self, key): + dict.__delitem__(self, str(key)) + self._send() + + def __len__(self): + return self._count + + def _send(self): + overrides = [0] * 8 + for k, v in self.iteritems(): + overrides[int(k)-1] = v + self._vehicle._master.mav.rc_channels_override_send(0, 0, *overrides) + + class Channels(dict): """ Implements RC object. """ def __init__(self, vehicle, count): + self._vehicle = vehicle self._count = count + self._overrides = ChannelsOverride(vehicle) + + # populate readback self._readonly = False - self._overrides = {} for k in range(0, count): self[k + 1] = None self._readonly = True @@ -435,10 +470,13 @@ def __init__(self, vehicle, count): def count(self): return self._count + def __getitem__(self, key): + return dict.__getitem__(self, str(key)) + def __setitem__(self, key, value): if self._readonly: raise TypeError('__setitem__ is not supported on Channels object') - return dict.__setitem__(self, key, value) + return dict.__setitem__(self, str(key), value) def __len__(self): return self._count @@ -446,23 +484,25 @@ def __len__(self): def _update_channel(self, channel, value): # If we have channels on different ports, we expand the Channels # object to support them. - channel = str(channel) + channel = int(channel) self._readonly = False self[channel] = value self._readonly = True - self._count = max(self._count, int(channel)) + self._count = max(self._count, channel) @property def overrides(self): - return copy.copy(self._overrides) + return self._overrides @overrides.setter def overrides(self, newch): - self._overrides = {} for k, v in newch.iteritems(): if v: self._overrides[str(k)] = v - self._master.mav.rc_channels_override_send(0, 0, *list(self._overrides.values())) + else: + del self._overrides[str(k)] + self._overrides._send() + class Vehicle(HasObservers): """ diff --git a/dronekit/test/sitl/test_channels.py b/dronekit/test/sitl/test_channels.py new file mode 100644 index 000000000..f05264f42 --- /dev/null +++ b/dronekit/test/sitl/test_channels.py @@ -0,0 +1,58 @@ +from dronekit import connect +from dronekit.lib import VehicleMode +from pymavlink import mavutil +import time +from dronekit import connect, VehicleMode, LocationGlobal +from dronekit.test import with_sitl +from nose.tools import assert_equals, assert_not_equals + +def assert_readback(vehicle, values): + i = 10 + while i > 0: + time.sleep(.1) + i -= .1 + for k, v in values.iteritems(): + if vehicle.channels[k] != v: + continue + break + if i <= 0: + raise Exception('Did not match in channels readback %s' % values) + +@with_sitl +def test_timeout(connpath): + vehicle = connect(connpath, wait_ready=True) + + assert_equals(len(vehicle.channels), 8) + assert_equals(len(vehicle.channels.overrides), 8) + + assert_equals(sorted(vehicle.channels.keys()), [str(x) for x in range(1, 9)]) + assert_equals(sorted(vehicle.channels.overrides.keys()), []) + + assert_equals(type(vehicle.channels['1']), int) + assert_equals(type(vehicle.channels['2']), int) + assert_equals(type(vehicle.channels['7']), int) + assert_equals(type(vehicle.channels['8']), int) + assert_equals(type(vehicle.channels[1]), int) + assert_equals(type(vehicle.channels[2]), int) + assert_equals(type(vehicle.channels[7]), int) + assert_equals(type(vehicle.channels[8]), int) + + vehicle.channels.overrides = {'1': 1010} + assert_readback(vehicle, {'1': 1010}) + + vehicle.channels.overrides = {'2': 1020} + assert_readback(vehicle, {'1': 1500, '2': 1010}) + + vehicle.channels.overrides['1'] = 1010 + assert_readback(vehicle, {'1': 1010, '2': 1020}) + + del vehicle.channels.overrides['1'] + assert_readback(vehicle, {'1': 1500, '2': 1020}) + + vehicle.channels.overrides = {'1': 1010, '2': None} + assert_readback(vehicle, {'1': 1010, '2': 1500}) + + vehicle.channels.overrides['1'] = None + assert_readback(vehicle, {'1': 1500, '2': 1500}) + + vehicle.close() From dd2a43b72e4d38bb8a0493431bf259ca88c9f3ef Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 10 Nov 2015 17:29:48 +1100 Subject: [PATCH 175/475] Fix up docs and examples for new channel overrides class --- docs/examples/channel_overrides.rst | 100 ++++++++++-- dronekit/lib/__init__.py | 142 +++++++++--------- .../channel_overrides/channel_overrides.py | 58 +++++-- 3 files changed, 201 insertions(+), 99 deletions(-) diff --git a/docs/examples/channel_overrides.rst b/docs/examples/channel_overrides.rst index 827b6fda1..42fb77356 100644 --- a/docs/examples/channel_overrides.rst +++ b/docs/examples/channel_overrides.rst @@ -1,9 +1,9 @@ .. _example_channel_overrides: .. _vehicle_state_channel_override: -========================== -Example: Channel Overrides -========================== +======================================= +Example: Channels and Channel Overrides +======================================= This example shows how to get channel information and to get/set channel-override information. @@ -52,19 +52,50 @@ On the command prompt you should see (something like): .. code:: bash - Overriding RC channels for roll and yaw - Current overrides are: {'1': 900, '4': 1000} - Channel default values: {'1': 1500, '3': 1000, '2': 1500, '5': 1800, '4': 1500, '7': 1000, '6': 1000, '8': 1800} - Cancelling override + Connecting to vehicle on: 170.0.0.1:14550 + >>> APM:Copter V3.3 (d6053245) + >>> Frame: QUAD + >>> Calibrating barometer + >>> Initialising APM... + >>> barometer calibration complete + >>> GROUND START + Channel values from RC Tx: {'1': 1500, '3': 1000, '2': 1500, '5': 1800, '4': 1500, '7': 1000, '6': 1000, '8': 1800} + Read channels individually: + Ch1: 1500 + Ch2: 1500 + Ch3: 1000 + Ch4: 1500 + Ch5: 1800 + Ch6: 1000 + Ch7: 1000 + Ch8: 1800 + Number of channels: 8 + + Channel overrides: {} + Set Ch2 override to 200 (indexing syntax) + Channel overrides: {'2': 200} + Ch2 override: 200 + Set Ch3 override to 300 (dictionary syntax) + Channel overrides: {'3': 300, '2': 200} + Set Ch1-Ch8 overrides to 110-810 respectively + Channel overrides: {'1': 110, '3': 310, '2': 210, '5': 510, '4': 4100, '7': 710, '6': 610} + + Cancel Ch2 override (indexing syntax) + Channel overrides: {'1': 110, '3': 310, '5': 510, '4': 4100, '7': 710, '6': 610} + Cancel Ch3 override (del syntax) + Channel overrides: {'1': 110, '5': 510, '4': 4100, '7': 710, '6': 610} + Cancel Ch5, Ch6 override and set channel 3 to 500 (braces syntax) + Channel overrides: {'1': 110, '3': 500, '4': 4100, '7': 710} + + Close vehicle object + Completed How does it work? ================= -Get the default values of the channels using the :py:attr:`channel_readback ` attribute. - -You can over-ride these values using the :py:attr:`channel_override ` attribute. This takes a dictionary argument defining the RC *output* channels to be overridden (specified by channel number), and their new values. Channels that are not specified in the dictionary are not overridden. All multi-channel updates are atomic. To cancel an override call ``channel_override`` again, setting zero for the overridden channels. +The RC transmitter channels are connected to the autopilot and control the vehicle. The values of the first four channels map to the main flight controls: 1=Roll, 2=Pitch, 3=Throttle, 4=Yaw (the mapping is defined in ``RCMAP_`` parameters in `Plane `_, @@ -77,7 +108,56 @@ In general a value of 0 set for a specific ``RCn_FUNCTION`` indicates that the c `mission controlled `_ (i.e. it will not directly be controlled by normal autopilot code). +You can read the values of the channels using the :py:attr:`Vehicle.channels ` attribute. The values are regularly updated, +from the UAV, based on the RC inputs from the transmitter. These can be read either as a set or individually: + +.. code:: python + + # Get all channel values from RC transmitter + print "Channel values from RC Tx:", vehicle.channels + + # Access channels individually + print "Read channels individually:" + print " Ch1: %s" % vehicle.channels['1'] + print " Ch2: %s" % vehicle.channels['2'] + +You can override the values sent to the vehicle by the autopilot using :py:attr:`Vehicle.channels.overrides ` +(although this is not recommended)! The overrides can be written individually using an indexing syntax or as a set using a dictionary syntax. + +.. code:: python + + # Set Ch2 override to 200 using indexing syntax + vehicle.channels.overrides['2'] = 200 + # Set Ch3, Ch4 override to 300,400 using dictionary syntax" + vehicle.channels.overrides = {'3':300, '4':400} + +To clear an override you can set its value to ``None`` as shown (or call ``del`` on it): + +.. code:: python + + # Clear override by setting channels to None + # Clear using index syntax + vehicle.channels.overrides['2'] = None + + # Clear using 'del' syntax + del vehicle.channels.overrides['3'] + + # Clear using dictionary syntax (and set override at same time!) + vehicle.channels.overrides = {'5':None, '6':None,'3':500} + +Read the channel overrides either as a dictionary or by index. + +.. code:: python + + # Get all channel overrides + print " Channel overrides: %s" % vehicle.channels.overrides + # Print just one channel override + print " Ch2 override: %s" % vehicle.channels.overrides['2'] + +.. note:: + You'll get a ``KeyError`` exception if you read a channel override that has + not been set. Source code diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index af67505b7..1b4cd9deb 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -420,6 +420,14 @@ def decorator(fn): class ChannelsOverride(dict): + """ + A dictionary class for managing Vehicle channel overrides. + + Channels can be read, written, or cleared by index or using a dictionary syntax. + To clear a value, set it to ``None`` or use ``del`` on the item. + + For more information and examples see :ref:`example_channel_overrides`. + """ def __init__(self, vehicle): self._vehicle = vehicle self._count = 8 # Fixed by MAVLink @@ -452,7 +460,12 @@ def _send(self): class Channels(dict): """ - Implements RC object. + A dictionary class for managing RC channel information associated with a :py:class:`Vehicle`. + + An object of this type is accessed through :py:attr:`Vehicle.channels`. This object also stores + the current vehicle channel overrides through its :py:attr:`overrides` attribute. + + For more information and examples see :ref:`example_channel_overrides`. """ def __init__(self, vehicle, count): @@ -468,6 +481,9 @@ def __init__(self, vehicle, count): @property def count(self): + """ + The number of channels defined in the dictionary (currently 8). + """ return self._count def __getitem__(self, key): @@ -492,6 +508,37 @@ def _update_channel(self, channel, value): @property def overrides(self): + """ + Attribute to read, set and clear channel overrides (also known as "rc overrides") + associated with a :py:class:`Vehicle` (via :py:class:`Vehicle.channels`). This is an + object of type :py:class:`ChannelsOverride`. + + For more information and examples see :ref:`example_channel_overrides`. + + To set channel overrides: + + .. code:: python + + # Set and clear overrids using dictionary syntax (clear by setting override to none) + vehicle.channels.overrides = {'5':None, '6':None,'3':500} + + # You can also set and clear overrides using indexing syntax + vehicle.channels.overrides['2'] = 200 + vehicle.channels.overrides['2'] = None + + # And clear using 'del' + del vehicle.channels.overrides['3'] + + Read the channel overrides either as a dictionary or by index. Note that you'll get + a ``KeyError`` exception if you read a channel override that has not been set. + + .. code:: python + + # Get all channel overrides + print " Channel overrides: %s" % vehicle.channels.overrides + # Print just one channel override + print " Ch2 override: %s" % vehicle.channels.overrides['2'] + """ return self._overrides @overrides.setter @@ -590,80 +637,7 @@ class Vehicle(HasObservers): :py:class:`Rangefinder` distance and voltage values. - .. py:attribute:: channel_override - - .. warning:: - - RC override may be useful for simulating user input and when implementing certain types of joystick control. - It should not be used for direct control of vehicle channels unless there is no other choice! - - Instead use the appropriate MAVLink commands like DO_SET_SERVO/DO_SET_RELAY, or more generally - set the desired position or direction/speed. - - This attribute takes a dictionary argument defining the RC *output* channels to be overridden (specified by channel number), and their new values. - Channels that are not specified in the dictionary are not overridden. All multi-channel updates are atomic. - - To cancel an override call ``channel_override`` again, setting zero for the overridden channels. - - The values of the first four channels map to the main flight controls: 1=Roll, 2=Pitch, 3=Throttle, 4=Yaw (the mapping is defined in ``RCMAP_`` parameters: - `Plane `_, - `Copter `_ , - `Rover `_). - - The remaining channel values are configurable, and their purpose can be determined using the - `RCn_FUNCTION parameters `_. - In general a value of 0 set for a specific ``RCn_FUNCTION`` indicates that the channel can be - `mission controlled `_ (i.e. it will not directly be - controlled by normal autopilot code). - - An example of setting and clearing the override is given below: - .. code:: python - - # Override channels 1 and 4 (only). - vehicle.channel_override = { "1" : 900, "4" : 1000 } - - # Cancel override on channel 1 and 4 by sending 0 - vehicle.channel_override = { "1" : 0, "4" : 0 } - - .. versionchanged:: 1.0 - - This update replaces ``rc_override`` with ``channel_override``/``channel_readback`` documentation. - - .. todo:: Add note to the examples/guide like warning above not to use this mechanism except as intended: - - https://github.com/dronekit/dronekit-python/issues/72 - - .. todo:: - - channel_override/channel_readback documentation - - In a future update strings will be defined per vehicle type ('pitch', 'yaw', 'roll' etc...) - and rather than setting channel 3 to 1400 (for instance), you will pass in a dict with - 'throttle':1200. - - This change will be useful in two ways: - - * we can hide (eventually we can deprecate) any notion of rc channel numbers at all. - * vehicles can eventually define new 'channels' for overridden values. - - FIXME: Remaining channel_override/channel_readback FIXMEs: - - * how to address the units issue? Merely with documentation or some other way? - * is there any benefit of using lists rather than tuples for these attributes - - .. py:attribute:: channel_readback - - This read-only attribute returns a dictionary containing the *original* vehicle RC channel values (ignoring any overrides set using - :py:attr:`channel_override `). Dictionary entries have the format ``channelName -> value``. - - For example, the returned dictionary might look like this: - - .. code:: python - - RC readback: {'1': 1500, '3': 1000, '2': 1500, '5': 1800, '4': 1500, '7': 1000, '6': 1000, '8': 1800} ? Dictionary () (read only) - - .. todo:: In V2, there may be ardupilot specific attributes & types (as in the introduction). If so, text below might be useful. **Autopilot specific attributes & types:** @@ -1238,6 +1212,26 @@ def ekf_ok(self): @property def channels(self): + """ + The RC channel values from the RC Transmitter, in a :py:class:`Channels` object. + The attribute can also be used to set and read RC Override (channel override) values + via :py:attr:`Vehicle.channels.override `. + + For more information and examples see :ref:`example_channel_overrides`. + + To read the channels from the RC transmitter: + + .. code:: python + + # Get all channel values from RC transmitter + print "Channel values from RC Tx:", vehicle.channels + + # Access channels individually + print "Read channels individually:" + print " Ch1: %s" % vehicle.channels['1'] + print " Ch2: %s" % vehicle.channels['2'] + + """ return self._channels @property diff --git a/examples/channel_overrides/channel_overrides.py b/examples/channel_overrides/channel_overrides.py index 57f9908ce..5edef9e2e 100644 --- a/examples/channel_overrides/channel_overrides.py +++ b/examples/channel_overrides/channel_overrides.py @@ -10,13 +10,10 @@ They are provided for development purposes. Please raise an issue explaining why you need them and we will try to find a better alternative: https://github.com/dronekit/dronekit-python/issues - Full documentation is provided at http://python.dronekit.io/examples/channel_overrides.html """ from dronekit import connect -from dronekit.lib import VehicleMode from pymavlink import mavutil -import time #Set up option parsing to get connection string import argparse @@ -30,23 +27,54 @@ print 'Connecting to vehicle on: %s' % args.connect vehicle = connect(args.connect, wait_ready=True) -#Override channels -print "\nOverriding RC channels for roll and yaw" -vehicle.channel_override = { "1" : 900, "4" : 1000 } -print " Current overrides are:", vehicle.channel_override - # Get all original channel values (before override) -print " Channel default values:", vehicle.channel_readback +print "Channel values from RC Tx:", vehicle.channels + +# Access channels individually +print "Read channels individually:" +print " Ch1: %s" % vehicle.channels['1'] +print " Ch2: %s" % vehicle.channels['2'] +print " Ch3: %s" % vehicle.channels['3'] +print " Ch4: %s" % vehicle.channels['4'] +print " Ch5: %s" % vehicle.channels['5'] +print " Ch6: %s" % vehicle.channels['6'] +print " Ch7: %s" % vehicle.channels['7'] +print " Ch8: %s" % vehicle.channels['8'] +print "Number of channels: %s" % len(vehicle.channels) + + +# Override channels +print "\nChannel overrides: %s" % vehicle.channels.overrides + +print "Set Ch2 override to 200 (indexing syntax)" +vehicle.channels.overrides['2'] = 200 +print " Channel overrides: %s" % vehicle.channels.overrides +print " Ch2 override: %s" % vehicle.channels.overrides['2'] + +print "Set Ch3 override to 300 (dictionary syntax)" +vehicle.channels.overrides = {'3':300} +print " Channel overrides: %s" % vehicle.channels.overrides + +print "Set Ch1-Ch8 overrides to 110-810 respectively" +vehicle.channels.overrides = {'1': 110, '2': 210,'3': 310,'4':4100, '5':510,'6':610,'7':710,'8':810} +print " Channel overrides: %s" % vehicle.channels.overrides + + +# Clear override by setting channels to None +print "\nCancel Ch2 override (indexing syntax)" +vehicle.channels.overrides['2'] = None +print " Channel overrides: %s" % vehicle.channels.overrides -# Cancel override by setting channels to 0 -print " Cancelling override" -vehicle.channel_override = { "1" : 0, "4" : 0 } +print "Clear Ch3 override (del syntax)" +del vehicle.channels.overrides['3'] +print " Channel overrides: %s" % vehicle.channels.overrides -# Short wait before exiting -time.sleep(5) +print "Clear Ch5, Ch6 override and set channel 3 to 500 (dictionary syntax)" +vehicle.channels.overrides = {'5':None, '6':None,'3':500} +print " Channel overrides: %s" % vehicle.channels.overrides #Close vehicle object before exiting script -print "Close vehicle object" +print "\nClose vehicle object" vehicle.close() print("Completed") From c8f91187004c0b99bf40c30a920b077d21fd1dde Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 10 Nov 2015 15:36:15 -0800 Subject: [PATCH 176/475] Adds more extensive tests. --- dronekit/test/sitl/test_channels.py | 85 ++++++++++++++++++++++ test/noise.py | 108 ++++++++++++++++++++++++++++ 2 files changed, 193 insertions(+) create mode 100644 test/noise.py diff --git a/dronekit/test/sitl/test_channels.py b/dronekit/test/sitl/test_channels.py index f05264f42..caf70d4ae 100644 --- a/dronekit/test/sitl/test_channels.py +++ b/dronekit/test/sitl/test_channels.py @@ -30,10 +30,18 @@ def test_timeout(connpath): assert_equals(type(vehicle.channels['1']), int) assert_equals(type(vehicle.channels['2']), int) + assert_equals(type(vehicle.channels['3']), int) + assert_equals(type(vehicle.channels['4']), int) + assert_equals(type(vehicle.channels['5']), int) + assert_equals(type(vehicle.channels['6']), int) assert_equals(type(vehicle.channels['7']), int) assert_equals(type(vehicle.channels['8']), int) assert_equals(type(vehicle.channels[1]), int) assert_equals(type(vehicle.channels[2]), int) + assert_equals(type(vehicle.channels[3]), int) + assert_equals(type(vehicle.channels[4]), int) + assert_equals(type(vehicle.channels[5]), int) + assert_equals(type(vehicle.channels[6]), int) assert_equals(type(vehicle.channels[7]), int) assert_equals(type(vehicle.channels[8]), int) @@ -55,4 +63,81 @@ def test_timeout(connpath): vehicle.channels.overrides['1'] = None assert_readback(vehicle, {'1': 1500, '2': 1500}) + #test + try: + print "Ch9: %s" % vehicle.channels['9'] + assert False, "Can read over end of channels" + except: + pass + + try: + print "Ch0: %s" % vehicle.channels['0'] + assert False, "Can read over start of channels" + except: + pass + + try: + vehicle.channels['1'] = 200 + assert False, "can write a channel value" + except: + pass + + print "Channel overrides: %s" % vehicle.channels.overrides + + # Set Ch1 to 100 using braces syntax + vehicle.channels.overrides = {'1': 1000} + print "Channel overrides: %s" % vehicle.channels.overrides + + # Set Ch2 to 200 using bracket + vehicle.channels.overrides['2'] = 200 + print "Channel overrides: %s" % vehicle.channels.overrides + + # Set Ch2 to 1010 + vehicle.channels.overrides = {'2': 1010} + print "Channel overrides: %s" % vehicle.channels.overrides + + # Set Ch3,4,5,6,7 to 300,400-700 respectively + vehicle.channels.overrides = {'3': 300, '4':400, '5':500,'6':600,'7':700} + print "Channel overrides: %s" % vehicle.channels.overrides + + # Set Ch8 to 800 using braces + vehicle.channels.overrides = {'8': 800} + print "Channel overrides: %s" % vehicle.channels.overrides + print "succeed - can write channel 8 using braces" + + # Set Ch8 to 800 using brackets + vehicle.channels.overrides['8'] = 800 + print "Channel overrides: %s" % vehicle.channels.overrides + + try: + # Try to write channel 9 override to a value with brackets + vehicle.channels.overrides['9']=900 + assert False, "can write channels.overrides 9" + except: + pass + + try: + # Try to write channel 9 override to a value with braces + vehicle.channels.overrides={'9': 900} + assert False, "can write channels.overrides 9 with braces" + except: + pass + + # Clear channel 3 using brackets + vehicle.channels.overrides['3'] = None + print "Channel overrides: %s" % vehicle.channels.overrides + + # Clear channel 2 using braces + vehicle.channels.overrides = {'2': None} + print "Channel overrides: %s" % vehicle.channels.overrides + + # Clear all channels + vehicle.channels.overrides = {} + print "Channel overrides: %s" % vehicle.channels.overrides + + # Set Ch2 to 33, clear channel 6 + vehicle.channels.overrides = {'2': 33, '6':None} + print "Channel overrides: %s" % vehicle.channels.overrides + + vehicle.close() diff --git a/test/noise.py b/test/noise.py new file mode 100644 index 000000000..21ca79b1e --- /dev/null +++ b/test/noise.py @@ -0,0 +1,108 @@ +from dronekit import connect, VehicleMode +#from dronekit.lib import VehicleMode +from pymavlink import mavutil +import time + +#Set up option parsing to get connection string +import argparse +parser = argparse.ArgumentParser(description='Example showing how to set and clear vehicle channel-override information. Connects to SITL on local PC by default.') +parser.add_argument('--connect', default='127.0.0.1:14550', + help="vehicle connection target. Default '127.0.0.1:14550'") +args = parser.parse_args() + + +# Connect to the Vehicle +print 'Connecting to vehicle on: %s' % args.connect +vehicle = connect(args.connect, wait_ready=True) + +# Check for channel access. +vehicle.channels['1'] +vehicle.channels['2'] +vehicle.channels['3'] +vehicle.channels['4'] +vehicle.channels['5'] +vehicle.channels['6'] +vehicle.channels['7'] +vehicle.channels['8'] + +#test +try: + print "Ch9: %s" % vehicle.channels['9'] + assert False, "Can read over end of channels" +except: + pass + +try: + print "Ch0: %s" % vehicle.channels['0'] + assert False, "Can read over start of channels" +except: + pass + +try: + vehicle.channels['1'] = 200 + assert False, "can write a channel value" +except: + pass + +print "Channel overrides: %s" % vehicle.channels.overrides + +# Set Ch1 to 100 using braces syntax +vehicle.channels.overrides = {'1': 1000} +print "Channel overrides: %s" % vehicle.channels.overrides + +# Set Ch2 to 200 using bracket +vehicle.channels.overrides['2'] = 200 +print "Channel overrides: %s" % vehicle.channels.overrides + +# Set Ch2 to 1010 +vehicle.channels.overrides = {'2': 1010} +print "Channel overrides: %s" % vehicle.channels.overrides + +# Set Ch3,4,5,6,7 to 300,400-700 respectively +vehicle.channels.overrides = {'3': 300, '4':400, '5':500,'6':600,'7':700} +print "Channel overrides: %s" % vehicle.channels.overrides + +# Set Ch8 to 800 using braces +vehicle.channels.overrides = {'8': 800} +print "Channel overrides: %s" % vehicle.channels.overrides +print "succeed - can write channel 8 using braces" + +# Set Ch8 to 800 using brackets +vehicle.channels.overrides['8'] = 800 +print "Channel overrides: %s" % vehicle.channels.overrides + +try: + # Try to write channel 9 override to a value with brackets + vehicle.channels.overrides['9']=900 + assert False, "can write channels.overrides 9" +except: + pass + +try: + # Try to write channel 9 override to a value with braces + vehicle.channels.overrides={'9': 900} + assert False, "can write channels.overrides 9 with braces" +except: + pass + +# Clear channel 3 using brackets +vehicle.channels.overrides['3'] = None +print "Channel overrides: %s" % vehicle.channels.overrides + +# Clear channel 2 using braces +vehicle.channels.overrides = {'2': None} +print "Channel overrides: %s" % vehicle.channels.overrides + +# Clear all channels +vehicle.channels.overrides = {} +print "Channel overrides: %s" % vehicle.channels.overrides + +# Set Ch2 to 33, clear channel 6 +vehicle.channels.overrides = {'2': 33, '6':None} +print "Channel overrides: %s" % vehicle.channels.overrides + +#Close vehicle object before exiting script +print "Close vehicle object" +vehicle.close() + +print("Completed") From 38cd7cee3ce277cdc2863db5dc1b97c55eb8a534 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 10 Nov 2015 15:36:28 -0800 Subject: [PATCH 177/475] Adds more extensive tests to channels. --- dronekit/lib/__init__.py | 25 +++++-- dronekit/test/sitl/test_channels.py | 27 ++++--- test/noise.py | 108 ---------------------------- 3 files changed, 30 insertions(+), 130 deletions(-) delete mode 100644 test/noise.py diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 1b4cd9deb..7b1dd0a92 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -431,15 +431,19 @@ class ChannelsOverride(dict): def __init__(self, vehicle): self._vehicle = vehicle self._count = 8 # Fixed by MAVLink + self._active = True def __getitem__(self, key): return dict.__getitem__(self, str(key)) def __setitem__(self, key, value): - if not (int(key) >= 0 and int(key) < self._count): + if not (int(key) > 0 and int(key) <= self._count): raise Exception('Invalid channel index %s' % key) if not value: - dict.__delitem__(self, str(key)) + try: + dict.__delitem__(self, str(key)) + except: + pass else: dict.__setitem__(self, str(key), value) self._send() @@ -452,10 +456,11 @@ def __len__(self): return self._count def _send(self): - overrides = [0] * 8 - for k, v in self.iteritems(): - overrides[int(k)-1] = v - self._vehicle._master.mav.rc_channels_override_send(0, 0, *overrides) + if self._active: + overrides = [0] * 8 + for k, v in self.iteritems(): + overrides[int(k)-1] = v + self._vehicle._master.mav.rc_channels_override_send(0, 0, *overrides) class Channels(dict): @@ -543,11 +548,17 @@ def overrides(self): @overrides.setter def overrides(self, newch): + self._overrides._active = False + self._overrides.clear() for k, v in newch.iteritems(): if v: self._overrides[str(k)] = v else: - del self._overrides[str(k)] + try: + del self._overrides[str(k)] + except: + pass + self._overrides._active = True self._overrides._send() diff --git a/dronekit/test/sitl/test_channels.py b/dronekit/test/sitl/test_channels.py index caf70d4ae..775c64ae1 100644 --- a/dronekit/test/sitl/test_channels.py +++ b/dronekit/test/sitl/test_channels.py @@ -82,32 +82,29 @@ def test_timeout(connpath): except: pass - print "Channel overrides: %s" % vehicle.channels.overrides - # Set Ch1 to 100 using braces syntax vehicle.channels.overrides = {'1': 1000} - print "Channel overrides: %s" % vehicle.channels.overrides + assert_readback(vehicle, {'1': 1000}) # Set Ch2 to 200 using bracket vehicle.channels.overrides['2'] = 200 - print "Channel overrides: %s" % vehicle.channels.overrides + assert_readback(vehicle, {'1': 200, '2': 200}) # Set Ch2 to 1010 vehicle.channels.overrides = {'2': 1010} - print "Channel overrides: %s" % vehicle.channels.overrides + assert_readback(vehicle, {'1': 1500, '2': 1010}) # Set Ch3,4,5,6,7 to 300,400-700 respectively vehicle.channels.overrides = {'3': 300, '4':400, '5':500,'6':600,'7':700} - print "Channel overrides: %s" % vehicle.channels.overrides + assert_readback(vehicle, {'3': 300, '4':400, '5':500,'6':600,'7':700}) # Set Ch8 to 800 using braces vehicle.channels.overrides = {'8': 800} - print "Channel overrides: %s" % vehicle.channels.overrides - print "succeed - can write channel 8 using braces" + assert_readback(vehicle, {'8':800}) # Set Ch8 to 800 using brackets - vehicle.channels.overrides['8'] = 800 - print "Channel overrides: %s" % vehicle.channels.overrides + vehicle.channels.overrides['8'] = 810 + assert_readback(vehicle, {'8':810}) try: # Try to write channel 9 override to a value with brackets @@ -125,19 +122,19 @@ def test_timeout(connpath): # Clear channel 3 using brackets vehicle.channels.overrides['3'] = None - print "Channel overrides: %s" % vehicle.channels.overrides + assert '3' not in vehicle.channels.overrides, 'overrides hould not contain None' # Clear channel 2 using braces vehicle.channels.overrides = {'2': None} - print "Channel overrides: %s" % vehicle.channels.overrides + assert '2' not in vehicle.channels.overrides, 'overrides hould not contain None' # Clear all channels vehicle.channels.overrides = {} - print "Channel overrides: %s" % vehicle.channels.overrides + assert_equals(len(vehicle.channels.overrides.keys()), 0) # Set Ch2 to 33, clear channel 6 vehicle.channels.overrides = {'2': 33, '6':None} - print "Channel overrides: %s" % vehicle.channels.overrides - + assert_readback(vehicle, {'2':33, '6': 1500}) + assert_equals(vehicle.channels.overrides.keys(), ['2']) vehicle.close() diff --git a/test/noise.py b/test/noise.py deleted file mode 100644 index 21ca79b1e..000000000 --- a/test/noise.py +++ /dev/null @@ -1,108 +0,0 @@ -from dronekit import connect, VehicleMode -#from dronekit.lib import VehicleMode -from pymavlink import mavutil -import time - -#Set up option parsing to get connection string -import argparse -parser = argparse.ArgumentParser(description='Example showing how to set and clear vehicle channel-override information. Connects to SITL on local PC by default.') -parser.add_argument('--connect', default='127.0.0.1:14550', - help="vehicle connection target. Default '127.0.0.1:14550'") -args = parser.parse_args() - - -# Connect to the Vehicle -print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, wait_ready=True) - -# Check for channel access. -vehicle.channels['1'] -vehicle.channels['2'] -vehicle.channels['3'] -vehicle.channels['4'] -vehicle.channels['5'] -vehicle.channels['6'] -vehicle.channels['7'] -vehicle.channels['8'] - -#test -try: - print "Ch9: %s" % vehicle.channels['9'] - assert False, "Can read over end of channels" -except: - pass - -try: - print "Ch0: %s" % vehicle.channels['0'] - assert False, "Can read over start of channels" -except: - pass - -try: - vehicle.channels['1'] = 200 - assert False, "can write a channel value" -except: - pass - -print "Channel overrides: %s" % vehicle.channels.overrides - -# Set Ch1 to 100 using braces syntax -vehicle.channels.overrides = {'1': 1000} -print "Channel overrides: %s" % vehicle.channels.overrides - -# Set Ch2 to 200 using bracket -vehicle.channels.overrides['2'] = 200 -print "Channel overrides: %s" % vehicle.channels.overrides - -# Set Ch2 to 1010 -vehicle.channels.overrides = {'2': 1010} -print "Channel overrides: %s" % vehicle.channels.overrides - -# Set Ch3,4,5,6,7 to 300,400-700 respectively -vehicle.channels.overrides = {'3': 300, '4':400, '5':500,'6':600,'7':700} -print "Channel overrides: %s" % vehicle.channels.overrides - -# Set Ch8 to 800 using braces -vehicle.channels.overrides = {'8': 800} -print "Channel overrides: %s" % vehicle.channels.overrides -print "succeed - can write channel 8 using braces" - -# Set Ch8 to 800 using brackets -vehicle.channels.overrides['8'] = 800 -print "Channel overrides: %s" % vehicle.channels.overrides - -try: - # Try to write channel 9 override to a value with brackets - vehicle.channels.overrides['9']=900 - assert False, "can write channels.overrides 9" -except: - pass - -try: - # Try to write channel 9 override to a value with braces - vehicle.channels.overrides={'9': 900} - assert False, "can write channels.overrides 9 with braces" -except: - pass - -# Clear channel 3 using brackets -vehicle.channels.overrides['3'] = None -print "Channel overrides: %s" % vehicle.channels.overrides - -# Clear channel 2 using braces -vehicle.channels.overrides = {'2': None} -print "Channel overrides: %s" % vehicle.channels.overrides - -# Clear all channels -vehicle.channels.overrides = {} -print "Channel overrides: %s" % vehicle.channels.overrides - -# Set Ch2 to 33, clear channel 6 -vehicle.channels.overrides = {'2': 33, '6':None} -print "Channel overrides: %s" % vehicle.channels.overrides - -#Close vehicle object before exiting script -print "Close vehicle object" -vehicle.close() - -print("Completed") From 3cdd7280b10d203459818b35cd4aac53a1276959 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 10 Nov 2015 16:04:59 -0800 Subject: [PATCH 178/475] Adds callback test. --- dronekit/lib/__init__.py | 1 + dronekit/test/sitl/test_channels.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 7b1dd0a92..07fc59d2d 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -783,6 +783,7 @@ def set_rc(chnum, v): set_rc(6, m.chan6_raw) set_rc(7, m.chan7_raw) set_rc(8, m.chan8_raw) + self.notify_attribute_listeners('channels', self.channels) self._voltage = None self._current = None diff --git a/dronekit/test/sitl/test_channels.py b/dronekit/test/sitl/test_channels.py index 775c64ae1..04dc4e04f 100644 --- a/dronekit/test/sitl/test_channels.py +++ b/dronekit/test/sitl/test_channels.py @@ -137,4 +137,19 @@ def test_timeout(connpath): assert_readback(vehicle, {'2':33, '6': 1500}) assert_equals(vehicle.channels.overrides.keys(), ['2']) + # Callbacks + result = {'success': False} + vehicle.channels.overrides = {} + def channels_callback(vehicle, name, channels): + print(channels['3']) + if channels['3'] == 55: + result['success'] = True + vehicle.add_attribute_listener('channels', channels_callback) + vehicle.channels.overrides = {'3': 55} + + i = 5 + while not result['success'] and i > 0: + time.sleep(.1) + assert result['success'], 'channels callback should be invoked.' + vehicle.close() From 054e9efb752f3eb91755f60cbfd652a80bb7f107 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 11 Nov 2015 11:42:57 +1100 Subject: [PATCH 179/475] Tidy up example/docs now that index 8 on channels.overrides works and clearing all overrides. Also added doc to migration guide --- docs/examples/channel_overrides.rst | 22 ++++++++++++------- docs/guide/migrating.rst | 19 ++++++++++++++++ dronekit/lib/__init__.py | 5 ++++- .../channel_overrides/channel_overrides.py | 6 ++++- 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/docs/examples/channel_overrides.rst b/docs/examples/channel_overrides.rst index 42fb77356..c93eb954a 100644 --- a/docs/examples/channel_overrides.rst +++ b/docs/examples/channel_overrides.rst @@ -76,16 +76,18 @@ On the command prompt you should see (something like): Channel overrides: {'2': 200} Ch2 override: 200 Set Ch3 override to 300 (dictionary syntax) - Channel overrides: {'3': 300, '2': 200} + Channel overrides: {'3': 300} Set Ch1-Ch8 overrides to 110-810 respectively - Channel overrides: {'1': 110, '3': 310, '2': 210, '5': 510, '4': 4100, '7': 710, '6': 610} + Channel overrides: {'1': 110, '3': 310, '2': 210, '5': 510, '4': 4100, '7': 710, '6': 610, '8': 810} Cancel Ch2 override (indexing syntax) - Channel overrides: {'1': 110, '3': 310, '5': 510, '4': 4100, '7': 710, '6': 610} - Cancel Ch3 override (del syntax) - Channel overrides: {'1': 110, '5': 510, '4': 4100, '7': 710, '6': 610} - Cancel Ch5, Ch6 override and set channel 3 to 500 (braces syntax) - Channel overrides: {'1': 110, '3': 500, '4': 4100, '7': 710} + Channel overrides: {'1': 110, '3': 310, '5': 510, '4': 4100, '7': 710, '6': 610, '8': 810} + Clear Ch3 override (del syntax) + Channel overrides: {'1': 110, '5': 510, '4': 4100, '7': 710, '6': 610, '8': 810} + Clear Ch5, Ch6 override and set channel 3 to 500 (dictionary syntax) + Channel overrides: {'3': 500} + Clear all overrides + Channel overrides: {} Close vehicle object Completed @@ -131,7 +133,8 @@ You can override the values sent to the vehicle by the autopilot using :py:attr: # Set Ch3, Ch4 override to 300,400 using dictionary syntax" vehicle.channels.overrides = {'3':300, '4':400} -To clear an override you can set its value to ``None`` as shown (or call ``del`` on it): +To clear all overrides, set the attribute to an empty dictionary. +To clear an individual override you can set its value to ``None`` (or call ``del`` on it): .. code:: python @@ -144,6 +147,9 @@ To clear an override you can set its value to ``None`` as shown (or call ``del`` # Clear using dictionary syntax (and set override at same time!) vehicle.channels.overrides = {'5':None, '6':None,'3':500} + + # Clear all overrides by setting an empty dictionary + vehicle.channels.overrides = {} Read the channel overrides either as a dictionary or by index. diff --git a/docs/guide/migrating.rst b/docs/guide/migrating.rst index 22013f816..23a5c13ec 100644 --- a/docs/guide/migrating.rst +++ b/docs/guide/migrating.rst @@ -237,6 +237,25 @@ including: :py:func:`Vehicle.is_armable `. +Channel Overrides +----------------- + +.. warning:: + + Channel overrides (a.k.a “RC overrides”) are highly discommended (they are primarily implemented for + simulating user input and when implementing certain types of joystick control). + +DKPY v2 replaces the ``vehicle.channel_readback`` attribute with +:py:attr:`Vehicle.channels ` (and the :py:class:`Channels ` +class) and the ``vehicle.channel_override`` attribute with +:py:attr:`Vehicle.channels.overrides ` +(and the :py:class:`ChannelsOverrides ` class). + +Documentation and example code for how to use the new API are provided in :ref:`example_channel_overrides`. + + + + Debugging ========= diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 07fc59d2d..5f29789e1 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -531,8 +531,11 @@ def overrides(self): vehicle.channels.overrides['2'] = 200 vehicle.channels.overrides['2'] = None - # And clear using 'del' + # Clear using 'del' del vehicle.channels.overrides['3'] + + # Clear all overrides by setting an empty dictionary + vehicle.channels.overrides = {} Read the channel overrides either as a dictionary or by index. Note that you'll get a ``KeyError`` exception if you read a channel override that has not been set. diff --git a/examples/channel_overrides/channel_overrides.py b/examples/channel_overrides/channel_overrides.py index 5edef9e2e..cecd9943f 100644 --- a/examples/channel_overrides/channel_overrides.py +++ b/examples/channel_overrides/channel_overrides.py @@ -13,7 +13,7 @@ Full documentation is provided at http://python.dronekit.io/examples/channel_overrides.html """ from dronekit import connect -from pymavlink import mavutil + #Set up option parsing to get connection string import argparse @@ -73,6 +73,10 @@ vehicle.channels.overrides = {'5':None, '6':None,'3':500} print " Channel overrides: %s" % vehicle.channels.overrides +print "Clear all overrides" +vehicle.channels.overrides = {} +print " Channel overrides: %s" % vehicle.channels.overrides + #Close vehicle object before exiting script print "\nClose vehicle object" vehicle.close() From bf1fa02b411dda7cbcc92efe8c64abbb4aafa429 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 10 Nov 2015 16:51:37 -0800 Subject: [PATCH 180/475] Memoize attribute listeners to not call them on equal values. --- dronekit/lib/__init__.py | 20 ++++++++++++++++---- dronekit/test/sitl/test_110.py | 14 +++++++++----- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 5f29789e1..132163efd 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -292,6 +292,7 @@ class HasObservers(object): def __init__(self): # A mapping from attr_name to a list of observers self.__observers = {} + self._attribute_cache = {} """ Provides callback based notification on attribute changes. @@ -363,16 +364,27 @@ def remove_attribute_listener(self, attr_name, observer): if len(l) == 0: del self.__observers[attr_name] - def notify_attribute_listeners(self, attr_name, value): + + def notify_attribute_listeners(self, attr_name, value, cache=False): """ This method calls attribute observers when the named attribute has changed. It should be called in message listeners after updating an attribute with new information from the vehicle. + + If ``cache`` is true, if the attribute's value has not changed since the last + invocation, its listeners are not invoked. :param String attr_name: The name of the attribute that has been updated. :param value: The current value of the attribute that has been updated. """ + # Cached values are not re-sent if they are unchanged. + if cache: + if attr_name in self._attribute_cache and self._attribute_cache[attr_name] == value: + return + self._attribute_cache[attr_name] = value + + # Notify observers. for fn in self.__observers.get(attr_name, []): fn(self, attr_name, value) for fn in self.__observers.get('*', []): @@ -840,11 +852,11 @@ def listener(self, name, m): @self.on_message('HEARTBEAT') def listener(self, name, m): self._armed = (m.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED) != 0 - self.notify_attribute_listeners('armed', self.armed) + self.notify_attribute_listeners('armed', self.armed, cache=True) self._flightmode = {v: k for k, v in self._master.mode_mapping().items()}[m.custom_mode] - self.notify_attribute_listeners('mode', self.mode) + self.notify_attribute_listeners('mode', self.mode, cache=True) self._system_status = m.system_status - self.notify_attribute_listeners('system_status', self.system_status) + self.notify_attribute_listeners('system_status', self.system_status, cache=True) # Waypoints. diff --git a/dronekit/test/sitl/test_110.py b/dronekit/test/sitl/test_110.py index 98c4e567e..c3ee2aea4 100644 --- a/dronekit/test/sitl/test_110.py +++ b/dronekit/test/sitl/test_110.py @@ -14,9 +14,13 @@ def test_110(connpath): # exclusively for simulation. Take heed!!! vehicle.parameters['FS_GCS_ENABLE'] = 0 vehicle.parameters['FS_EKF_THRESH'] = 100 + + # Await armability. + while not vehicle.is_armable: + time.sleep(.1) # Change the vehicle into STABILIZE mode - vehicle.mode = VehicleMode("STABILIZE") + vehicle.mode = VehicleMode("GUIDED") # NOTE wait crudely for ACK on mode update time.sleep(3) @@ -34,8 +38,8 @@ def armed_callback(vehicle, attribute, value): vehicle.add_attribute_listener('armed', armed_callback) vehicle.add_attribute_listener('armed', armed_callback) - # Disarm and see update. - vehicle.armed = False + # arm and see update. + vehicle.armed = True # Wait for ACK. time.sleep(3) @@ -51,8 +55,8 @@ def armed_callback(vehicle, attribute, value): vehicle.remove_attribute_listener('armed', armed_callback) callcount = armed_callback.called - # Re-arm and see update. - vehicle.armed = True + # Disarm and see update. + vehicle.armed = False # Wait for ack time.sleep(3) From f3ad25ee1ee5bddc0c4ea676e8d503e7f5a45c31 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 11 Nov 2015 17:10:35 +1100 Subject: [PATCH 181/475] Updates to docs now observers may be cached ... or not --- docs/examples/create_attribute.rst | 21 +++++++-- docs/examples/vehicle_state.rst | 9 ++-- docs/guide/migrating.rst | 19 +++++++-- docs/guide/vehicle_state_and_parameters.rst | 34 +++++++++------ dronekit/lib/__init__.py | 47 ++++++++++++++++----- examples/create_attribute/my_vehicle.py | 2 + examples/vehicle_state/vehicle_state.py | 21 ++++----- 7 files changed, 109 insertions(+), 44 deletions(-) diff --git a/docs/examples/create_attribute.rst b/docs/examples/create_attribute.rst index d6e75eae3..dd65c5458 100644 --- a/docs/examples/create_attribute.rst +++ b/docs/examples/create_attribute.rst @@ -155,9 +155,8 @@ decorator. The listener is called for messages that contain the string "RAW_IMU" with arguments for the vehicle, message name, and the message. It copies the message information into the attribute and then notifies all observers. - .. code-block:: python - :emphasize-lines: 6, 9-10, 30 + :emphasize-lines: 6, 9-10, 32 class MyVehicle(Vehicle): def __init__(self, *args): @@ -188,12 +187,28 @@ the attribute and then notifies all observers. self._raw_imu.zmag=message.zmag # Notify all observers of new message (with new value) + # Note that argument `cache=False` by default so listeners + # are updaed with every new message self.notify_attribute_listeners('raw_imu', self._raw_imu) @property def raw_imu(self): return self._raw_imu - + + +.. note:: + + The notifier function (:py:func:`Vehicle.notify_attribute_listeners() `) + should be called every time there is an update from the vehicle. + + You can set a third parameter (``cache=True``) so that it only invokes the listeners when the value *changes*. + This is normally used for vehicle state information like ``Vehicle.mode``, where the value is updated + regularly from the vehicle client code is only interested in attribute changes. + + You should not set ``cache=True`` for attributes that represent sensor information or other "live" information, including + the RAW_IMU attribute demonstrated here. Clients can then implement their own caching strategy if needed. + + At the end of the class we create the public properly ``raw_imu`` which client code may read and observe. .. note:: diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index 3e0d4b136..def80e622 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -97,10 +97,13 @@ On the command prompt you should see (something like): CALLBACK: Mode changed to VehicleMode:STABILIZE Remove Vehicle.mode observer - Add attribute callback/observer `mode` attribute using decorator - Set mode=GUIDED (currently: STABILIZE) + Add attribute callback/observer on `attitude` attribute using decorator Wait 2s so callback invoked before observer removed - CALLBACK: Mode changed to VehicleMode:GUIDED + CALLBACK: Location changed to Attitude:pitch=0.0062674083747,yaw=-0.0318436846137,roll=-0.00923461187631 + CALLBACK: Location changed to Attitude:pitch=0.00625518895686,yaw=-0.0317140743136,roll=-0.0091759338975 + ... + CALLBACK: Location changed to Attitude:pitch=0.00629614247009,yaw=-0.0343224518001,roll=-0.0108289364725 + CALLBACK: Location changed to Attitude:pitch=0.00636938679963,yaw=-0.0352342799306,roll=-0.01096534729 Attempt to remove observer added with `on_attribute` decorator (should fail) Exception: Cannot add observer added using decorator diff --git a/docs/guide/migrating.rst b/docs/guide/migrating.rst index 23a5c13ec..8550edd9d 100644 --- a/docs/guide/migrating.rst +++ b/docs/guide/migrating.rst @@ -196,8 +196,21 @@ the vehicle. The difference between :py:func:`Vehicle.add_attribute_listener() ` and :py:func:`Vehicle.on_attribute() ` is that attribute listeners added using -:py:func:`Vehicle.on_attribute() ` cannot be removed (but ``on_attribute()`` does have -a more elegant syntax). +:py:func:`Vehicle.on_attribute() ` cannot be removed (while ``on_attribute()`` +has a more elegant syntax). + +A few attributes have been modified so that they only notify when the value changes: +:py:func:`Vehicle.system_status `, +:py:attr:`Vehicle.armed `, and +:py:attr:`Vehicle.mode `. Users no longer need to add caching code +for these attributes in their listeners. +Attributes that provide "streams" of information (i.e. sensor output) remain unchanged. + +.. note:: + + If you're :ref:`creating your own attributes ` this caching is trivially + provided using the ``cache=True`` argument to + :py:func:`Vehicle.notify_attribute_listeners() `. See :ref:`vehicle_state_observe_attributes` for more information. @@ -220,7 +233,7 @@ decorator, which allows you to specify a callback function that will be invoked The API also adds :py:func:`Vehicle.add_message_listener() ` and :py:func:`Vehicle.remove_message_listener() `. These can be used instead of :py:func:`Vehicle.on_message() ` when you need to be - able to *remove* an added listener. + able to *remove* an added listener. Typically you won't need to! See :ref:`mavlink_messages` for more information. diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index 181be2b41..3d5ed6816 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -21,7 +21,8 @@ Attributes Vehicle state information is exposed through vehicle *attributes*. DroneKit-Python currently supports the following "standard" attributes: -:py:attr:`Vehicle.location `, +:py:attr:`Vehicle.location.global_frame `, +:py:attr:`Vehicle.location.local_frame `, :py:attr:`Vehicle.attitude `, :py:attr:`Vehicle.velocity `, :py:attr:`Vehicle.airspeed `, @@ -41,12 +42,14 @@ Vehicle state information is exposed through vehicle *attributes*. DroneKit-Pyth Attributes are initially created with ``None`` values for their members. In most cases the members are populated (and repopulated) as new MAVLink messages of the associated types are received from the vehicle. -All of the attributes can be :ref:`read ` and :ref:`observed `, +All of the attributes can be :ref:`read `, but only the :py:attr:`Vehicle.home_location `, :py:attr:`Vehicle.mode ` and :py:attr:`Vehicle.armed ` status can be :ref:`written `. +Almost all of the attributes can be :ref:`observed `. + The behaviour of :py:attr:`Vehicle.home_location ` is different from the other attributes, and is :ref:`discussed in its own section below `. @@ -106,7 +109,7 @@ Setting attributes ------------------ Only the :py:attr:`Vehicle.mode ` and :py:attr:`Vehicle.armed ` -attributes can be written. +attributes can be written (``Vehicle.home_location`` is a special case, as :ref:`discussed below `). The attributes are set by assigning a value: @@ -143,11 +146,16 @@ to confirm they have changed before proceeding. Observing attribute changes --------------------------- -You can observe any of the attributes (except for :py:attr:`Vehicle.home_location ` and -:py:attr:`Vehicle.parameters `) and will receive notification every time a value is received -from the connected vehicle. This allows you to monitor changes to velocity and other vehicle state without the need for polling. +You can observe any of the vehicle attributes and monitor for changes without the need for polling. + +Listeners ("observer callback functions") are invoked differently based on the *type of observed attribute*. Attributes that represent sensor values or other +"streams of information" are updated whenever a message is received from the vehicle. Attributes which reflect vehicle +"state" are only updated when their values change (for example +:py:func:`Vehicle.system_status `, +:py:attr:`Vehicle.armed `, and +:py:attr:`Vehicle.mode `). -Observers are added using :py:func:`Vehicle.add_attribute_listener() ` or the +Callbacks are added using :py:func:`Vehicle.add_attribute_listener() ` or the :py:func:`Vehicle.on_attribute() ` decorator method. The main difference between these methods is that only attribute callbacks added with :py:func:`Vehicle.add_attribute_listener() ` can be removed (see :py:func:`remove_attribute_listener() `). @@ -185,18 +193,13 @@ callback is first run. vehicle.remove_message_listener('location', location_callback) -Callbacks are triggered every time a message is received from the vehicle (whether or not the observed attribute changes). -Callback code may therefore choose to cache the result and only report changes. - The example below shows how you can declare an attribute callback using the -:py:func:`Vehicle.on_attribute() ` decorator function. This stores the result of the -previous callback and only prints the output when there is a signficant change in :py:attr:`Vehicle.rangefinder `. +:py:func:`Vehicle.on_attribute() ` decorator function. .. code-block:: python :emphasize-lines: 3,4 - last_rangefinder_distance=0 @vehicle.on_attribute('rangefinder') @@ -208,6 +211,11 @@ previous callback and only prints the output when there is a signficant change i last_rangefinder_distance = round(self.rangefinder.distance, 1) print " Rangefinder (metres): %s" % last_rangefinder_distance +.. note:: + + The fragment above stores the result of the previous callback and only prints the output when there is a + signficant change in :py:attr:`Vehicle.rangefinder `. You might want to + perform caching like this to ignore updates that are not significant to your code. The examples above show how you can monitor a single attribute. You can pass the special name ('``*``') to specify a callback that will be called for any/all attribute changes: diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 132163efd..efd342b41 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -303,9 +303,13 @@ def add_attribute_listener(self, attr_name, observer): """ Add an attribute listener callback. - The callback function (``observer``) is invoked every time the associated attribute is updated - from the vehicle (the attribute value may not have *changed*). The callback can be removed - using :py:func:`remove_attribute_listener`. + The callback function (``observer``) is invoked differently depending on the *type of attribute*. + Attributes that represent sensor values or which are used to monitor connection status are updated + whenever a message is received from the vehicle. Attributes which reflect vehicle "state" are + only updated when their values change (for example :py:func:`Vehicle.system_status `, + :py:attr:`Vehicle.armed `, and :py:attr:`Vehicle.mode `). + + The callback can be removed using :py:func:`remove_attribute_listener`. .. note:: @@ -332,6 +336,8 @@ def location_callback(self, attr_name, msg): #Add observer for the vehicle's current location vehicle.add_attribute_listener('global_frame', location_callback) + See :ref:`vehicle_state_observe_attributes` for more information. + :param String attr_name: The name of the attribute to watch (or '*' to watch all attributes). :param observer: The callback to invoke when a change in the attribute is detected. @@ -353,6 +359,8 @@ def remove_attribute_listener(self, attr_name, observer): .. code:: python vehicle.remove_attribute_listener('global_frame', location_callback) + + See :ref:`vehicle_state_observe_attributes` for more information. :param String attr_name: The attribute name that is to have an observer removed (or '*' to remove an 'all attribute' observer). :param observer: The callback function to remove. @@ -367,16 +375,24 @@ def remove_attribute_listener(self, attr_name, observer): def notify_attribute_listeners(self, attr_name, value, cache=False): """ - This method calls attribute observers when the named attribute has changed. + This method is used to update attribute observers when the named attribute is updated. - It should be called in message listeners after updating an attribute with new information - from the vehicle. + You should call it in your message listeners after updating an attribute with + information from a vehicle message. - If ``cache`` is true, if the attribute's value has not changed since the last - invocation, its listeners are not invoked. + By default the value of ``cache`` is ``False`` and every update from the vehicle is sent to listeners + (whether or not the attribute has changed). This is appropriate for attributes which represent sensor + or heartbeat-type monitoring. + + Set ``cache=True`` to update listeners only when the value actually changes (cache the previous + attribute value). This should be used where clients will only ever need to know the value when it has + changed. For example, this setting has been used for notifying :py:attr:`mode` changes. + + See :ref:`example_create_attribute` for more information. :param String attr_name: The name of the attribute that has been updated. :param value: The current value of the attribute that has been updated. + :param Boolean cache: Set ``True`` to only notify observers when the attribute value changes. """ # Cached values are not re-sent if they are unchanged. if cache: @@ -394,8 +410,11 @@ def on_attribute(self, name): """ Decorator for attribute listeners. - The decorated ``observer`` callback function is invoked every time the associated attribute is updated - from the vehicle (the attribute value may not have *changed*). + The decorated function (``observer``) is invoked differently depending on the *type of attribute*. + Attributes that represent sensor values or which are used to monitor connection status are updated + whenever a message is received from the vehicle. Attributes which reflect vehicle "state" are + only updated when their values change (for example :py:func:`Vehicle.system_status `, + :py:attr:`Vehicle.armed `, and :py:attr:`Vehicle.mode `). The callback arguments are: @@ -418,6 +437,8 @@ def on_attribute(self, name): @vehicle.on_attribute('attitude') def attitude_listener(self, name, msg): print '%s attribute is: %s' % (name, msg) + + See :ref:`vehicle_state_observe_attributes` for more information. :param String attr_name: The name of the attribute to watch (or '*' to watch all attributes). :param observer: The callback to invoke when a change in the attribute is detected. @@ -1023,6 +1044,8 @@ def on_message(self, name): def my_method(self, name, msg): pass + See :ref:`mavlink_messages` for more information. + :param String name: The name of the message to be intercepted by the decorated listener function (or '*' to get all messages). """ def decorator(fn): @@ -1059,6 +1082,8 @@ def my_method(self, name, msg): pass vehicle.add_message_listener('HEARTBEAT',my_method) + + See :ref:`mavlink_messages` for more information. :param String name: The name of the message to be intercepted by the listener function (or '*' to get all messages). :param fn: The listener function that will be called if a message is received. @@ -1073,6 +1098,8 @@ def remove_message_listener(self, name, fn): """ Removes a message listener (that was previously added using :py:func:`add_message_listener`). + See :ref:`mavlink_messages` for more information. + :param String name: The name of the message for which the listener is to be removed (or '*' to remove an 'all messages' observer). :param fn: The listener callback function to remove. diff --git a/examples/create_attribute/my_vehicle.py b/examples/create_attribute/my_vehicle.py index 4570d1cdf..6a1b31c99 100644 --- a/examples/create_attribute/my_vehicle.py +++ b/examples/create_attribute/my_vehicle.py @@ -76,6 +76,8 @@ def listener(self, name, message): self._raw_imu.zmag=message.zmag # Notify all observers of new message (with new value) + # Note that argument `cache=False` by default so listeners + # are updaed with every new message self.notify_attribute_listeners('raw_imu', self._raw_imu) @property diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 9f8c92f1d..17cc9cc43 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -124,24 +124,21 @@ def mode_callback(self, attr_name, value): -# Add mode attribute callback using decorator (callbacks added this way cannot be removed). -print "\nAdd attribute callback/observer `mode` attribute using decorator" -last_published_mode='' -@vehicle.on_attribute('mode') -def mode_decorated_callback(self, attr_name, value): +# Add attitude attribute callback using decorator (callbacks added this way cannot be removed). +print "\nAdd attribute callback/observer on `attitude` attribute using decorator" +last_attitude_cache=None +@vehicle.on_attribute('attitude') +def decorated_attitude_callback(self, attr_name, value): # `attr_name` - the observed attribute (used if callback is used for multiple attributes) # `self` - the associated vehicle object (used if a callback is different for multiple vehicles) # `value` is the updated attribute value. - global last_published_mode + global last_attitude_cache # Only publish when mode changes - if value!=last_published_mode: - print " CALLBACK: Mode changed to", value - last_published_mode=value + if value!=last_attitude_cache: + print " CALLBACK: Location changed to", value + last_attitude_cache=value -print " Set mode=GUIDED (currently: %s)" % vehicle.mode.name -vehicle.mode = VehicleMode("GUIDED") - print " Wait 2s so callback invoked before observer removed" time.sleep(2) From 5859b833b1ceaa9cbcd4d61bd963c8935460fd0a Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 11 Nov 2015 20:49:22 +1100 Subject: [PATCH 182/475] Fix typos in example --- examples/vehicle_state/vehicle_state.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 17cc9cc43..e2aa7102b 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -133,9 +133,9 @@ def decorated_attitude_callback(self, attr_name, value): # `self` - the associated vehicle object (used if a callback is different for multiple vehicles) # `value` is the updated attribute value. global last_attitude_cache - # Only publish when mode changes + # Only publish when value changes if value!=last_attitude_cache: - print " CALLBACK: Location changed to", value + print " CALLBACK: Attitude changed to", value last_attitude_cache=value @@ -144,9 +144,9 @@ def decorated_attitude_callback(self, attr_name, value): print "\n Attempt to remove observer added with `on_attribute` decorator (should fail)" try: - vehicle.remove_attribute_listener('mode', mode_decorated_callback) + vehicle.remove_attribute_listener('mode', decorated_attitude_callback) except: - print " Exception: Cannot add observer added using decorator" + print " Exception: Cannot remove observer added using decorator" From c0ddb13acaad23e30990b7c80bf0001c45b1892a Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 10 Nov 2015 19:54:07 -0800 Subject: [PATCH 183/475] Adds smarter error notification when errors occur. --- dronekit/__init__.py | 17 ++++++++++++----- dronekit/lib/__init__.py | 8 ++++---- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 0cb6de4cb..f2b168b81 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -6,6 +6,7 @@ import platform import re import dronekit.lib +from dronekit.lib import APIException from dronekit.util import errprinter from pymavlink import mavutil, mavwp from Queue import Queue, Empty @@ -60,6 +61,7 @@ def __init__(self, master, vehicle_class=Vehicle): # Debug flag. self._accept_input = True self._alive = True + self._death_error = None import atexit def onexit(): @@ -85,8 +87,7 @@ def mavlink_thread(): except socket.error as error: # If connection reset (closed), stop polling. if error.errno == ECONNABORTED: - errprinter('>>> connection aborted during read') - return + raise APIException('Connection aborting during read') raise except Empty: break @@ -100,8 +101,7 @@ def mavlink_thread(): except socket.error as error: # If connection reset (closed), stop polling. if error.errno == ECONNABORTED: - errprinter('>>> connection aborting during send') - return + raise APIException('Connection aborting during send') raise except Exception as e: # TODO this should be more rigorous. How to avoid @@ -116,6 +116,13 @@ def mavlink_thread(): for fn in self.message_listeners: fn(self, msg) + except APIException as e: + errprinter('>>> ' + str(e.message)) + self._alive = False + self.master.close() + self._death_error = e + return + except Exception as e: # http://bugs.python.org/issue1856 if not self._alive: @@ -123,7 +130,7 @@ def mavlink_thread(): else: self._alive = False self.master.close() - raise + self._death_error = e t = Thread(target=mavlink_thread) t.daemon = True diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index efd342b41..b7fff66d6 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -70,11 +70,11 @@ class APIException(Exception): """ Base class for DroneKit related exceptions. - :param String msg: Message string describing the exception + :param String message: Message string describing the exception """ - def __init__(self, msg): - self.msg = msg + def __init__(self, message): + super(APIException, self).__init__(message) class Attitude(object): """ @@ -1005,7 +1005,7 @@ def listener(_): # Timeouts. if self._heartbeat_started: if self._heartbeat_error and self._heartbeat_error > 0 and time.time() - self._heartbeat_lastreceived > self._heartbeat_error: - raise Exception('>>> No heartbeat in %s seconds, aborting.' % self._heartbeat_error) + raise APIException('No heartbeat in %s seconds, aborting.' % self._heartbeat_error) elif time.time() - self._heartbeat_lastreceived > self._heartbeat_warning: if self._heartbeat_timeout == False: errprinter('>>> Link timeout, no heartbeat in last %s seconds' % self._heartbeat_warning) From 1ea2032a5d6ce784306712cec442364e1137075f Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 9 Nov 2015 16:52:13 -0800 Subject: [PATCH 184/475] Allows parameters to be iterated over. --- dronekit/lib/__init__.py | 12 +++++++++++- dronekit/test/sitl/test_parameters.py | 12 ++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index b7fff66d6..be1a46650 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -60,6 +60,7 @@ import threading, time, math, copy import CloudClient +import collections from pymavlink.dialects.v10 import ardupilotmega from pymavlink import mavutil, mavwp from dronekit.util import errprinter @@ -1484,7 +1485,7 @@ def wait_ready(self, *types, **kwargs): return True -class Parameters(HasObservers): +class Parameters(collections.MutableMapping, HasObservers): """ This object is used to get and set the values of named parameters for a vehicle. See the following links for information about the supported parameters for each platform: `Copter `_, @@ -1522,6 +1523,15 @@ def __setitem__(self, name, value): self.wait_ready() self.set(name, value) + def __delitem__(self, name): + raise APIException('Cannot delete value from parameters list.') + + def __len__(self): + return len(self._vehicle._params_map) + + def __iter__(self): + return self._vehicle._params_map.__iter__() + def get(self, name, wait_ready=True): if wait_ready: self.wait_ready() diff --git a/dronekit/test/sitl/test_parameters.py b/dronekit/test/sitl/test_parameters.py index 9cea8b856..2e966a3fd 100644 --- a/dronekit/test/sitl/test_parameters.py +++ b/dronekit/test/sitl/test_parameters.py @@ -24,3 +24,15 @@ def test_parameters(connpath): assert_equals(vehicle.parameters.get('xXx_extreme_garbage_value_xXx', wait_ready=True), None) vehicle.close() + +@with_sitl +def test_parameters(connpath): + vehicle = connect(connpath, wait_ready=True) + + # Iterate over parameters. + for k, v in vehicle.parameters.iteritems(): + break + for value in vehicle.parameters: + break + + vehicle.close() From a3dad03934bbedcc53f732e29ba6693ea4262659 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 9 Nov 2015 17:01:45 -0800 Subject: [PATCH 185/475] Enables vehicle.parameters to be observed. --- dronekit/lib/__init__.py | 16 ++++++++------- dronekit/test/sitl/test_parameters.py | 28 +++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index be1a46650..61b440408 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -292,7 +292,7 @@ def __ne__(self, other): class HasObservers(object): def __init__(self): # A mapping from attr_name to a list of observers - self.__observers = {} + self._attribute_listeners = {} self._attribute_cache = {} """ @@ -343,10 +343,10 @@ def location_callback(self, attr_name, msg): :param observer: The callback to invoke when a change in the attribute is detected. """ - l = self.__observers.get(attr_name) + l = self._attribute_listeners.get(attr_name) if l is None: l = [] - self.__observers[attr_name] = l + self._attribute_listeners[attr_name] = l if not observer in l: l.append(observer) @@ -367,11 +367,11 @@ def remove_attribute_listener(self, attr_name, observer): :param observer: The callback function to remove. """ - l = self.__observers.get(attr_name) + l = self._attribute_listeners.get(attr_name) if l is not None: l.remove(observer) if len(l) == 0: - del self.__observers[attr_name] + del self._attribute_listeners[attr_name] def notify_attribute_listeners(self, attr_name, value, cache=False): @@ -402,9 +402,9 @@ def notify_attribute_listeners(self, attr_name, value, cache=False): self._attribute_cache[attr_name] = value # Notify observers. - for fn in self.__observers.get(attr_name, []): + for fn in self._attribute_listeners.get(attr_name, []): fn(self, attr_name, value) - for fn in self.__observers.get('*', []): + for fn in self._attribute_listeners.get('*', []): fn(self, attr_name, value) def on_attribute(self, name): @@ -982,6 +982,7 @@ def listener(self, name, msg): self._params_duration = start_duration self._params_set[msg.param_index] = msg self._params_map[msg.param_id] = msg.param_value + self._parameters.notify_attribute_listeners(msg.param_id, msg.param_value) except: import traceback traceback.print_exc() @@ -1513,6 +1514,7 @@ class Parameters(collections.MutableMapping, HasObservers): """ def __init__(self, vehicle): + super(Parameters, self).__init__() self._vehicle = vehicle def __getitem__(self, name): diff --git a/dronekit/test/sitl/test_parameters.py b/dronekit/test/sitl/test_parameters.py index 2e966a3fd..c1c74f0e6 100644 --- a/dronekit/test/sitl/test_parameters.py +++ b/dronekit/test/sitl/test_parameters.py @@ -26,13 +26,37 @@ def test_parameters(connpath): vehicle.close() @with_sitl -def test_parameters(connpath): +def test_iterating(connpath): vehicle = connect(connpath, wait_ready=True) # Iterate over parameters. for k, v in vehicle.parameters.iteritems(): break - for value in vehicle.parameters: + for key in vehicle.parameters: break vehicle.close() + +@with_sitl +def test_setting(connpath): + vehicle = connect(connpath, wait_ready=True) + + assert_not_equals(vehicle.parameters['THR_MIN'], None) + + result = { 'success': False } + + @vehicle.parameters.on_attribute('THR_MIN') + def listener(self, name, value): + result['success'] = name == 'THR_MIN' and value == 3.000 + + vehicle.parameters['THR_MIN'] = 3.000 + + # Wait a bit. + i = 5 + while not result['success'] and i > 0: + time.sleep(1) + i = i - 1 + + assert_equals(result['success'], True) + + vehicle.close() From 06446d27c694e2f91a4f4a1ed8fb764680d37408 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 11 Nov 2015 11:41:09 -0800 Subject: [PATCH 186/475] Makes parameters case-insensitive. --- dronekit/lib/__init__.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 61b440408..09aaad750 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1518,10 +1518,12 @@ def __init__(self, vehicle): self._vehicle = vehicle def __getitem__(self, name): + name = name.upper() self.wait_ready() return self._vehicle._params_map[name] def __setitem__(self, name, value): + name = name.upper() self.wait_ready() self.set(name, value) @@ -1535,6 +1537,7 @@ def __iter__(self): return self._vehicle._params_map.__iter__() def get(self, name, wait_ready=True): + name = name.upper() if wait_ready: self.wait_ready() return self._vehicle._params_map.get(name, None) @@ -1553,7 +1556,7 @@ def set(self, name, value, retries=3, wait_ready=False): success = False remaining = retries while True: - self._vehicle._master.param_set_send(name.upper(), value) + self._vehicle._master.param_set_send(name, value) tstart = time.time() if remaining == 0: break @@ -1573,6 +1576,22 @@ def wait_ready(self, **kwargs): """ self._vehicle.wait_ready('parameters', **kwargs) + def add_attribute_listener(self, attr_name, observer): + attr_name = attr_name.upper() + return super(Parameters, self).add_attribute_listener(attr_name, observer) + + def remove_attribute_listener(self, attr_name, observer): + attr_name = attr_name.upper() + return super(Parameters, self).add_attribute_listener(attr_name, observer) + + def notify_attribute_listeners(self, attr_name, value): + attr_name = attr_name.upper() + return super(Parameters, self).add_attribute_listener(attr_name, value) + + def on_attribute(self, name): + attr_name = attr_name.upper() + return super(Parameters, self).on_attribute(attr_name) + class Command(mavutil.mavlink.MAVLink_mission_item_message): """ A waypoint object. From dad2676efc9617b198916b9724879a3cbb460630 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 11 Nov 2015 11:42:28 -0800 Subject: [PATCH 187/475] Caches parameters notifications. --- dronekit/lib/__init__.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 09aaad750..34b7f1268 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -982,7 +982,7 @@ def listener(self, name, msg): self._params_duration = start_duration self._params_set[msg.param_index] = msg self._params_map[msg.param_id] = msg.param_value - self._parameters.notify_attribute_listeners(msg.param_id, msg.param_value) + self._parameters.notify_attribute_listeners(msg.param_id, msg.param_value, cache=True) except: import traceback traceback.print_exc() @@ -1576,21 +1576,21 @@ def wait_ready(self, **kwargs): """ self._vehicle.wait_ready('parameters', **kwargs) - def add_attribute_listener(self, attr_name, observer): + def add_attribute_listener(self, attr_name, *args, **kwargs): attr_name = attr_name.upper() - return super(Parameters, self).add_attribute_listener(attr_name, observer) + return super(Parameters, self).add_attribute_listener(attr_name, *args, **kwargs) - def remove_attribute_listener(self, attr_name, observer): + def remove_attribute_listener(self, attr_name, *args, **kwargs): attr_name = attr_name.upper() - return super(Parameters, self).add_attribute_listener(attr_name, observer) + return super(Parameters, self).remove_attribute_listener(attr_name, *args, **kwargs) - def notify_attribute_listeners(self, attr_name, value): + def notify_attribute_listeners(self, attr_name, *args, **kwargs): attr_name = attr_name.upper() - return super(Parameters, self).add_attribute_listener(attr_name, value) + return super(Parameters, self).notify_attribute_listeners(attr_name, *args, **kwargs) - def on_attribute(self, name): + def on_attribute(self, attr_name, *args, **kwargs): attr_name = attr_name.upper() - return super(Parameters, self).on_attribute(attr_name) + return super(Parameters, self).on_attribute(attr_name, *args, **kwargs) class Command(mavutil.mavlink.MAVLink_mission_item_message): """ From d1919d5eda68f4e7977fae2e98483de24e8f9e45 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 6 Nov 2015 17:33:54 -0800 Subject: [PATCH 188/475] Prevents division error in battery instantiation. --- dronekit/lib/__init__.py | 2 ++ dronekit/test/sitl/test_298.py | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 dronekit/test/sitl/test_298.py diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 34b7f1268..a21da8c92 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1166,6 +1166,8 @@ def location(self): @property def battery(self): + if not (self._voltage and self._current and self._level): + return None return Battery(self._voltage, self._current, self._level) @property diff --git a/dronekit/test/sitl/test_298.py b/dronekit/test/sitl/test_298.py new file mode 100644 index 000000000..5a1434a3a --- /dev/null +++ b/dronekit/test/sitl/test_298.py @@ -0,0 +1,23 @@ +import time +import sys +import os +import socket +from dronekit import connect, VehicleMode +from dronekit.test import with_sitl +from nose.tools import assert_equals + +@with_sitl +def test_battery_none(connpath): + vehicle = connect(connpath) + + # Ensure we can get (possibly unpopulated) battery object without throwing error. + b1 = vehicle.battery + + vehicle.wait_ready('battery') + + # Ensure we can get battery object without throwing error. + b2 = vehicle.battery + + assert b1 == b2 or b1 == None + + vehicle.close() From 10e76ce81be071d72d79f7554d15f5173189c8ad Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 11 Nov 2015 13:39:09 -0800 Subject: [PATCH 189/475] Fixes battery test, fixes battery bug! --- dronekit/__init__.py | 5 +++-- dronekit/lib/__init__.py | 4 ++-- .../test/sitl/{test_298.py => test_earlyattrs.py} | 13 ++++++------- 3 files changed, 11 insertions(+), 11 deletions(-) rename dronekit/test/sitl/{test_298.py => test_earlyattrs.py} (63%) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index f2b168b81..edc20d7e2 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -177,7 +177,7 @@ def close(self): time.sleep(0.1) self.master.close() -def connect(ip, wait_ready=None, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200, heartbeat_timeout=30): +def connect(ip, _initialize=True, wait_ready=None, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200, heartbeat_timeout=30): handler = MAVHandler(mavutil.mavlink_connection(ip, baud=baud)) vehicle = vehicle_class(handler) @@ -186,7 +186,8 @@ def connect(ip, wait_ready=None, status_printer=errprinter, vehicle_class=Vehicl def listener(self, name, m): status_printer(re.sub(r'(^|\n)', '>>> ', m.text.rstrip())) - vehicle.initialize(rate=rate, heartbeat_timeout=heartbeat_timeout) + if _initialize: + vehicle.initialize(rate=rate, heartbeat_timeout=heartbeat_timeout) if wait_ready: if wait_ready == True: diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index a21da8c92..0de03a721 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1166,7 +1166,7 @@ def location(self): @property def battery(self): - if not (self._voltage and self._current and self._level): + if self._voltage == None or self._current == None or self._level == None: return None return Battery(self._voltage, self._current, self._level) @@ -1426,7 +1426,7 @@ def message_factory(self): """ return self._master.mav - def initialize(self, wait_ready=False, rate=None, heartbeat_timeout=30): + def initialize(self, rate=4, heartbeat_timeout=30): self._handler.start() # Start heartbeat polling. diff --git a/dronekit/test/sitl/test_298.py b/dronekit/test/sitl/test_earlyattrs.py similarity index 63% rename from dronekit/test/sitl/test_298.py rename to dronekit/test/sitl/test_earlyattrs.py index 5a1434a3a..febd08fbe 100644 --- a/dronekit/test/sitl/test_298.py +++ b/dronekit/test/sitl/test_earlyattrs.py @@ -4,20 +4,19 @@ import socket from dronekit import connect, VehicleMode from dronekit.test import with_sitl -from nose.tools import assert_equals +from nose.tools import assert_equals, assert_not_equals @with_sitl def test_battery_none(connpath): - vehicle = connect(connpath) + vehicle = connect(connpath, _initialize=False) # Ensure we can get (possibly unpopulated) battery object without throwing error. - b1 = vehicle.battery + assert_equals(vehicle.battery, None) - vehicle.wait_ready('battery') + vehicle.initialize() # Ensure we can get battery object without throwing error. - b2 = vehicle.battery - - assert b1 == b2 or b1 == None + vehicle.wait_ready('battery') + assert_not_equals(vehicle.battery, None) vehicle.close() From 041a7097b053164e39334514471c1d0986fbbb7e Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 11 Nov 2015 13:39:48 -0800 Subject: [PATCH 190/475] Removes excess print statements from test_channels. --- dronekit/test/sitl/test_channels.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dronekit/test/sitl/test_channels.py b/dronekit/test/sitl/test_channels.py index 04dc4e04f..0df00ac6a 100644 --- a/dronekit/test/sitl/test_channels.py +++ b/dronekit/test/sitl/test_channels.py @@ -65,13 +65,13 @@ def test_timeout(connpath): #test try: - print "Ch9: %s" % vehicle.channels['9'] + vehicle.channels['9'] assert False, "Can read over end of channels" except: pass try: - print "Ch0: %s" % vehicle.channels['0'] + vehicle.channels['0'] assert False, "Can read over start of channels" except: pass @@ -141,7 +141,6 @@ def test_timeout(connpath): result = {'success': False} vehicle.channels.overrides = {} def channels_callback(vehicle, name, channels): - print(channels['3']) if channels['3'] == 55: result['success'] = True vehicle.add_attribute_listener('channels', channels_callback) From b543d6acdb222e4bf28aae8e937f8f33e190f118 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 9 Nov 2015 15:53:28 -0800 Subject: [PATCH 191/475] Fixes drone delivery example to start on other thread. --- examples/drone_delivery/drone_delivery.py | 139 +++++++++++++++------- 1 file changed, 95 insertions(+), 44 deletions(-) diff --git a/examples/drone_delivery/drone_delivery.py b/examples/drone_delivery/drone_delivery.py index 91a329ca3..56ac57192 100644 --- a/examples/drone_delivery/drone_delivery.py +++ b/examples/drone_delivery/drone_delivery.py @@ -5,19 +5,16 @@ Full documentation is provided at http://python.dronekit.io/examples/drone_delivery.html """ -import os, os.path -import simplejson +import os +import simplejson +import time from pymavlink import mavutil -import dronekit.lib -from dronekit import connect -from dronekit.lib import VehicleMode, LocationGlobal - +from dronekit import connect, VehicleMode, LocationGlobal import cherrypy from cherrypy.process import wspbus, plugins from jinja2 import Environment, FileSystemLoader - #Set up option parsing to get connection string import argparse parser = argparse.ArgumentParser(description='Print out vehicle state information. Connects to SITL on local PC by default.') @@ -31,7 +28,6 @@ print "local path: %s" % local_path - cherrypy_conf = { '/': { 'tools.sessions.on': True, @@ -43,14 +39,53 @@ } } + +def arm_and_takeoff(aTargetAltitude): + """ + Arms vehicle and fly to aTargetAltitude. + """ + + print "Basic pre-arm checks" + # Don't let the user try to fly autopilot is booting + if vehicle.mode.name == "INITIALISING": + print "Waiting for vehicle to initialise" + time.sleep(1) + while vehicle.gps_0.fix_type < 2: + print "Waiting for GPS...:", vehicle.gps_0.fix_type + time.sleep(1) + + print "Arming motors" + # Copter should arm in GUIDED mode + vehicle.mode = VehicleMode("GUIDED") + vehicle.armed = True + vehicle.flush() + + while not vehicle.armed: + print " Waiting for arming..." + time.sleep(1) + + print "Taking off!" + vehicle.commands.takeoff(aTargetAltitude) # Take off to target altitude + vehicle.flush() + + # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command + # after Vehicle.commands.takeoff will execute immediately). + while True: + print " Altitude: ", vehicle.location.alt + if vehicle.location.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. + print "Reached target altitude" + break; + time.sleep(1) + class Drone(object): def __init__(self, home_coords, server_enabled=True): + self.gps_lock = False + self.altitude = 30.0 + # Connect to the Vehicle print 'Connecting to vehicle on: %s' % args.connect - self.vehicle = connect(args.connect, wait_ready=True) + self.vehicle = vehicle print "connected ..." - self.gps_lock = False - self.altitude = 30.0 self.commands = self.vehicle.commands self.current_coords = [] self.home_coords = home_coords @@ -60,28 +95,40 @@ def __init__(self, home_coords, server_enabled=True): # Register observers self.vehicle.add_attribute_listener('armed', self.armed_callback) self.vehicle.add_attribute_listener('location', self.location_callback) - #self.vehicle.add_attribute_listener('mode', self.mode_callback) self.vehicle.add_attribute_listener('gps_0', self.gps_callback) self._log("Waiting for GPS Lock") - def takeoff(self): - self._log("Taking off") - self.commands.takeoff(30.0) + def launch(self): + while not self.gps_lock: + time.sleep(1) - def arm(self): - self._log("Arming") - self.vehicle.armed = True - - def run(self): self._log('Running initial boot sequence') + self.change_mode('GUIDED') + time.sleep(5) # EKF warmup self.arm() self.takeoff() - self.change_mode('GUIDED') if self.webserver_enabled is True: self._run_server() + def takeoff(self): + self._log("Taking off") + self.commands.takeoff(30.0) + self.vehicle.flush() + + def arm(self, value=True): + if value: + self._log("Arming") + self.vehicle.armed = True + while not self.vehicle.armed: + print " Waiting for arming..." + print " Mode: %s" % self.vehicle.mode.name + time.sleep(1) + else: + self._log("Disarming") + self.vehicle.armed = False + def _run_server(self): # Start web server if enabled cherrypy.tree.mount(DroneDelivery(self), '/', config=cherrypy_conf) @@ -92,48 +139,52 @@ def _run_server(self): 'log.screen': None }) + print 'http://localhost:8080/' cherrypy.engine.start() def change_mode(self, mode): self._log("Mode: {0}".format(mode)) - self.vehicle.mode = VehicleMode(mode) + self.vehicle.mode = VehicleMode(mode) + while self.vehicle.mode.name != mode: + print " Waiting for mode change ... (%s)" % self.vehicle.mode.name + print " Mode: {0}".format(mode) + self.vehicle.mode = VehicleMode(mode) + time.sleep(1) def goto(self, location, relative=None): self._log("Goto: {0}, {1}".format(location, self.altitude)) self.commands.goto( - Location( + LocationGlobal( float(location[0]), float(location[1]), float(self.altitude), is_relative=relative ) ) + self.vehicle.flush() def get_location(self): return [self.current_location.lat, self.current_location.lon] - def location_callback(self, location): - location = self.vehicle.location.global_frame - + def location_callback(self, vehicle, name, location): if location.alt is not None: self.altitude = location.alt self.current_location = location - def armed_callback(self, armed): - self._log("DroneDelivery Armed Callback") - self.vehicle.remove_message_listener('armed', self.armed_callback) - - def mode_callback(self, mode): - self._log("Mode: {0}".format(self.vehicle.mode)) + def armed_callback(self, vehicle, name, armed): + self._log("DroneDelivery Armed Callback: %s" % armed) + self.vehicle.remove_attribute_listener('armed', self.armed_callback) - def gps_callback(self, gps): - self._log("GPS: {0}".format(self.vehicle.gps_0)) - if self.gps_lock is False: - self.gps_lock = True - self.vehicle.remove_message_listener('gps_0', self.gps_callback) - self.run() + def gps_callback(self, vehicle, name, gps): + self._log("GPS: {0}".format(gps)) + if self.vehicle.gps_0.fix_type >= 2: + self.gps_lock = True + self.vehicle.remove_attribute_listener('gps_0', self.gps_callback) + else: + print "Waiting for GPS...:", vehicle.gps_0.fix_type + self.gps_lock = False def _log(self, message): print "[DEBUG]: {0}".format(message) @@ -211,10 +262,10 @@ def track(self, lat=None, lon=None): return self.templates.track(self.drone.get_location()) -Drone([32.5738, -117.0068]) -cherrypy.engine.block() -#Close vehicle object before exiting script -print "Close vehicle object" -vehicle.close() -print("Completed") +# Connect to the Vehicle +print 'Connecting to vehicle on: %s' % args.connect +vehicle = connect(args.connect, wait_ready=True) + +Drone([32.5738, -117.0068]).launch() +cherrypy.engine.block() From 2ef81d4dba608e1980b0002e14b5b9f6d36286cc Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 10 Nov 2015 16:16:18 -0800 Subject: [PATCH 192/475] Improves drone delivery example, also cleanup. --- examples/drone_delivery/drone_delivery.py | 77 +++-------------------- 1 file changed, 9 insertions(+), 68 deletions(-) diff --git a/examples/drone_delivery/drone_delivery.py b/examples/drone_delivery/drone_delivery.py index 56ac57192..70cda418b 100644 --- a/examples/drone_delivery/drone_delivery.py +++ b/examples/drone_delivery/drone_delivery.py @@ -40,52 +40,14 @@ } -def arm_and_takeoff(aTargetAltitude): - """ - Arms vehicle and fly to aTargetAltitude. - """ - - print "Basic pre-arm checks" - # Don't let the user try to fly autopilot is booting - if vehicle.mode.name == "INITIALISING": - print "Waiting for vehicle to initialise" - time.sleep(1) - while vehicle.gps_0.fix_type < 2: - print "Waiting for GPS...:", vehicle.gps_0.fix_type - time.sleep(1) - - print "Arming motors" - # Copter should arm in GUIDED mode - vehicle.mode = VehicleMode("GUIDED") - vehicle.armed = True - vehicle.flush() - - while not vehicle.armed: - print " Waiting for arming..." - time.sleep(1) - - print "Taking off!" - vehicle.commands.takeoff(aTargetAltitude) # Take off to target altitude - vehicle.flush() - - # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command - # after Vehicle.commands.takeoff will execute immediately). - while True: - print " Altitude: ", vehicle.location.alt - if vehicle.location.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. - print "Reached target altitude" - break; - time.sleep(1) - class Drone(object): def __init__(self, home_coords, server_enabled=True): self.gps_lock = False self.altitude = 30.0 # Connect to the Vehicle - print 'Connecting to vehicle on: %s' % args.connect + self._log('Connected to vehicle.') self.vehicle = vehicle - print "connected ..." self.commands = self.vehicle.commands self.current_coords = [] self.home_coords = home_coords @@ -93,19 +55,15 @@ def __init__(self, home_coords, server_enabled=True): self._log("DroneDelivery Start") # Register observers - self.vehicle.add_attribute_listener('armed', self.armed_callback) self.vehicle.add_attribute_listener('location', self.location_callback) - self.vehicle.add_attribute_listener('gps_0', self.gps_callback) - - self._log("Waiting for GPS Lock") def launch(self): - while not self.gps_lock: - time.sleep(1) + self._log("Waiting for ability to arm...") + while not self.vehicle.is_armable: + time.sleep(.1) self._log('Running initial boot sequence') self.change_mode('GUIDED') - time.sleep(5) # EKF warmup self.arm() self.takeoff() @@ -119,14 +77,12 @@ def takeoff(self): def arm(self, value=True): if value: - self._log("Arming") + self._log('Waiting for arming...') self.vehicle.armed = True while not self.vehicle.armed: - print " Waiting for arming..." - print " Mode: %s" % self.vehicle.mode.name - time.sleep(1) + time.sleep(.1) else: - self._log("Disarming") + self._log("Disarming!") self.vehicle.armed = False def _run_server(self): @@ -143,13 +99,11 @@ def _run_server(self): cherrypy.engine.start() def change_mode(self, mode): - self._log("Mode: {0}".format(mode)) + self._log("Changing to mode: {0}".format(mode)) self.vehicle.mode = VehicleMode(mode) while self.vehicle.mode.name != mode: - print " Waiting for mode change ... (%s)" % self.vehicle.mode.name - print " Mode: {0}".format(mode) - self.vehicle.mode = VehicleMode(mode) + self._log(' ... polled mode: {0}'.format(mode)) time.sleep(1) def goto(self, location, relative=None): @@ -173,19 +127,6 @@ def location_callback(self, vehicle, name, location): self.current_location = location - def armed_callback(self, vehicle, name, armed): - self._log("DroneDelivery Armed Callback: %s" % armed) - self.vehicle.remove_attribute_listener('armed', self.armed_callback) - - def gps_callback(self, vehicle, name, gps): - self._log("GPS: {0}".format(gps)) - if self.vehicle.gps_0.fix_type >= 2: - self.gps_lock = True - self.vehicle.remove_attribute_listener('gps_0', self.gps_callback) - else: - print "Waiting for GPS...:", vehicle.gps_0.fix_type - self.gps_lock = False - def _log(self, message): print "[DEBUG]: {0}".format(message) From 8d12c6ac067ad8838cf4b12c4f75c48d0409887b Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 11 Nov 2015 17:23:40 -0800 Subject: [PATCH 193/475] 2.0.0rc10 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 4172267f5..ad667319c 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.0.0rc9' +version = '2.0.0rc10' setup(name='dronekit', zip_safe=True, From 6fddfc6c4b981ce316d99f39d6dba55ced4dfcf9 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 12 Nov 2015 14:45:21 +1100 Subject: [PATCH 194/475] Update apiref for wait_ready in Vehicle and connect() --- dronekit/lib/__init__.py | 55 ++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 0de03a721..ddb3e9c72 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -30,15 +30,21 @@ ---- -.. todo:: Update this when have confirmed how to register for parameter notifications. - .. py:function:: connect(ip, wait_ready=False, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200) Returns a :py:class:`Vehicle` object connected to the address specified by string parameter ``ip``. - Connection string parameters for different targets are listed in the :ref:`getting started guide `. + Connection string parameters (``ip``) for different targets are listed in the :ref:`getting started guide `. :param String ip: Connection string for target address - e.g. 127.0.0.1:14550. - :param Bool wait_ready: Wait until all :py:func:`Vehicle.parameters` have downloaded before the method returns (default is false) + :param Bool/Array wait_ready: If ``True`` wait until all default attributes have downloaded before + the method returns (default is ``False``). + The default attributes to wait on are: :py:attr:`parameters`, :py:attr:`gps_0`, + :py:attr:`armed`, :py:attr:`mode`, and :py:attr:`attitude`. + + You can also specify a named set of parameters to wait on (e.g. ``wait_ready=['system_status','mode']``). + + For more information see :py:func:`Vehicle.wait_ready `. + :param status_printer: Method of signature ``def status_printer(txt)`` that prints STATUS_TEXT messages from the Vehicle and other diagnostic information. By default the status information is printed to the command prompt in which the script is running. :param Vehicle vehicle_class: The class that will be instantiated by the ``connect()`` method. @@ -47,15 +53,7 @@ :param int baud: The baud rate for the connection. The default is 115200. - :returns: A connected :py:class:`Vehicle` object. - ----- - - .. todo:: - - Confirm what status_printer, vehicle_class and rate "mean" (https://github.com/dronekit/dronekit-python/issues/395#issuecomment-153527657) - Can we hide in API. Can we get method defined in this file or connect method file exported - + :returns: A connected vehicle of the type defined in ``vehicle_class`` (a superclass of :py:class:`Vehicle`). """ import threading, time, math, copy @@ -1465,6 +1463,37 @@ def initialize(self, rate=4, heartbeat_timeout=30): break def wait_ready(self, *types, **kwargs): + """ + Waits for specified attributes to be populated from the vehicle (values are initially ``None``). + + This is typically called "behind the scenes" to ensure that :py:func:`connect` does not return until + attributes have populated (via the ``wait_ready`` parameter). You can also use it after connecting to + wait on a specific value(s). + + There are two ways to call the method: + + .. code-block:: python + + #Wait on default attributes to populate + vehicle.wait_ready(True) + + #Wait on specified attributes (or array of attributes) to populate + vehicle.wait_ready('mode','airspeed') + + Using the ``wait_ready(True)`` waits on :py:attr:`parameters`, :py:attr:`gps_0`, + :py:attr:`armed`, :py:attr:`mode`, and :py:attr:`attitude`. In practice this usually + means that all supported attributes will be populated. + + By default, the method will timeout after 30 seconds and raise an exception if the + attributes were not populated. + + :param *types: ``True`` to wait on the default set of attributes, or a + comma-separated list of the specific attributes to wait on. + :param int timeout: Timeout in seconds after which the method will raise an exception + (the default) or return ``False``. The default timeout is 30 seconds. + :param Boolean raise_exception: If ``True`` the method will raise an exception on timeout, + otherwise the method will return ``False``. The default is ``True`` (raise exception). + """ timeout = kwargs.get('timeout', 30) raise_exception = kwargs.get('raise_exception', True) From 87156953666d1d30b9b1343ab90c10735d83e850 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 12 Nov 2015 16:55:31 +1100 Subject: [PATCH 195/475] Updates to docs/examples/ref for parameter observers, wait_ready. UPdates to migration guide for this to. UPdated main entry point to link to migration guide --- docs/examples/vehicle_state.rst | 107 ++++++++++------ docs/guide/migrating.rst | 57 +++++++-- docs/guide/vehicle_state_and_parameters.rst | 75 ++++++++--- docs/index.rst | 4 + dronekit/lib/__init__.py | 99 +++++++++++++-- examples/vehicle_state/vehicle_state.py | 134 +++++++++++++------- 6 files changed, 355 insertions(+), 121 deletions(-) diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index def80e622..7c605c132 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -49,33 +49,37 @@ On the command prompt you should see (something like): .. code:: bash + Connecting to vehicle on: 170.0.0.1:14550 >>> APM:Copter V3.3 (d6053245) >>> Frame: QUAD - - Accumulating vehicle attribute messages + >>> Calibrating barometer + >>> Initialising APM... + >>> barometer calibration complete + >>> GROUND START Get all vehicle attribute values: - Global Location: LocationGlobal:lat=-35.3632361,lon=149.1652374,alt=361.989990234,is_relative=False + Global Location: LocationGlobal:lat=-35.363261,lon=149.1652299,alt=0.0,is_relative=False Local Location: LocationLocal:north=None,east=None,down=None - Attitude: Attitude:pitch=-0.0078572165221,yaw=-0.352846503258,roll=0.00523957656696 - Velocity: [-0.02, 0.01, 0.0] + Attitude: Attitude:pitch=0.00294387154281,yaw=-0.11805768311,roll=0.00139428151306 + Velocity: [-0.03, 0.02, 0.0] GPS: GPSInfo:fix=3,num_sat=10 Groundspeed: 0.0 Airspeed: 0.0 Mount status: [None, None, None] - Battery: Battery:voltage=12.587,current=0.0,level=95 - EKF OK?: True + Battery: Battery:voltage=12.587,current=0.0,level=100 + EKF OK?: False Rangefinder: Rangefinder: distance=None, voltage=None Rangefinder distance: None Rangefinder voltage: None - Is Armable?: True + Heading: 353 + Is Armable?: False System status: STANDBY - Heading: 341 Mode: STABILIZE Armed: False Waiting for home location ... ... Waiting for home location ... + Waiting for home location ... Home location: LocationGlobal:lat=-35.3632621765,lon=149.165237427,alt=583.989990234,is_relative=False @@ -88,59 +92,84 @@ On the command prompt you should see (something like): Set Vehicle.armed=True (currently: False) Waiting for arming... + Waiting for arming... + Waiting for arming... >>> ARMING MOTORS + >>> GROUND START + Waiting for arming... + Waiting for arming... >>> Initialising APM... + Vehicle is armed: True - Add attribute callback/observer on `vehicle` for `mode` attribute - Set mode=STABILIZE (currently: GUIDED) - Wait 2s so callback invoked before observer removed - CALLBACK: Mode changed to VehicleMode:STABILIZE - Remove Vehicle.mode observer - - Add attribute callback/observer on `attitude` attribute using decorator + Add `attitude` attribute callback/observer on `vehicle` Wait 2s so callback invoked before observer removed - CALLBACK: Location changed to Attitude:pitch=0.0062674083747,yaw=-0.0318436846137,roll=-0.00923461187631 - CALLBACK: Location changed to Attitude:pitch=0.00625518895686,yaw=-0.0317140743136,roll=-0.0091759338975 + CALLBACK: Attitude changed to Attitude:pitch=-0.000483880605316,yaw=-0.0960851684213,roll=-0.00799709651619 + CALLBACK: Attitude changed to Attitude:pitch=0.000153727291035,yaw=-0.0962921902537,roll=-0.00707155792043 ... - CALLBACK: Location changed to Attitude:pitch=0.00629614247009,yaw=-0.0343224518001,roll=-0.0108289364725 - CALLBACK: Location changed to Attitude:pitch=0.00636938679963,yaw=-0.0352342799306,roll=-0.01096534729 + CALLBACK: Attitude changed to Attitude:pitch=0.00485319690779,yaw=-0.100129388273,roll=0.00181497994345 + Remove Vehicle.attitude observer + + Add `mode` attribute callback/observer using decorator + Set mode=STABILIZE (currently: GUIDED) and wait for callback + Wait 2s so callback invoked before moving to next example + CALLBACK: Mode changed to VehicleMode:STABILIZE Attempt to remove observer added with `on_attribute` decorator (should fail) - Exception: Cannot add observer added using decorator + Exception: Cannot remove observer added using decorator - Add attribute calback detecting any attribute change + Add attribute callback detecting ANY attribute change Wait 1s so callback invoked before observer removed - CALLBACK: (battery): Battery:voltage=12.538,current=3.48,level=95 - CALLBACK: (gps_0): GPSInfo:fix=3,num_sat=10 - CALLBACK: (location): LocationGlobal:lat=-35.3632361,lon=149.1652379,alt=361.989990234,is_relative=False - CALLBACK: (velocity): [-0.01, 0.03, 0.0] - CALLBACK: (local_position): LocationLocal:north=2.78085613251,east=0.730665147305,down=0.00156301062088 - CALLBACK: (attitude): Attitude:pitch=-0.00780974514782,yaw=-0.361094027758,roll=0.00564418500289 - CALLBACK: (heading): 339 - CALLBACK: (location): LocationGlobal:lat=-35.3632361,lon=149.1652379,alt=361.989990234,is_relative=False - CALLBACK: (airspeed): 0.019999999553 - CALLBACK: (groundspeed): 0.019999999553 + CALLBACK: (attitude): Attitude:pitch=0.00716688157991,yaw=-0.0950401723385,roll=0.00759896961972 + CALLBACK: (heading): 354 + CALLBACK: (location): LocationGlobal:lat=-35.3632621,lon=149.1652291,alt=362.0,is_relative=False + CALLBACK: (airspeed): 0.0 + CALLBACK: (groundspeed): 0.0 CALLBACK: (ekf_ok): True - CALLBACK: (armed): True - CALLBACK: (mode): VehicleMode:GUIDED + CALLBACK: (battery): Battery:voltage=12.538,current=3.48,level=99 + CALLBACK: (gps_0): GPSInfo:fix=3,num_sat=10 + CALLBACK: (location): LocationGlobal:lat=-35.3632622,lon=149.1652295,alt=362.0,is_relative=False + CALLBACK: (velocity): [-0.14, 0.1, 0.0] + CALLBACK: (local_position): LocationLocal:north=-0.136136248708,east=-0.0430941730738,down=-0.00938374921679 + CALLBACK: (channels): {'1': 1500, '3': 1000, '2': 1500, '5': 1800, '4': 1500, '7': 1000, '6': 1000, '8': 1800} ... CALLBACK: (ekf_ok): True Remove Vehicle attribute observer - Read vehicle param 'THR_MIN': 130.0 - Write vehicle param 'THR_MIN' : 10 - Read new value of param 'THR_MIN': 10.0 + Read and write parameters + Read vehicle param 'THR_MIN': 130.0 + Write vehicle param 'THR_MIN' : 10 + Read new value of param 'THR_MIN': 10.0 + + Print all parameters (iterate `vehicle.parameters`): + Key:RC7_REV Value:1.0 + Key:GPS_INJECT_TO Value:127.0 + Key:FLTMODE1 Value:7.0 + ... + Key:SR2_POSITION Value:0.0 + Key:SIM_FLOW_DELAY Value:0.0 + Key:BATT_CURR_PIN Value:12.0 + + Create parameter observer using decorator + Write vehicle param 'THR_MIN' : 20 (and wait for callback) + PARAMETER CALLBACK: THR_MIN changed to: 20.0 + + Create (removable) observer for any parameter using wildcard string + Change THR_MID and THR_MIN parameters (and wait for callback) + ANY PARAMETER CALLBACK: THR_MID changed to: 400.0 + PARAMETER CALLBACK: THR_MIN changed to: 30.0 + ANY PARAMETER CALLBACK: THR_MIN changed to: 30.0 Reset vehicle attributes/parameters and exit >>> DISARMING MOTORS - CALLBACK: Mode changed to VehicleMode:STABILIZE + PARAMETER CALLBACK: THR_MIN changed to: 130.0 + ANY PARAMETER CALLBACK: THR_MIN changed to: 130.0 + ANY PARAMETER CALLBACK: THR_MID changed to: 500.0 Close vehicle object Completed - How does it work? ================= diff --git a/docs/guide/migrating.rst b/docs/guide/migrating.rst index 8550edd9d..0ed49cd63 100644 --- a/docs/guide/migrating.rst +++ b/docs/guide/migrating.rst @@ -65,13 +65,18 @@ values as were passed to *MAVProxy* when setting up a connection in DKPY 1.x (in # Connect to the Vehicle (in this case a UDP endpoint) vehicle = connect('127.0.0.1:14550', wait_ready=True) +.. note:: + + The ``wait_ready=True`` parameter ensures that ``connect()`` won't return until + :py:attr:`Vehicle.parameters ` and most other default attributes have been + populated with values from the vehicle. Check out :py:func:`Vehicle.wait_ready() ` for more + information (this method is used by the ``connect()`` implementation). -The ``wait_ready=True`` parameter ensures that ``connect()`` won't return until -:py:attr:`Vehicle.parameters ` has been populated. -This also allows *MAVLink* messages to arrive from the connected vehicle -and populate other ``Vehicle`` attributes. + :py:func:`connect() ` also has arguments for setting the baud rate + and returning your own :ref:`custom vehicle classes `. + -The vehicle can then be used in exactly the same way as in DKPY 1.x. +After connecting, the returned ``vehicle`` can be used in exactly the same way as in DKPY 1.x. .. note:: @@ -165,7 +170,7 @@ Instead, use normal Python methods for getting file system information: full_directory_path_of_current_script = os.path.dirname(os.path.abspath(__file__)) -.. _migrating_dkpy2_0_heading: +.. _migrating_dkpy2_0_home_location: Home location ------------- @@ -180,6 +185,21 @@ This code must be replaced with the DroneKit-Python 2.x :py:attr:`Vehicle.home_l :py:attr:`Vehicle.home_location `. +Missions and Waypoints +---------------------- + +The API for working with missions has been improved and made significantly more robust. + +One of the major changes is that the :py:attr:`Vehicle.commands ` list no +longer includes the :ref:`home location ` waypoint in the 0th +index. Another change is that we now wait for command download to complete using +:py:attr:`Vehicle.commands.wait_ready() `. + +All the known bugs have been fixed. It is now much easier to download, clear, and add items to the mission +because there is no need to work around race conditions and other issues with the API. + +For more information see :ref:`auto_mode_vehicle_control`. + Observing attribute changes --------------------------- @@ -194,10 +214,12 @@ rather than just the attribute name. This allows you to more easily write callba vehicle-specific handling and means that you can get the new value from the callback attribute rather than by re-querying the vehicle. -The difference between :py:func:`Vehicle.add_attribute_listener() ` and -:py:func:`Vehicle.on_attribute() ` is that attribute listeners added using -:py:func:`Vehicle.on_attribute() ` cannot be removed (while ``on_attribute()`` -has a more elegant syntax). +.. note:: + + The difference between :py:func:`Vehicle.add_attribute_listener() ` and + :py:func:`Vehicle.on_attribute() ` is that attribute listeners added using + :py:func:`Vehicle.on_attribute() ` cannot be removed (while ``on_attribute()`` + has a more elegant syntax). A few attributes have been modified so that they only notify when the value changes: :py:func:`Vehicle.system_status `, @@ -215,6 +237,21 @@ Attributes that provide "streams" of information (i.e. sensor output) remain unc See :ref:`vehicle_state_observe_attributes` for more information. +Parameter changes +----------------- + +In DKPY2 you can now :ref:`observe ` parameters in order to +be notified of changes, and also :ref:`iterate ` +:py:attr:`Vehicle.parameters ` to get a list of off the supported +values in the connected vehicle. + +In addition, the code to download parameters and keep information in sync with the vehicle +is now a lot more robust. + + + + + Intercepting MAVLink Messages ----------------------------- diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index 3d5ed6816..e9036df3f 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -323,17 +323,17 @@ until the download completes), and subsequently keeps the values updated by moni for changes to individual parameters. This process ensures that it is always safe to read supported parameters, and that their values will match the information on the vehicle. -Parameters can be read and set using the :py:attr:`Vehicle.parameters ` +Parameters can be read, set, observed and iterated using the :py:attr:`Vehicle.parameters ` attribute (a :py:class:`Parameters ` object). Getting parameters ------------------ -The parameters are read using the parameter name as a key. Reads will always succeed unless you attempt to access an unsupported parameter -(which will result in a ``KeyError`` exception). +The parameters are read using the parameter name as a key (case-insensitive). Reads will always succeed unless you +attempt to access an unsupported parameter (which will result in a ``KeyError`` exception). -The code example below shows how to set Minimum Throttle (THR_MIN) setting. On Copter and Rover (not Plane), this is the minimum PWM setting for the +The code snippet below shows how to get the Minimum Throttle (THR_MIN) setting. On Copter and Rover (not Plane), this is the minimum PWM setting for the throttle at which the motors will keep spinning. .. code:: python @@ -353,29 +353,74 @@ Vehicle parameters are set as shown in the code fragment below, using the parame # Change the parameter value (Copter, Rover) vehicle.parameters['THR_MIN']=100 + +.. _vehicle_state_iterating_parameters: + +Listing all parameters +---------------------- + +:py:attr:`Vehicle.parameters ` can be iterated to list all parameters and their values: + +.. code:: python + + + print "\nPrint all parameters (iterate `vehicle.parameters`):" + for key, value in vehicle.parameters.iteritems(): + print " Key:%s Value:%s" % (key,value) + + +.. _vehicle_state_observing_parameters: + Observing parameter changes --------------------------- -At time of writing :py:class:`Parameters ` does `not support `_ observing parameter changes. +You can observe any of the vehicle parameters and monitor for changes without the need for polling. +The parameters are cached, so that callback functions are only invoked when parameter values change. -.. todo:: +.. tip:: - Check to see if observers have been implemented and if so, update the information here, in about, and in Vehicle class: - https://github.com/dronekit/dronekit-python/issues/107 + Observing parameters is virtually identical to :ref:`observing attributes `. +The code snippet below shows how to add a callback function to observe changes in the "THR_MIN" +parameter using a decorator. Note that the parameter name is case-insensitive, and that callbacks +added using a decorator cannot be removed. +.. code-block:: python + + @vehicle.parameters.on_attribute('THR_MIN') + def decorated_thr_min_callback(self, attr_name, value): + print " PARAMETER CALLBACK: %s changed to: %s" % (attr_name, value) -.. _api-information-known-issues: +The ``observer`` callback function is invoked with the following arguments: + +* ``self`` - the associated :py:class:`Parameters`. +* ``attr_name`` - the parameter name + (useful if the same callback is used for watching several parameters). +* ``msg`` - the parameter value (so you don't need to re-query the ``Vehicle.parameters`` object). -Known issues -============ +The code snippet below demonstrates how you can add and remove a listener (in this case +for "any parameter") using the +:py:func:`Parameters.add_attribute_listener() ` and +:py:func:`Parameters.remove_attribute_listener() `. + +.. code-block:: python + + #Callback function for "any" parameter + def any_parameter_callback(self, attr_name, value): + print " ANY PARAMETER CALLBACK: %s changed to: %s" % (attr_name, value) + + #Add observer for the vehicle's any/all parameters parameter (note wildcard string ``'*'``) + vehicle.parameters.add_attribute_listener('*', any_parameter_callback) + -Below are a number of bugs and known issues related to vehicle state and settings: -* `#107 Add implementation for observer methods in Parameter class `_ -* `#114 DroneKit has no method for detecting command failure `_ -Other API issues and improvement suggestions can viewed on `github here `_. \ No newline at end of file +.. _api-information-known-issues: + +Known issues +============ + +Known issues and improvement suggestions can viewed on `github here `_. \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index c01be21b5..8b0ee6525 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -11,7 +11,11 @@ DroneKit-Python helps you create powerful apps for UAVs. These apps run on a UAV This documentation provides everything you need to :doc:`get started ` with DroneKit-Python, including an :doc:`overview ` of the API, guide material, a number of demos and examples, and :doc:`API Reference `. +.. tip:: + If you're migrating from DroneKit-Python version 1, check out our comprehensive :ref:`Migration Guide `. + + Contents: .. toctree:: diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index ddb3e9c72..65decb2ee 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1523,7 +1523,7 @@ class Parameters(collections.MutableMapping, HasObservers): the supported parameters for each platform: `Copter `_, `Plane `_, `Rover `_. - Attribute names are generated automatically based on parameter names. The example below shows how to get and set the value of a parameter. + The code fragment below shows how to get and set the value of a parameter. .. code:: python @@ -1533,15 +1533,9 @@ class Parameters(collections.MutableMapping, HasObservers): # Change the parameter value to something different. vehicle.parameters['THR_MIN']=100 - .. note:: - - At time of writing ``Parameters`` does not implement the observer methods, and change notification for parameters - is not supported. - - .. todo:: - - Check to see if observers have been implemented and if so, update the information here, in about, and in Vehicle class: - https://github.com/dronekit/dronekit-python/issues/107 + It is also possible to observe parameters and to iterate the :py:func:`Vehicle.parameters`. + + For more information see: :ref:`vehicle_state_parameters`. """ def __init__(self, vehicle): @@ -1608,10 +1602,62 @@ def wait_ready(self, **kwargs): self._vehicle.wait_ready('parameters', **kwargs) def add_attribute_listener(self, attr_name, *args, **kwargs): + """ + Add a listener callback on a particular parameter. + + The callback can be removed using :py:func:`remove_attribute_listener`. + + .. note:: + + The :py:func:`on_attribute` decorator performs the same operation as this method, but with + a more elegant syntax. Use ``add_attribute_listener`` only if you will need to remove + the observer. + + The callback function is invoked only when the parameter changes. + + The callback arguments are: + + * ``self`` - the associated :py:class:`Parameters`. + * ``attr_name`` - the parameter name. This can be used to infer which parameter has triggered + if the same callback is used for watching multiple parameters. + * ``msg`` - the new parameter value (so you don't need to re-query the vehicle object). + + The example below shows how to get callbacks for the ``THR_MIN`` parameter: + + .. code:: python + + #Callback function for the THR_MIN parameter + def thr_min_callback(self, attr_name, value): + print " PARAMETER CALLBACK: %s changed to: %s" % (attr_name, value) + + #Add observer for the vehicle's THR_MIN parameter + vehicle.parameters.add_attribute_listener('THR_MIN', thr_min_callback) + + See :ref:`vehicle_state_observing_parameters` for more information. + + :param String attr_name: The name of the parameter to watch (or '*' to watch all parameters). + :param *args: The callback to invoke when a change in the parameter is detected. + + """ attr_name = attr_name.upper() return super(Parameters, self).add_attribute_listener(attr_name, *args, **kwargs) def remove_attribute_listener(self, attr_name, *args, **kwargs): + """ + Remove a paremeter listener that was previously added using :py:func:`add_attribute_listener`. + + For example to remove the ``thr_min_callback()`` callback function: + + .. code:: python + + vehicle.parameters.remove_attribute_listener('thr_min', thr_min_callback) + + See :ref:`vehicle_state_observing_parameters` for more information. + + :param String attr_name: The parameter name that is to have an observer removed (or '*' to remove an 'all attribute' observer). + :param *args: The callback function to remove. + + """ attr_name = attr_name.upper() return super(Parameters, self).remove_attribute_listener(attr_name, *args, **kwargs) @@ -1620,9 +1666,42 @@ def notify_attribute_listeners(self, attr_name, *args, **kwargs): return super(Parameters, self).notify_attribute_listeners(attr_name, *args, **kwargs) def on_attribute(self, attr_name, *args, **kwargs): + """ + Decorator for parameter listeners. + + .. note:: + + There is no way to remove a listener added with this decorator. Use + :py:func:`add_attribute_listener` if you need to be able to remove + the :py:func:`listener `. + + The callback function is invoked only when the parameter changes. + + The callback arguments are: + + * ``self`` - the associated :py:class:`Parameters`. + * ``attr_name`` - the parameter name. This can be used to infer which parameter has triggered + if the same callback is used for watching multiple parameters. + * ``msg`` - the new parameter value (so you don't need to re-query the vehicle object). + + The code fragment below shows how to get callbacks for the ``THR_MIN`` parameter: + + .. code:: python + + @vehicle.parameters.on_attribute('THR_MIN') + def decorated_thr_min_callback(self, attr_name, value): + print " PARAMETER CALLBACK: %s changed to: %s" % (attr_name, value) + + See :ref:`vehicle_state_observing_parameters` for more information. + + :param String attr_name: The name of the parameter to watch (or '*' to watch all parameters). + :param args: The callback to invoke when a change in the parameter is detected. + + """ attr_name = attr_name.upper() return super(Parameters, self).on_attribute(attr_name, *args, **kwargs) + class Command(mavutil.mavlink.MAVLink_mission_item_message): """ A waypoint object. diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index e2aa7102b..56257faa6 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -19,18 +19,11 @@ args = parser.parse_args() -# Connect to the Vehicle +# Connect to the Vehicle. +# Set `wait_ready=True` to ensure default attributes are populated before `connect()` returns. print "\nConnecting to vehicle on: %s" % args.connect vehicle = connect(args.connect, wait_ready=True) -if vehicle.mode.name == "INITIALISING": - print "Waiting for vehicle to initialise" - time.sleep(1) - -print "\nAccumulating vehicle attribute messages" -while vehicle.attitude.pitch==None: #Attitude is fairly quick to propagate - print " ..." - time.sleep(1) # Get all vehicle attributes (state) print "\nGet all vehicle attribute values:" @@ -54,6 +47,7 @@ print " Armed: %s" % vehicle.armed # settable + # Get Vehicle Home location - will be `None` until first set by autopilot while not vehicle.home_location: cmds = vehicle.commands @@ -64,6 +58,7 @@ # We have a home location, so print it! print "\n Home location: %s" % vehicle.home_location + # Set vehicle home_location, mode, and armed attributes (the only settable attributes) print "\nSet new home location" @@ -74,7 +69,7 @@ vehicle.home_location=my_location_alt print " New Home Location (from attribute - altitude should be 222): %s" % vehicle.home_location -#Confirm it is written out (note that you must re-download commands) +#Confirm current value on vehicle by re-downloading commands cmds = vehicle.commands cmds.download() cmds.wait_ready() @@ -88,47 +83,26 @@ time.sleep(1) -# Check we have a good gps fix (required to arm) -while vehicle.gps_0.fix_type < 2: - print "Waiting for GPS fix=3 (needed to arm):", vehicle.gps_0.fix_type +# Check that vehicle is armable +while not vehicle.is_armable: + print " Waiting for vehicle to initialise..." time.sleep(1) - + # If required, you can provide additional information about initialisation + # using `vehicle.gps_0.fix_type` and `vehicle.mode.name`. print "\nSet Vehicle.armed=True (currently: %s)" % vehicle.armed vehicle.armed = True while not vehicle.armed: print " Waiting for arming..." time.sleep(1) +print " Vehicle is armed: %s" % vehicle.armed -# Add and remove and attribute callbacks (using mode as example) -def mode_callback(self, attr_name, value): - # `attr_name` is the observed attribute (used if callback is used for multiple attributes) - # `attr_name` - the observed attribute (used if callback is used for multiple attributes) - # `value` is the updated attribute value. - print " CALLBACK: Mode changed to", value +# Add and remove and attribute callbacks -print "\nAdd attribute callback/observer on `vehicle` for `mode` attribute" -vehicle.add_attribute_listener('mode', mode_callback) - - -print " Set mode=STABILIZE (currently: %s)" % vehicle.mode.name -vehicle.mode = VehicleMode("STABILIZE") - -print " Wait 2s so callback invoked before observer removed" -time.sleep(2) - -print " Remove Vehicle.mode observer" -# Remove observer added with `add_attribute_listener()` - specifying the attribute and callback function -vehicle.remove_attribute_listener('mode', mode_callback) - - - -# Add attitude attribute callback using decorator (callbacks added this way cannot be removed). -print "\nAdd attribute callback/observer on `attitude` attribute using decorator" +#Define callback for `vehicle.attitude` observer last_attitude_cache=None -@vehicle.on_attribute('attitude') -def decorated_attitude_callback(self, attr_name, value): +def attitude_callback(self, attr_name, value): # `attr_name` - the observed attribute (used if callback is used for multiple attributes) # `self` - the associated vehicle object (used if a callback is different for multiple vehicles) # `value` is the updated attribute value. @@ -138,17 +112,41 @@ def decorated_attitude_callback(self, attr_name, value): print " CALLBACK: Attitude changed to", value last_attitude_cache=value +print "\nAdd `attitude` attribute callback/observer on `vehicle`" +vehicle.add_attribute_listener('attitude', attitude_callback) print " Wait 2s so callback invoked before observer removed" time.sleep(2) +print " Remove Vehicle.attitude observer" +# Remove observer added with `add_attribute_listener()` specifying the attribute and callback function +vehicle.remove_attribute_listener('attitude', attitude_callback) + + + +# Add mode attribute callback using decorator (callbacks added this way cannot be removed). +print "\nAdd `mode` attribute callback/observer using decorator" +@vehicle.on_attribute('mode') +def decorated_mode_callback(self, attr_name, value): + # `attr_name` is the observed attribute (used if callback is used for multiple attributes) + # `attr_name` - the observed attribute (used if callback is used for multiple attributes) + # `value` is the updated attribute value. + print " CALLBACK: Mode changed to", value + +print " Set mode=STABILIZE (currently: %s) and wait for callback" % vehicle.mode.name +vehicle.mode = VehicleMode("STABILIZE") + +print " Wait 2s so callback invoked before moving to next example" +time.sleep(2) + print "\n Attempt to remove observer added with `on_attribute` decorator (should fail)" try: - vehicle.remove_attribute_listener('mode', decorated_attitude_callback) + vehicle.remove_attribute_listener('mode', decorated_mode_callback) except: print " Exception: Cannot remove observer added using decorator" + # Demonstrate getting callback on any attribute change def wildcard_callback(self, attr_name, value): @@ -157,7 +155,7 @@ def wildcard_callback(self, attr_name, value): # `value` - updated attribute value. print " CALLBACK: (%s): %s" % (attr_name,value) -print "\nAdd attribute calback detecting any attribute change" +print "\nAdd attribute callback detecting ANY attribute change" vehicle.add_attribute_listener('*', wildcard_callback) @@ -168,14 +166,51 @@ def wildcard_callback(self, attr_name, value): # Remove observer added with `add_attribute_listener()` vehicle.remove_attribute_listener('*', wildcard_callback) - - + # Get/Set Vehicle Parameters -print "\nRead vehicle param 'THR_MIN': %s" % vehicle.parameters['THR_MIN'] -print "Write vehicle param 'THR_MIN' : 10" +print "\nRead and write parameters" +print " Read vehicle param 'THR_MIN': %s" % vehicle.parameters['THR_MIN'] + +print " Write vehicle param 'THR_MIN' : 10" vehicle.parameters['THR_MIN']=10 -print "Read new value of param 'THR_MIN': %s" % vehicle.parameters['THR_MIN'] +print " Read new value of param 'THR_MIN': %s" % vehicle.parameters['THR_MIN'] + + +print "\nPrint all parameters (iterate `vehicle.parameters`):" +for key, value in vehicle.parameters.iteritems(): + print " Key:%s Value:%s" % (key,value) + + +print "\nCreate parameter observer using decorator" +# Parameter string is case-insensitive +# Value is cached (listeners are only updated on change) +# Observer added using decorator can't be removed. + +@vehicle.parameters.on_attribute('THR_MIN') +def decorated_thr_min_callback(self, attr_name, value): + print " PARAMETER CALLBACK: %s changed to: %s" % (attr_name, value) + + +print "Write vehicle param 'THR_MIN' : 20 (and wait for callback)" +vehicle.parameters['THR_MIN']=20 +for x in range(1,5): + #Callbacks may not be updated for a few seconds + if vehicle.parameters['THR_MIN']==20: + break + time.sleep(1) + + +#Callback function for the any parameter +print "\nCreate (removable) observer for any parameter using wildcard string" +def any_parameter_callback(self, attr_name, value): + print " ANY PARAMETER CALLBACK: %s changed to: %s" % (attr_name, value) + +#Add observer for the vehicle's any/all parameters parameter (defined using wildcard string ``'*'``) +vehicle.parameters.add_attribute_listener('*', any_parameter_callback) +print " Change THR_MID and THR_MIN parameters (and wait for callback)" +vehicle.parameters['THR_MID']=400 +vehicle.parameters['THR_MIN']=30 ## Reset variables to sensible values. @@ -183,6 +218,7 @@ def wildcard_callback(self, attr_name, value): vehicle.mode = VehicleMode("STABILIZE") vehicle.armed = False vehicle.parameters['THR_MIN']=130 +vehicle.parameters['THR_MID']=500 #Close vehicle object before exiting script @@ -190,3 +226,7 @@ def wildcard_callback(self, attr_name, value): vehicle.close() print("Completed") + + + + From 6092b6237e98359acfd4b95b866d2b8f56cd01d0 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 12 Nov 2015 16:57:06 +1100 Subject: [PATCH 196/475] minor fixup --- examples/vehicle_state/vehicle_state.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 56257faa6..2b09e03c0 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -201,7 +201,7 @@ def decorated_thr_min_callback(self, attr_name, value): time.sleep(1) -#Callback function for the any parameter +#Callback function for "any" parameter print "\nCreate (removable) observer for any parameter using wildcard string" def any_parameter_callback(self, attr_name, value): print " ANY PARAMETER CALLBACK: %s changed to: %s" % (attr_name, value) From 39c907aea487e4454f976d18abd56db06f74dbc8 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 12 Nov 2015 13:21:38 -0800 Subject: [PATCH 197/475] Renames msg arg to value. --- docs/guide/vehicle_state_and_parameters.rst | 2 +- dronekit/lib/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index e9036df3f..4425d545b 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -166,7 +166,7 @@ The ``observer`` callback function is invoked with the following arguments: to implement vehicle-specific callback handling (if needed). * ``attr_name`` - the attribute name. This can be used to infer which attribute has triggered if the same callback is used for watching several attributes. -* ``msg`` - the attribute value (so you don't need to re-query the vehicle object). +* ``value`` - the attribute value (so you don't need to re-query the vehicle object). The code snippet below shows how to add (and remove) a callback function to observe changes in :py:attr:`Vehicle.location.global_frame ` using diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 65decb2ee..76b2f8bf4 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -322,7 +322,7 @@ def add_attribute_listener(self, attr_name, observer): to implement vehicle-specific callback handling (if needed). * ``attr_name`` - the attribute name. This can be used to infer which attribute has triggered if the same callback is used for watching several attributes. - * ``msg`` - the attribute value (so you don't need to re-query the vehicle object). + * ``value`` - the attribute value (so you don't need to re-query the vehicle object). The example below shows how to get callbacks for (global) location changes: From bceb03512b1abec374abc90601fcd59c4f4ef3c7 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 11 Nov 2015 13:46:10 -0800 Subject: [PATCH 198/475] Exposes target_system on connect(). --- dronekit/__init__.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index edc20d7e2..d38cdc38a 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -40,7 +40,7 @@ def read(self): os._exit(43) class MAVHandler: - def __init__(self, master, vehicle_class=Vehicle): + def __init__(self, master, vehicle_class=Vehicle, target_system=0): self.vehicle_class = vehicle_class self.master = master @@ -51,8 +51,7 @@ def __init__(self, master, vehicle_class=Vehicle): self.master.mav = mavutil.mavlink.MAVLink(MavWriter(self.out_queue), srcSystem=self.master.source_system, use_native=False) # Targets - self.target_system = 0 - self.target_component = 0 + self.target_system = target_system # Listeners. self.loop_listeners = [] @@ -151,8 +150,6 @@ def fix_targets(self, message): """Set correct target IDs for our vehicle""" if hasattr(message, 'target_system'): message.target_system = self.target_system - if hasattr(message, 'target_component'): - message.target_component = self.target_component def forward_loop(self, fn): """ @@ -177,8 +174,8 @@ def close(self): time.sleep(0.1) self.master.close() -def connect(ip, _initialize=True, wait_ready=None, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200, heartbeat_timeout=30): - handler = MAVHandler(mavutil.mavlink_connection(ip, baud=baud)) +def connect(ip, _initialize=True, wait_ready=None, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200, heartbeat_timeout=30, target_system=0): + handler = MAVHandler(mavutil.mavlink_connection(ip, baud=baud), target_system=target_system) vehicle = vehicle_class(handler) if status_printer: From 64a4775cb7a53fc749cf9a161a1451b892da9161 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 16 Nov 2015 19:06:31 -0800 Subject: [PATCH 199/475] Create MAVConnection abstraction to implement forwarding. --- dronekit/__init__.py | 154 +----------------------- dronekit/mavlink.py | 186 +++++++++++++++++++++++++++++ dronekit/test/sitl/test_mavlink.py | 26 ++++ setup.py | 2 +- 4 files changed, 215 insertions(+), 153 deletions(-) create mode 100644 dronekit/mavlink.py create mode 100644 dronekit/test/sitl/test_mavlink.py diff --git a/dronekit/__init__.py b/dronekit/__init__.py index d38cdc38a..fbe9e9a20 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -7,17 +7,13 @@ import re import dronekit.lib from dronekit.lib import APIException +from dronekit.mavlink import MAVConnection from dronekit.util import errprinter from pymavlink import mavutil, mavwp from Queue import Queue, Empty from threading import Thread import types -if platform.system() == 'Windows': - from errno import WSAECONNRESET as ECONNABORTED -else: - from errno import ECONNABORTED - # Public re-exports Vehicle = dronekit.lib.Vehicle Command = dronekit.lib.Command @@ -28,154 +24,8 @@ LocationLocal = dronekit.lib.LocationLocal CloudClient = dronekit.lib.CloudClient -class MavWriter(): - def __init__(self, queue): - self.queue = queue - - def write(self, pkt): - self.queue.put(pkt) - - def read(self): - errprinter('writer should not have had a read request') - os._exit(43) - -class MAVHandler: - def __init__(self, master, vehicle_class=Vehicle, target_system=0): - self.vehicle_class = vehicle_class - - self.master = master - - # TODO get rid of "master" object as exposed, - # keep it private, expose something smaller for dronekit - self.out_queue = Queue() - self.master.mav = mavutil.mavlink.MAVLink(MavWriter(self.out_queue), srcSystem=self.master.source_system, use_native=False) - - # Targets - self.target_system = target_system - - # Listeners. - self.loop_listeners = [] - self.message_listeners = [] - - # Debug flag. - self._accept_input = True - self._alive = True - self._death_error = None - - import atexit - def onexit(): - self._alive = False - atexit.register(onexit) - - def mavlink_thread(): - # Huge try catch in case we see http://bugs.python.org/issue1856 - try: - while True: - # Downtime - time.sleep(0.05) - - # Loop listeners. - for fn in self.loop_listeners: - fn(self) - - while True: - try: - msg = self.out_queue.get_nowait() - self.fix_targets(msg) - self.master.write(msg) - except socket.error as error: - # If connection reset (closed), stop polling. - if error.errno == ECONNABORTED: - raise APIException('Connection aborting during read') - raise - except Empty: - break - except Exception as e: - errprinter('>>> mav send error:', e) - break - - while self._accept_input: - try: - msg = self.master.recv_msg() - except socket.error as error: - # If connection reset (closed), stop polling. - if error.errno == ECONNABORTED: - raise APIException('Connection aborting during send') - raise - except Exception as e: - # TODO this should be more rigorous. How to avoid - # invalid MAVLink prefix '73' - # invalid MAVLink prefix '13' - # errprinter('mav recv error:', e) - msg = None - if not msg: - break - - # Message listeners. - for fn in self.message_listeners: - fn(self, msg) - - except APIException as e: - errprinter('>>> ' + str(e.message)) - self._alive = False - self.master.close() - self._death_error = e - return - - except Exception as e: - # http://bugs.python.org/issue1856 - if not self._alive: - pass - else: - self._alive = False - self.master.close() - self._death_error = e - - t = Thread(target=mavlink_thread) - t.daemon = True - self.mavlink_thread = t - - def reset(self): - self.out_queue = Queue() - if hasattr(self.master, 'reset'): - self.master.reset() - else: - try: - self.master.close() - except: - pass - self.master = mavutil.mavlink_connection(self.master.address) - - def fix_targets(self, message): - """Set correct target IDs for our vehicle""" - if hasattr(message, 'target_system'): - message.target_system = self.target_system - - def forward_loop(self, fn): - """ - Decorator for event loop. - """ - self.loop_listeners.append(fn) - - def forward_message(self, fn): - """ - Decorator for message inputs. - """ - self.message_listeners.append(fn) - - def start(self): - if not self.mavlink_thread.is_alive(): - self.mavlink_thread.start() - - def close(self): - # TODO this can block forever if parameters continue to be added - self._alive = False - while not self.out_queue.empty(): - time.sleep(0.1) - self.master.close() - def connect(ip, _initialize=True, wait_ready=None, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200, heartbeat_timeout=30, target_system=0): - handler = MAVHandler(mavutil.mavlink_connection(ip, baud=baud), target_system=target_system) + handler = MAVConnection(ip, baud=baud, target_system=target_system) vehicle = vehicle_class(handler) if status_printer: diff --git a/dronekit/mavlink.py b/dronekit/mavlink.py new file mode 100644 index 000000000..54e9b3ab4 --- /dev/null +++ b/dronekit/mavlink.py @@ -0,0 +1,186 @@ +from __future__ import print_function +import time +import socket +import sys +import os +import platform +import re +import dronekit.lib +from dronekit.lib import APIException +from dronekit.util import errprinter +from pymavlink import mavutil, mavwp +from Queue import Queue, Empty +from threading import Thread +import types + +if platform.system() == 'Windows': + from errno import WSAECONNRESET as ECONNABORTED +else: + from errno import ECONNABORTED + + +class MAVWriter(object): + def __init__(self, queue): + self.queue = queue + + def write(self, pkt): + self.queue.put(pkt) + + def read(self): + errprinter('writer should not have had a read request') + os._exit(43) + + +class MAVConnection(object): + def __init__(self, ip, + baud=115200, + target_system=0): + self.master = mavutil.mavlink_connection(ip, baud=baud) + + # TODO get rid of "master" object as exposed, + # keep it private, expose something smaller for dronekit + self.out_queue = Queue() + self.master.mav = mavutil.mavlink.MAVLink( + MAVWriter(self.out_queue), + srcSystem=self.master.source_system, + use_native=False) + + # Targets + self.target_system = target_system + + # Listeners. + self.loop_listeners = [] + self.message_listeners = [] + + # Debug flag. + self._accept_input = True + self._alive = True + self._death_error = None + + import atexit + + def onexit(): + self._alive = False + + atexit.register(onexit) + + def mavlink_thread(): + # Huge try catch in case we see http://bugs.python.org/issue1856 + try: + while True: + # Downtime + time.sleep(0.05) + + # Loop listeners. + for fn in self.loop_listeners: + fn(self) + + while True: + try: + msg = self.out_queue.get_nowait() + self.fix_targets(msg) + self.master.write(msg) + except socket.error as error: + # If connection reset (closed), stop polling. + if error.errno == ECONNABORTED: + raise APIException( + 'Connection aborting during read') + raise + except Empty: + break + except Exception as e: + errprinter('>>> mav send error:', e) + break + + while self._accept_input: + try: + msg = self.master.recv_msg() + except socket.error as error: + # If connection reset (closed), stop polling. + if error.errno == ECONNABORTED: + raise APIException( + 'Connection aborting during send') + raise + except Exception as e: + # TODO this should be more rigorous. How to avoid + # invalid MAVLink prefix '73' + # invalid MAVLink prefix '13' + # errprinter('mav recv error:', e) + msg = None + if not msg: + break + + # Message listeners. + for fn in self.message_listeners: + fn(self, msg) + + except APIException as e: + errprinter('>>> ' + str(e.message)) + self._alive = False + self.master.close() + self._death_error = e + return + + except Exception as e: + # http://bugs.python.org/issue1856 + if not self._alive: + pass + else: + self._alive = False + self.master.close() + self._death_error = e + + t = Thread(target=mavlink_thread) + t.daemon = True + self.mavlink_thread = t + + def reset(self): + self.out_queue = Queue() + if hasattr(self.master, 'reset'): + self.master.reset() + else: + try: + self.master.close() + except: + pass + self.master = mavutil.mavlink_connection(self.master.address) + + def fix_targets(self, message): + """Set correct target IDs for our vehicle""" + if hasattr(message, 'target_system'): + message.target_system = self.target_system + + def forward_loop(self, fn): + """ + Decorator for event loop. + """ + self.loop_listeners.append(fn) + + def forward_message(self, fn): + """ + Decorator for message inputs. + """ + self.message_listeners.append(fn) + + def start(self): + if not self.mavlink_thread.is_alive(): + self.mavlink_thread.start() + + def close(self): + # TODO this can block forever if parameters continue to be added + self._alive = False + while not self.out_queue.empty(): + time.sleep(0.1) + self.master.close() + + def pipe(self, target): + @self.forward_message + def callback(self, msg): + target.out_queue.put(msg.pack(self.master.mav)) + + @target.forward_message + def callback(self, msg): + self.out_queue.put(msg.pack(self.master.mav)) + + return target + diff --git a/dronekit/test/sitl/test_mavlink.py b/dronekit/test/sitl/test_mavlink.py new file mode 100644 index 000000000..35d156045 --- /dev/null +++ b/dronekit/test/sitl/test_mavlink.py @@ -0,0 +1,26 @@ +import time +import math +from dronekit import connect +from dronekit.mavlink import MAVConnection +from dronekit.test import with_sitl +from nose.tools import assert_not_equals, assert_equals + +@with_sitl +def test_mavlink(connpath): + vehicle = connect(connpath) + out = MAVConnection('udpin:localhost:15668') + vehicle._handler.pipe(out) + out.start() + + vehicle2 = connect('udpout:localhost:15668') + + result = {'success': False} + @vehicle2.on_attribute('location') + def callback(*args): + result['success'] = True + + i = 20 + while not result['success'] and i > 0: + time.sleep(1) + + assert result['success'] diff --git a/setup.py b/setup.py index ad667319c..3f7e5ba04 100644 --- a/setup.py +++ b/setup.py @@ -26,6 +26,6 @@ ], license='apache', packages=[ - 'dronekit', 'dronekit.lib', 'dronekit.test', + 'dronekit', 'dronekit.lib', 'dronekit.test' ], ext_modules=[]) From 4d8beaa27842fbd57bbd8f8d325db7e16f609ca4 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 10 Nov 2015 16:35:51 -0800 Subject: [PATCH 200/475] Corrects is_relative attr of vehicle.location. --- dronekit/lib/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 76b2f8bf4..6c8f4924b 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1157,9 +1157,9 @@ def mode(self, v): @property def location(self): # For backward compatibility, this is (itself) a LocationLocal object. - ret = LocationGlobal(self._lat, self._lon, self._alt, is_relative=False) + ret = LocationGlobal(self._lat, self._lon, self._alt, is_relative=True) ret.local_frame = LocationLocal(self._north, self._east, self._down) - ret.global_frame = LocationGlobal(self._lat, self._lon, self._alt, is_relative=False) + ret.global_frame = LocationGlobal(self._lat, self._lon, self._alt, is_relative=True) return ret @property From cc8baa3a8a202f8d4982172cb20d6ff209987850 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 12 Nov 2015 18:01:29 -0800 Subject: [PATCH 201/475] Corrects fame to 'frame' :( --- dronekit/lib/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 6c8f4924b..d3ce57edf 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -126,7 +126,7 @@ def __init__(self, lat, lon, alt=None, is_relative=True): # This is for backward compatibility. self.local_frame = None - self.global_fame = None + self.global_frame = None def __str__(self): return "LocationGlobal:lat=%s,lon=%s,alt=%s,is_relative=%s" % (self.lat, self.lon, self.alt, self.is_relative) From 5bf2d4e2a1d47251cfb02e063c0481a6419d3059 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 12 Nov 2015 18:11:35 -0800 Subject: [PATCH 202/475] Refactors locations, adds LocationGlobalRelative --- dronekit/__init__.py | 1 + dronekit/lib/__init__.py | 81 ++++++++++++++++++----- dronekit/test/sitl/test_goto.py | 6 +- examples/drone_delivery/drone_delivery.py | 19 ++++-- examples/follow_me/follow_me.py | 2 +- examples/mission_basic/mission_basic.py | 2 +- examples/simple_goto/simple_goto.py | 4 +- 7 files changed, 84 insertions(+), 31 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index fbe9e9a20..516de230a 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -20,6 +20,7 @@ CommandSequence = dronekit.lib.CommandSequence VehicleMode = dronekit.lib.VehicleMode SystemStatus = dronekit.lib.SystemStatus +LocationGlobalRelative = dronekit.lib.LocationGlobalRelative LocationGlobal = dronekit.lib.LocationGlobal LocationLocal = dronekit.lib.LocationLocal CloudClient = dronekit.lib.CloudClient diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index d3ce57edf..18f8428c8 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -109,7 +109,7 @@ class LocationGlobal(object): .. code:: python - LocationGlobal(-34.364114, 149.166022, 30, is_relative=True) + LocationGlobal(-34.364114, 149.166022, 30) .. todo:: FIXME: Location class - possibly add a vector3 representation. @@ -118,21 +118,53 @@ class LocationGlobal(object): :param alt: Altitude in meters (either relative or absolute). :param is_relative: ``True`` if the specified altitude is relative to a 'home' location (this is usually desirable). ``False`` to set altitude relative to "mean sea-level". """ - def __init__(self, lat, lon, alt=None, is_relative=True): + def __init__(self, lat, lon, alt=None): self.lat = lat self.lon = lon self.alt = alt - self.is_relative = is_relative + self.is_relative = False # This is for backward compatibility. self.local_frame = None self.global_frame = None def __str__(self): - return "LocationGlobal:lat=%s,lon=%s,alt=%s,is_relative=%s" % (self.lat, self.lon, self.alt, self.is_relative) + return "LocationGlobal:lat=%s,lon=%s,alt=%s" % (self.lat, self.lon, self.alt) + + +class LocationGlobalRelative(object): + """ + A global location object relative to home location. + + The latitude and longitude are relative to the `WGS84 coordinate system `_. + The altitude is relative to either the *home position* or "mean sea-level", depending on the value of the ``is_relative``. + + For example, a global location object might be defined as: + + .. code:: python + + LocationGlobalRelative(-34.364114, 149.166022, 0) + + .. todo:: FIXME: Location class - possibly add a vector3 representation. + + :param lat: Latitude. + :param lon: Longitude. + :param alt: Altitude in meters (either relative or absolute). + :param is_relative: ``True`` if the specified altitude is relative to a 'home' location (this is usually desirable). ``False`` to set altitude relative to "mean sea-level". + """ + def __init__(self, lat, lon, alt=None): + self.lat = lat + self.lon = lon + self.alt = alt + self.is_relative = True + + # This is for backward compatibility. + self.local_frame = None + self.global_frame = None + + def __str__(self): + return "LocationGlobalRelative:lat=%s,lon=%s,alt=%s" % (self.lat, self.lon, self.alt) -# Back-compatibility for earlier clients. -Location = LocationGlobal class LocationLocal(object): """ @@ -450,7 +482,6 @@ def decorator(fn): self.add_attribute_listener(name, fn) return decorator - class ChannelsOverride(dict): """ A dictionary class for managing Vehicle channel overrides. @@ -596,6 +627,15 @@ def overrides(self, newch): self._overrides._active = True self._overrides._send() +class Locations(HasObservers): + """ + Locations. + """ + def __init__(self): + super(Locations, self).__init__() + self.local_frame = None + self.global_frame = None + self.global_relative_frame = None class Vehicle(HasObservers): """ @@ -723,8 +763,12 @@ def listener(_, name, value): def listener(_, msg): self.notify_message_listeners(msg.get_type(), msg) + self._location = Locations() + self._lat = None self._lon = None + self._alt = None + self._relative_alt = None self._vx = None self._vy = None self._vz = None @@ -732,7 +776,13 @@ def listener(_, msg): @self.on_message('GLOBAL_POSITION_INT') def listener(self, name, m): (self._lat, self._lon) = (m.lat / 1.0e7, m.lon / 1.0e7) + (self._alt, self._relative_alt) = (m.alt, m.relative_alt) + self._location.global_frame = LocationGlobal(self._lat, self._lon, self._alt) + self._location.global_relative_frame = LocationGlobalRelative(self._lat, self._lon, self._relative_alt) self.notify_attribute_listeners('location', self.location) + self.location.notify_attribute_listeners('global_frame', self.location.global_frame) + self.location.notify_attribute_listeners('global_relative_frame', self.location.global_relative_frame) + (self._vx, self._vy, self._vz) = (m.vx / 100.0, m.vy / 100.0, m.vz / 100.0) self.notify_attribute_listeners('velocity', self.velocity) @@ -745,7 +795,9 @@ def listener(self, name, m): self._north = m.x self._east = m.y self._down = m.z - self.notify_attribute_listeners('local_position', self.location.local_frame) + self._location._local_frame = LocationLocal(self._north, self._east, self._down) + self.notify_attribute_listeners('location', self.location) + self.location.notify_attribute_listeners('local_frame', self.location.local_frame) self._pitch = None self._yaw = None @@ -765,7 +817,6 @@ def listener(self, name, m): self.notify_attribute_listeners('attitude', self.attitude) self._heading = None - self._alt = None self._airspeed = None self._groundspeed = None @@ -773,8 +824,6 @@ def listener(self, name, m): def listener(self, name, m): self._heading = m.heading self.notify_attribute_listeners('heading', self.heading) - self._alt = m.alt - self.notify_attribute_listeners('location', self.location) self._airspeed = m.airspeed self.notify_attribute_listeners('airspeed', self.airspeed) self._groundspeed = m.groundspeed @@ -899,7 +948,7 @@ def listener(self, name, msg): if not self._wp_loaded: if msg.seq == 0: if not (msg.x == 0 and msg.y == 0 and msg.z == 0): - self._home_location = LocationGlobal(msg.x, msg.y, msg.z, is_relative=False) + self._home_location = LocationGlobal(msg.x, msg.y, msg.z) if msg.seq > self._wploader.count(): # Unexpected waypoint @@ -1156,11 +1205,7 @@ def mode(self, v): @property def location(self): - # For backward compatibility, this is (itself) a LocationLocal object. - ret = LocationGlobal(self._lat, self._lon, self._alt, is_relative=True) - ret.local_frame = LocationLocal(self._north, self._east, self._down) - ret.global_frame = LocationGlobal(self._lat, self._lon, self._alt, is_relative=True) - return ret + return self._location @property def battery(self): @@ -1846,7 +1891,7 @@ def goto(self, l): vehicle.mode = VehicleMode("GUIDED") # Set the LocationGlobal to head towards - a_location = LocationGlobal(-34.364114, 149.166022, 30, is_relative=True) + a_location = LocationGlobal(-34.364114, 149.166022, 30) vehicle.commands.goto(a_location) :param LocationGlobal location: The target location. diff --git a/dronekit/test/sitl/test_goto.py b/dronekit/test/sitl/test_goto.py index fb3468a78..5dc67cd78 100644 --- a/dronekit/test/sitl/test_goto.py +++ b/dronekit/test/sitl/test_goto.py @@ -8,7 +8,7 @@ """ import time -from dronekit import connect, VehicleMode, LocationGlobal +from dronekit import connect, VehicleMode, LocationGlobalRelative from dronekit.test import with_sitl from nose.tools import assert_equals @@ -71,14 +71,14 @@ def arm_and_takeoff(aTargetAltitude): arm_and_takeoff(10) # print "Going to first point..." - point1 = LocationGlobal(-35.361354, 149.165218, 20, is_relative=True) + point1 = LocationGlobalRelative(-35.361354, 149.165218, 20) vehicle.commands.goto(point1) # sleep so we can see the change in map time.sleep(3) # print "Going to second point..." - point2 = LocationGlobal(-35.363244, 149.168801, 20, is_relative=True) + point2 = LocationGlobalRelative(-35.363244, 149.168801, 20) vehicle.commands.goto(point2) # sleep so we can see the change in map diff --git a/examples/drone_delivery/drone_delivery.py b/examples/drone_delivery/drone_delivery.py index 70cda418b..947be6234 100644 --- a/examples/drone_delivery/drone_delivery.py +++ b/examples/drone_delivery/drone_delivery.py @@ -109,13 +109,20 @@ def change_mode(self, mode): def goto(self, location, relative=None): self._log("Goto: {0}, {1}".format(location, self.altitude)) - self.commands.goto( - LocationGlobal( - float(location[0]), float(location[1]), - float(self.altitude), - is_relative=relative + if relative: + self.commands.goto( + LocationGlobalRelative( + float(location[0]), float(location[1]), + float(self.altitude) + ) + ) + else: + self.commands.goto( + LocationGlobal( + float(location[0]), float(location[1]), + float(self.altitude) + ) ) - ) self.vehicle.flush() def get_location(self): diff --git a/examples/follow_me/follow_me.py b/examples/follow_me/follow_me.py index 4f50801db..7f255c1d2 100644 --- a/examples/follow_me/follow_me.py +++ b/examples/follow_me/follow_me.py @@ -86,7 +86,7 @@ def arm_and_takeoff(aTargetAltitude): # Once we have a valid location (see gpsd documentation) we can start moving our vehicle around if (gpsd.valid & gps.LATLON_SET) != 0: altitude = 30 # in meters - dest = LocationGlobal(gpsd.fix.latitude, gpsd.fix.longitude, altitude, is_relative=True) + dest = LocationGlobalRelative(gpsd.fix.latitude, gpsd.fix.longitude, altitude) print "Going to: %s" % dest # A better implementation would only send new waypoints if the position had changed significantly diff --git a/examples/mission_basic/mission_basic.py b/examples/mission_basic/mission_basic.py index 8a438f4bd..6e4477328 100644 --- a/examples/mission_basic/mission_basic.py +++ b/examples/mission_basic/mission_basic.py @@ -73,7 +73,7 @@ def distance_to_current_waypoint(): lat=missionitem.x lon=missionitem.y alt=missionitem.z - targetWaypointLocation=LocationGlobal(lat,lon,alt,is_relative=True) + targetWaypointLocation=LocationGlobalRelative(lat,lon,alt) distancetopoint = get_distance_metres(vehicle.location.global_frame, targetWaypointLocation) return distancetopoint diff --git a/examples/simple_goto/simple_goto.py b/examples/simple_goto/simple_goto.py index a0d5c8985..3d6542634 100644 --- a/examples/simple_goto/simple_goto.py +++ b/examples/simple_goto/simple_goto.py @@ -63,14 +63,14 @@ def arm_and_takeoff(aTargetAltitude): print "Going to first point..." -point1 = LocationGlobal(-35.361354, 149.165218, 20, is_relative=True) +point1 = LocationGlobalRelative(-35.361354, 149.165218, 20) vehicle.commands.goto(point1) # sleep so we can see the change in map time.sleep(30) print "Going to second point..." -point2 = LocationGlobal(-35.363244, 149.168801, 20, is_relative=True) +point2 = LocationGlobalRelative(-35.363244, 149.168801, 20) vehicle.commands.goto(point2) # sleep so we can see the change in map From bcfff544d34672190168fd80d61db3cbef640fb7 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 13 Nov 2015 16:53:13 +1100 Subject: [PATCH 203/475] Fixes to API ref, example, documentation --- docs/examples/vehicle_state.rst | 16 +-- docs/guide/vehicle_state_and_parameters.rst | 2 + dronekit/lib/__init__.py | 105 +++++++++++++++----- examples/vehicle_state/vehicle_state.py | 1 + 4 files changed, 93 insertions(+), 31 deletions(-) diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index 7c605c132..47fdd1c69 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -58,7 +58,8 @@ On the command prompt you should see (something like): >>> GROUND START Get all vehicle attribute values: - Global Location: LocationGlobal:lat=-35.363261,lon=149.1652299,alt=0.0,is_relative=False + Global Location: LocationGlobal:lat=-35.363261,lon=149.1652299,alt=584 + Global Location (relative altitude): LocationGlobalRelative:lat=-35.363261,lon=149.1652299,alt=362 Local Location: LocationLocal:north=None,east=None,down=None Attitude: Attitude:pitch=0.00294387154281,yaw=-0.11805768311,roll=0.00139428151306 Velocity: [-0.03, 0.02, 0.0] @@ -81,11 +82,11 @@ On the command prompt you should see (something like): Waiting for home location ... Waiting for home location ... - Home location: LocationGlobal:lat=-35.3632621765,lon=149.165237427,alt=583.989990234,is_relative=False + Home location: LocationGlobal:lat=-35.3632621765,lon=149.165237427,alt=583.989990234 Set new home location - New Home Location (from attribute - altitude should be 222): LocationGlobal:lat=-35.363261,lon=149.1652299,alt=222,is_relative=False - New Home Location (from vehicle - altitude should be 222): LocationGlobal:lat=-35.3632621765,lon=149.165237427,alt=222.0,is_relative=False + New Home Location (from attribute - altitude should be 222): LocationGlobal:lat=-35.363261,lon=149.1652299,alt=222 + New Home Location (from vehicle - altitude should be 222): LocationGlobal:lat=-35.3632621765,lon=149.165237427,alt=222.0 Set Vehicle.mode=GUIDED (currently: STABILIZE) Waiting for mode change ... @@ -121,13 +122,13 @@ On the command prompt you should see (something like): Wait 1s so callback invoked before observer removed CALLBACK: (attitude): Attitude:pitch=0.00716688157991,yaw=-0.0950401723385,roll=0.00759896961972 CALLBACK: (heading): 354 - CALLBACK: (location): LocationGlobal:lat=-35.3632621,lon=149.1652291,alt=362.0,is_relative=False + CALLBACK: (location): CALLBACK: (airspeed): 0.0 CALLBACK: (groundspeed): 0.0 CALLBACK: (ekf_ok): True CALLBACK: (battery): Battery:voltage=12.538,current=3.48,level=99 CALLBACK: (gps_0): GPSInfo:fix=3,num_sat=10 - CALLBACK: (location): LocationGlobal:lat=-35.3632622,lon=149.1652295,alt=362.0,is_relative=False + CALLBACK: (location): CALLBACK: (velocity): [-0.14, 0.1, 0.0] CALLBACK: (local_position): LocationLocal:north=-0.136136248708,east=-0.0430941730738,down=-0.00938374921679 CALLBACK: (channels): {'1': 1500, '3': 1000, '2': 1500, '5': 1800, '4': 1500, '7': 1000, '6': 1000, '8': 1800} @@ -191,7 +192,8 @@ This example has no known issues. Source code =========== -The full source code at documentation build-time is listed below (`current version on github `_): +The full source code at documentation build-time is listed below +(`current version on github `_): .. literalinclude:: ../../examples/vehicle_state/vehicle_state.py :language: python diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index 4425d545b..594299382 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -22,6 +22,7 @@ Attributes Vehicle state information is exposed through vehicle *attributes*. DroneKit-Python currently supports the following "standard" attributes: :py:attr:`Vehicle.location.global_frame `, +:py:attr:`Vehicle.location.global_relative_frame `, :py:attr:`Vehicle.location.local_frame `, :py:attr:`Vehicle.attitude `, :py:attr:`Vehicle.velocity `, @@ -65,6 +66,7 @@ regularly updated from MAVLink messages sent by the vehicle). # vehicle is an instance of the Vehicle class print "Global Location: %s" % vehicle.location.global_frame + print "Global Location (relative altitude): %s" % vehicle.location.global_relative_frame print "Local Location: %s" % vehicle.location.local_frame #NED print "Attitude: %s" % vehicle.attitude print "Velocity: %s" % vehicle.velocity diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 18f8428c8..ec8293b74 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -103,20 +103,22 @@ class LocationGlobal(object): A global location object. The latitude and longitude are relative to the `WGS84 coordinate system `_. - The altitude is relative to either the *home position* or "mean sea-level", depending on the value of the ``is_relative``. + The altitude is relative to mean sea-level (MSL). - For example, a global location object might be defined as: + For example, a global location object with altitude 30 metres above sea level might be defined as: .. code:: python LocationGlobal(-34.364114, 149.166022, 30) .. todo:: FIXME: Location class - possibly add a vector3 representation. + + An object of this type is owned by :py:attr:`Vehicle.location`. See that class for information on + reading and observing location in the global frame. :param lat: Latitude. :param lon: Longitude. - :param alt: Altitude in meters (either relative or absolute). - :param is_relative: ``True`` if the specified altitude is relative to a 'home' location (this is usually desirable). ``False`` to set altitude relative to "mean sea-level". + :param alt: Altitude in meters relative to mean sea-level (MSL). """ def __init__(self, lat, lon, alt=None): self.lat = lat @@ -134,23 +136,25 @@ def __str__(self): class LocationGlobalRelative(object): """ - A global location object relative to home location. + A global location object, with attitude relative to home location altitude. The latitude and longitude are relative to the `WGS84 coordinate system `_. - The altitude is relative to either the *home position* or "mean sea-level", depending on the value of the ``is_relative``. + The altitude is relative to the *home position*. - For example, a global location object might be defined as: + For example, a ``LocationGlobalRelative`` object with an altitude of 30 metres above the home location might be defined as: .. code:: python - LocationGlobalRelative(-34.364114, 149.166022, 0) + LocationGlobalRelative(-34.364114, 149.166022, 30) .. todo:: FIXME: Location class - possibly add a vector3 representation. + + An object of this type is owned by :py:attr:`Vehicle.location`. See that class for information on + reading and observing location in the global-relative frame. :param lat: Latitude. :param lon: Longitude. - :param alt: Altitude in meters (either relative or absolute). - :param is_relative: ``True`` if the specified altitude is relative to a 'home' location (this is usually desirable). ``False`` to set altitude relative to "mean sea-level". + :param alt: Altitude in meters (relative to the home location). """ def __init__(self, lat, lon, alt=None): self.lat = lat @@ -170,7 +174,10 @@ class LocationLocal(object): """ A local location object. - The north, east and down are relative to the EKF origin. This is most likely the location where the vehicle was turned on. + The north, east and down are relative to the EKF origin. This is most likely the location where the vehicle was turned on. + + An object of this type is owned by :py:attr:`Vehicle.location`. See that class for information on + reading and observing location in the local frame. :param north: Position north of the EKF origin in meters. :param east: Position east of the EKF origin in meters. @@ -629,7 +636,16 @@ def overrides(self, newch): class Locations(HasObservers): """ - Locations. + An object for holding location information in global, global relative and local frames. + + The different frames are accessed through the members: + + * ``global_frame`` (a :py:class:`LocationGlobal`) + * ``global_frame_relative`` (a :py:class:`LocationGlobalRelative`) + * ``local_frame`` (a :py:class:`LocationLocal`) + + :py:class:`Vehicle` owns an object of this type. See :py:attr:`Vehicle.location` for information on + reading and observing location in the different frames. """ def __init__(self): super(Locations, self).__init__() @@ -658,14 +674,6 @@ class Vehicle(HasObservers): **Standard attributes & types:** - .. py:attribute:: location.global_frame - - Current :py:class:`LocationGlobal`. - - .. py:attribute:: location.local_frame - - Current :py:class:`LocationLocal`. - .. py:attribute:: attitude Current vehicle :py:class:`Attitude` (pitch, yaw, roll). @@ -776,7 +784,7 @@ def listener(_, msg): @self.on_message('GLOBAL_POSITION_INT') def listener(self, name, m): (self._lat, self._lon) = (m.lat / 1.0e7, m.lon / 1.0e7) - (self._alt, self._relative_alt) = (m.alt, m.relative_alt) + (self._alt, self._relative_alt) = (m.alt / 1000, m.relative_alt/1000) self._location.global_frame = LocationGlobal(self._lat, self._lon, self._alt) self._location.global_relative_frame = LocationGlobalRelative(self._lat, self._lon, self._relative_alt) self.notify_attribute_listeners('location', self.location) @@ -1205,6 +1213,55 @@ def mode(self, v): @property def location(self): + """ + A :py:class:`Locations` object containing vehicle location information in + global, global relative and local frames. + + The different frames are accessed through its members: + + * ``global_frame`` (a :py:class:`LocationGlobal`) + * ``global_frame_relative`` (a :py:class:`LocationGlobalRelative`) + * ``local_frame`` (a :py:class:`LocationLocal`) + + For example, to print the location in each frame for a ``vehicle``: + + .. code-block:: python + + # Print location information for `vehicle` in all frames (default printer) + print "Global Location: %s" % vehicle.location.global_frame + print "Global Location (relative altitude): %s" % vehicle.location.global_relative_frame + print "Local Location: %s" % vehicle.location.local_frame #NED + + # Print altitudes in the different frames (see class definitions for other available information) + print "Altitude (global frame): %s" % vehicle.location.global_frame.alt + print "Altitude (global relative frame): %s" % vehicle.location.global_relative_frame.alt + print "Altitude (NED frame): %s" % vehicle.location.local_frame.down + + The attribute and its members are observable. To watch for changes in all frames using a listener + created using a decorator (you can also define a listener and explicitly add it). + + .. code-block:: python + + @vehicle.on_attribute('location') + def listener(self, attr_name, value): + # `self`: :py:class:`Vehicle` object that has been updated. + # `attr_name`: name of the observed attribute - 'location' + # `value` is the updated attribute value (a :py:class:`Locations`). This can be queried for the frame information + print " Global: %s" % value.global_frame + print " GlobalRelative: %s" % value.global_relative_frame + print " Local: %s" % value.local_frame + + To watch for changes in just one attribute: + + .. code-block:: python + + @vehicle.on_attribute('global_frame') + def listener(self, attr_name, value): + # `self`: :py:class:`Locations` object that has been updated. + # `attr_name`: name of the observed attribute - 'global_frame' + # `value` is the updated attribute value. + print " Global: %s" % value + """ return self._location @property @@ -1532,7 +1589,7 @@ def wait_ready(self, *types, **kwargs): By default, the method will timeout after 30 seconds and raise an exception if the attributes were not populated. - :param *types: ``True`` to wait on the default set of attributes, or a + :param types: ``True`` to wait on the default set of attributes, or a comma-separated list of the specific attributes to wait on. :param int timeout: Timeout in seconds after which the method will raise an exception (the default) or return ``False``. The default timeout is 30 seconds. @@ -1681,7 +1738,7 @@ def thr_min_callback(self, attr_name, value): See :ref:`vehicle_state_observing_parameters` for more information. :param String attr_name: The name of the parameter to watch (or '*' to watch all parameters). - :param *args: The callback to invoke when a change in the parameter is detected. + :param args: The callback to invoke when a change in the parameter is detected. """ attr_name = attr_name.upper() @@ -1700,7 +1757,7 @@ def remove_attribute_listener(self, attr_name, *args, **kwargs): See :ref:`vehicle_state_observing_parameters` for more information. :param String attr_name: The parameter name that is to have an observer removed (or '*' to remove an 'all attribute' observer). - :param *args: The callback function to remove. + :param args: The callback function to remove. """ attr_name = attr_name.upper() diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 2b09e03c0..f4a83b568 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -28,6 +28,7 @@ # Get all vehicle attributes (state) print "\nGet all vehicle attribute values:" print " Global Location: %s" % vehicle.location.global_frame +print " Global Location (relative altitude): %s" % vehicle.location.global_relative_frame print " Local Location: %s" % vehicle.location.local_frame print " Attitude: %s" % vehicle.attitude print " Velocity: %s" % vehicle.velocity From dbc39dae7b27580d42c9974675d256eeba923cbb Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 13 Nov 2015 11:54:18 -0800 Subject: [PATCH 204/475] Removes is_relative from LocationGlobal*. --- dronekit/lib/__init__.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index ec8293b74..030148b29 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -124,7 +124,6 @@ def __init__(self, lat, lon, alt=None): self.lat = lat self.lon = lon self.alt = alt - self.is_relative = False # This is for backward compatibility. self.local_frame = None @@ -160,7 +159,6 @@ def __init__(self, lat, lon, alt=None): self.lat = lat self.lon = lon self.alt = alt - self.is_relative = True # This is for backward compatibility. self.local_frame = None @@ -1936,9 +1934,9 @@ def takeoff(self, alt=None): 0, 0, 0, 0, 0, 0, 0, altitude) - def goto(self, l): + def goto(self, location): ''' - Go to a specified global location (:py:class:`LocationGlobal`). + Go to a specified global location (:py:class:`LocationGlobal` or :py:class:`LocationGlobalRelative`). The method will change the :py:class:`VehicleMode` to ``GUIDED`` if necessary. @@ -1953,15 +1951,18 @@ def goto(self, l): :param LocationGlobal location: The target location. ''' - if l.is_relative: + if isinstance(location, LocationGlobalRelative): frame = mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT - else: + elif isinstance(location, LocationGlobal): frame = mavutil.mavlink.MAV_FRAME_GLOBAL + else: + raise APIException('Expecting location to be LocationGlobal or LocationGlobalRelative.') + self._vehicle._master.mav.mission_item_send(0, 0, 0, frame, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 2, 0, 0, 0, 0, 0, - l.lat, l.lon, l.alt) + location.lat, location.lon, location.alt) def clear(self): ''' From 89b89bd0a9ae87f17fa7c28a8b5ff714aa2c22fc Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 13 Nov 2015 12:10:39 -0800 Subject: [PATCH 205/475] Fixes localposition. Allows wait_ready on location.local_frame. --- dronekit/lib/__init__.py | 5 ++++- dronekit/test/sitl/test_localposition.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 030148b29..0f3dc8b3e 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -786,7 +786,9 @@ def listener(self, name, m): self._location.global_frame = LocationGlobal(self._lat, self._lon, self._alt) self._location.global_relative_frame = LocationGlobalRelative(self._lat, self._lon, self._relative_alt) self.notify_attribute_listeners('location', self.location) + self.notify_attribute_listeners('location.global_frame', self.location.global_frame) self.location.notify_attribute_listeners('global_frame', self.location.global_frame) + self.notify_attribute_listeners('location.global_relative_frame', self.location.global_relative_frame) self.location.notify_attribute_listeners('global_relative_frame', self.location.global_relative_frame) (self._vx, self._vy, self._vz) = (m.vx / 100.0, m.vy / 100.0, m.vz / 100.0) @@ -801,8 +803,9 @@ def listener(self, name, m): self._north = m.x self._east = m.y self._down = m.z - self._location._local_frame = LocationLocal(self._north, self._east, self._down) + self._location.local_frame = LocationLocal(self._north, self._east, self._down) self.notify_attribute_listeners('location', self.location) + self.notify_attribute_listeners('location.local_frame', self.location.local_frame) self.location.notify_attribute_listeners('local_frame', self.location.local_frame) self._pitch = None diff --git a/dronekit/test/sitl/test_localposition.py b/dronekit/test/sitl/test_localposition.py index ebf433f23..cf0f549dc 100644 --- a/dronekit/test/sitl/test_localposition.py +++ b/dronekit/test/sitl/test_localposition.py @@ -60,7 +60,7 @@ def arm_and_takeoff(aTargetAltitude): time.sleep(1) arm_and_takeoff(10) - vehicle.wait_ready('local_position', timeout=60) + vehicle.wait_ready('location.local_frame', timeout=60) # .north, .east, and .down are initialized to None. # Any other value suggests that a LOCAL_POSITION_NED was received and parsed. From b1d5d911fe128c9eae9fb3a71c5b99ad4e7ff5e5 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 13 Nov 2015 12:15:03 -0800 Subject: [PATCH 206/475] Makes generic locations test. Checks location.on_attribute. --- .../{test_localposition.py => test_locations.py} | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) rename dronekit/test/sitl/{test_localposition.py => test_locations.py} (86%) diff --git a/dronekit/test/sitl/test_localposition.py b/dronekit/test/sitl/test_locations.py similarity index 86% rename from dronekit/test/sitl/test_localposition.py rename to dronekit/test/sitl/test_locations.py index cf0f549dc..a8ef6f87c 100644 --- a/dronekit/test/sitl/test_localposition.py +++ b/dronekit/test/sitl/test_locations.py @@ -69,3 +69,19 @@ def arm_and_takeoff(aTargetAltitude): assert_not_equals(vehicle.location.local_frame.down, None) vehicle.close() + +@with_sitl +def test_location_notify(connpath): + vehicle = connect(connpath) + + ret = {'success': False} + @vehicle.location.on_attribute('global_frame') + def callback(*args): + ret['success'] = True + + i = 15 + while i > 0 and not ret['success']: + time.sleep(1) + i = i - 1 + + assert ret['success'], 'Expected location object to emit notifications.' From 135b62ff527f3aae9768fbbf55584da841d84ead Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 13 Nov 2015 13:10:34 -0800 Subject: [PATCH 207/475] Waits for non-0 alt on global_frame. --- dronekit/lib/__init__.py | 14 ++++++++++---- dronekit/test/sitl/test_locations.py | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 0f3dc8b3e..ea80aef87 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -782,15 +782,21 @@ def listener(_, msg): @self.on_message('GLOBAL_POSITION_INT') def listener(self, name, m): (self._lat, self._lon) = (m.lat / 1.0e7, m.lon / 1.0e7) - (self._alt, self._relative_alt) = (m.alt / 1000, m.relative_alt/1000) - self._location.global_frame = LocationGlobal(self._lat, self._lon, self._alt) + self._relative_alt = m.relative_alt/1000 self._location.global_relative_frame = LocationGlobalRelative(self._lat, self._lon, self._relative_alt) + self.notify_attribute_listeners('location', self.location) - self.notify_attribute_listeners('location.global_frame', self.location.global_frame) - self.location.notify_attribute_listeners('global_frame', self.location.global_frame) self.notify_attribute_listeners('location.global_relative_frame', self.location.global_relative_frame) self.location.notify_attribute_listeners('global_relative_frame', self.location.global_relative_frame) + if self._alt != None or m.alt != 0: + # Require first alt value to be non-0 + # TODO is this the proper check to do? + self._alt = m.alt/1000 + self._location.global_frame = LocationGlobal(self._lat, self._lon, self._alt) + self.notify_attribute_listeners('location.global_frame', self.location.global_frame) + self.location.notify_attribute_listeners('global_frame', self.location.global_frame) + (self._vx, self._vy, self._vz) = (m.vx / 100.0, m.vy / 100.0, m.vz / 100.0) self.notify_attribute_listeners('velocity', self.velocity) diff --git a/dronekit/test/sitl/test_locations.py b/dronekit/test/sitl/test_locations.py index a8ef6f87c..47e50e466 100644 --- a/dronekit/test/sitl/test_locations.py +++ b/dronekit/test/sitl/test_locations.py @@ -77,6 +77,7 @@ def test_location_notify(connpath): ret = {'success': False} @vehicle.location.on_attribute('global_frame') def callback(*args): + assert_not_equals(args[2].alt, 0) ret['success'] = True i = 15 From 0bcb94afd99673296032e24f55301b72aab7a075 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 13 Nov 2015 13:29:34 -0800 Subject: [PATCH 208/475] Adds error exception in message listener. --- dronekit/mavlink.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dronekit/mavlink.py b/dronekit/mavlink.py index 54e9b3ab4..78e5b3ceb 100644 --- a/dronekit/mavlink.py +++ b/dronekit/mavlink.py @@ -112,7 +112,11 @@ def mavlink_thread(): # Message listeners. for fn in self.message_listeners: - fn(self, msg) + try: + fn(self, msg) + except Exception as e: + errprinter('>>> Exception in message handler for %s' % msg.get_type()) + errprinter('>>> ' + str(e)) except APIException as e: errprinter('>>> ' + str(e.message)) From 2b1a213206d720223e4a08fb4fd99b03dad9c625 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 16 Nov 2015 15:42:35 +1100 Subject: [PATCH 209/475] Fix up examples to test against isarmable, Fix up location accesses to relative. --- docs/examples/vehicle_state.rst | 4 +-- docs/guide/vehicle_state_and_parameters.rst | 23 ++++++++---- dronekit/lib/__init__.py | 36 ++++++++++++++----- examples/follow_me/follow_me.py | 23 ++++++------ .../guided_set_speed_yaw.py | 28 +++++++-------- examples/mission_basic/mission_basic.py | 27 ++++++-------- examples/simple_goto/simple_goto.py | 6 ++-- 7 files changed, 84 insertions(+), 63 deletions(-) diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index 47fdd1c69..e44c9d3c1 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -58,9 +58,9 @@ On the command prompt you should see (something like): >>> GROUND START Get all vehicle attribute values: - Global Location: LocationGlobal:lat=-35.363261,lon=149.1652299,alt=584 + Global Location: None Global Location (relative altitude): LocationGlobalRelative:lat=-35.363261,lon=149.1652299,alt=362 - Local Location: LocationLocal:north=None,east=None,down=None + Local Location: None Attitude: Attitude:pitch=0.00294387154281,yaw=-0.11805768311,roll=0.00139428151306 Velocity: [-0.03, 0.02, 0.0] GPS: GPSInfo:fix=3,num_sat=10 diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index 594299382..ca2ac97a0 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -21,9 +21,9 @@ Attributes Vehicle state information is exposed through vehicle *attributes*. DroneKit-Python currently supports the following "standard" attributes: -:py:attr:`Vehicle.location.global_frame `, -:py:attr:`Vehicle.location.global_relative_frame `, -:py:attr:`Vehicle.location.local_frame `, +:py:attr:`Vehicle.location.global_frame `, +:py:attr:`Vehicle.location.global_relative_frame `, +:py:attr:`Vehicle.location.local_frame `, :py:attr:`Vehicle.attitude `, :py:attr:`Vehicle.velocity `, :py:attr:`Vehicle.airspeed `, @@ -171,7 +171,7 @@ The ``observer`` callback function is invoked with the following arguments: * ``value`` - the attribute value (so you don't need to re-query the vehicle object). The code snippet below shows how to add (and remove) a callback function to observe changes -in :py:attr:`Vehicle.location.global_frame ` using +in :py:attr:`Vehicle.location.global_frame ` using :py:func:`Vehicle.add_attribute_listener() `. The two second ``sleep()`` is required because otherwise the observer might be removed before the the callback is first run. @@ -186,13 +186,24 @@ callback is first run. # Add a callback `location_callback` for the `global_frame` attribute. - vehicle.add_attribute_listener('global_frame', location_callback) + vehicle.add_attribute_listener('location.global_frame', location_callback) # Wait 2s so callback can be notified before the observer is removed time.sleep(2) # Remove observer - specifying the attribute and previously registered callback function - vehicle.remove_message_listener('location', location_callback) + vehicle.remove_message_listener('location.global_frame', location_callback) + +.. note:: + + The example above adds a listener on ``Vehicle`` to for attribute name ``'location.global_frame'`` + You can alternatively add (and remove) a listener ``Vehicle.location`` for the attribute name ``'global_frame'``. + Both alternatives are shown below: + + .. code-block:: python + + vehicle.add_attribute_listener('location.global_frame', location_callback) + vehicle.location.add_attribute_listener('global_frame', location_callback) The example below shows how you can declare an attribute callback using the diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index ea80aef87..bb3b42bdd 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -636,14 +636,32 @@ class Locations(HasObservers): """ An object for holding location information in global, global relative and local frames. - The different frames are accessed through the members: - - * ``global_frame`` (a :py:class:`LocationGlobal`) - * ``global_frame_relative`` (a :py:class:`LocationGlobalRelative`) - * ``local_frame`` (a :py:class:`LocationLocal`) - :py:class:`Vehicle` owns an object of this type. See :py:attr:`Vehicle.location` for information on reading and observing location in the different frames. + + The different frames are accessed through the members. These can be read, and are observable. + + .. py:attribute:: global_frame + + Location in global frame (a :py:class:`LocationGlobal`). + + The altitude for global frame may take some time to populate. + + .. py:attribute:: global_frame_relative + + Location in global frame, with altitude relative to the home location + (a :py:class:`LocationGlobalRelative`) + + .. py:attribute:: local_frame + + Location in local NED frame (a :py:class:`LocationGlobalRelative`). + + This location will not start to update until the vehicle is armed. + + + + + """ def __init__(self): super(Locations, self).__init__() @@ -1258,16 +1276,18 @@ def listener(self, attr_name, value): print " GlobalRelative: %s" % value.global_relative_frame print " Local: %s" % value.local_frame - To watch for changes in just one attribute: + To watch for changes in just one attribute (in this case ``global_frame``): .. code-block:: python - @vehicle.on_attribute('global_frame') + @vehicle.on_attribute('location.global_frame') def listener(self, attr_name, value): # `self`: :py:class:`Locations` object that has been updated. # `attr_name`: name of the observed attribute - 'global_frame' # `value` is the updated attribute value. print " Global: %s" % value + + #Or watch using decorator: ``@vehicle.location.on_attribute('global_frame')``. """ return self._location diff --git a/examples/follow_me/follow_me.py b/examples/follow_me/follow_me.py index 7f255c1d2..184fa7a34 100644 --- a/examples/follow_me/follow_me.py +++ b/examples/follow_me/follow_me.py @@ -33,23 +33,22 @@ def arm_and_takeoff(aTargetAltitude): """ - Arm vehicle and fly to aTargetAltitude. + Arms vehicle and fly to aTargetAltitude. """ + print "Basic pre-arm checks" - # Don't let the user try to fly while autopilot is booting - if vehicle.mode.name == "INITIALISING": - print "Waiting for vehicle to initialise" - time.sleep(1) - while vehicle.gps_0.fix_type < 2: - print "Waiting for GPS...:", vehicle.gps_0.fix_type + # Don't let the user try to arm until autopilot is ready + while not vehicle.is_armable: + print " Waiting for vehicle to initialise..." time.sleep(1) + print "Arming motors" # Copter should arm in GUIDED mode vehicle.mode = VehicleMode("GUIDED") - vehicle.armed = True + vehicle.armed = True - while not vehicle.armed: + while not vehicle.armed: print " Waiting for arming..." time.sleep(1) @@ -59,10 +58,10 @@ def arm_and_takeoff(aTargetAltitude): # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.commands.takeoff will execute immediately). while True: - print " Altitude: ", vehicle.location.global_frame.alt - if vehicle.location.global_frame.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. + print " Altitude: ", vehicle.location.global_relative_frame.alt + if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: #Trigger just below target alt. print "Reached target altitude" - break; + break time.sleep(1) diff --git a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py index fecc8942d..2a3f02bca 100644 --- a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py +++ b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py @@ -28,25 +28,23 @@ def arm_and_takeoff(aTargetAltitude): """ - Arm vehicle and fly to aTargetAltitude. + Arms vehicle and fly to aTargetAltitude. """ + print "Basic pre-arm checks" - # Don't let the user try to fly while autopilot is booting - if vehicle.mode.name == "INITIALISING": - print "Waiting for vehicle to initialise" - time.sleep(1) - while vehicle.gps_0.fix_type < 2: - print "Waiting for GPS...:", vehicle.gps_0.fix_type + # Don't let the user try to arm until autopilot is ready + while not vehicle.is_armable: + print " Waiting for vehicle to initialise..." time.sleep(1) + print "Arming motors" # Copter should arm in GUIDED mode vehicle.mode = VehicleMode("GUIDED") - vehicle.armed = True + vehicle.armed = True - while not vehicle.armed: + while not vehicle.armed: print " Waiting for arming..." - vehicle.armed = True time.sleep(1) print "Taking off!" @@ -55,10 +53,10 @@ def arm_and_takeoff(aTargetAltitude): # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.commands.takeoff will execute immediately). while True: - print " Altitude: ", vehicle.location.global_frame.alt - if vehicle.location.global_frame.alt>=aTargetAltitude*0.95: #Trigger just below target alt. + print " Altitude: ", vehicle.location.global_relative_frame.alt + if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: #Trigger just below target alt. print "Reached target altitude" - break; + break time.sleep(1) @@ -474,7 +472,7 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z): print("Point ROI at current location (home position)") # NOTE that this has to be called after the goto command as first "move" command of a particular type # "resets" ROI/YAW commands -set_roi(vehicle.location.global_frame) +set_roi(vehicle.location.global_relative_frame) time.sleep(DURATION) print("North 50m, East 50m, 10m altitude") @@ -482,7 +480,7 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z): time.sleep(DURATION) print("Point ROI at current location") -set_roi(vehicle.location.global_frame) +set_roi(vehicle.location.global_relative_frame) print("North 0m, East 50m, 10m altitude") goto_position_target_local_ned(0,50,-10) diff --git a/examples/mission_basic/mission_basic.py b/examples/mission_basic/mission_basic.py index 6e4477328..b5c34d467 100644 --- a/examples/mission_basic/mission_basic.py +++ b/examples/mission_basic/mission_basic.py @@ -128,27 +128,20 @@ def arm_and_takeoff(aTargetAltitude): """ Arms vehicle and fly to aTargetAltitude. """ + print "Basic pre-arm checks" - # Don't let the user try to fly autopilot is booting - if vehicle.mode.name == "INITIALISING": - print "Waiting for vehicle to initialise" - time.sleep(1) - else: - print "MODE: %s" % vehicle.mode.name - - while vehicle.gps_0.fix_type < 2: - print "Waiting for GPS...:", vehicle.gps_0.fix_type + # Don't let the user try to arm until autopilot is ready + while not vehicle.is_armable: + print " Waiting for vehicle to initialise..." time.sleep(1) - # Wait for EKF to settle. - time.sleep(5) - + print "Arming motors" # Copter should arm in GUIDED mode vehicle.mode = VehicleMode("GUIDED") - vehicle.armed = True + vehicle.armed = True - while not vehicle.armed: + while not vehicle.armed: print " Waiting for arming..." time.sleep(1) @@ -158,10 +151,10 @@ def arm_and_takeoff(aTargetAltitude): # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.commands.takeoff will execute immediately). while True: - print " Altitude: ", vehicle.location.global_frame.alt - if vehicle.location.global_frame.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. + print " Altitude: ", vehicle.location.global_relative_frame.alt + if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: #Trigger just below target alt. print "Reached target altitude" - break; + break time.sleep(1) diff --git a/examples/simple_goto/simple_goto.py b/examples/simple_goto/simple_goto.py index 3d6542634..da8c67e44 100644 --- a/examples/simple_goto/simple_goto.py +++ b/examples/simple_goto/simple_goto.py @@ -8,7 +8,7 @@ import time from dronekit import connect -from dronekit.lib import VehicleMode, LocationGlobal +from dronekit.lib import VehicleMode, LocationGlobal, LocationGlobalRelative from pymavlink import mavutil import time @@ -53,8 +53,8 @@ def arm_and_takeoff(aTargetAltitude): # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.commands.takeoff will execute immediately). while True: - print " Altitude: ", vehicle.location.global_frame.alt - if vehicle.location.global_frame.alt>=aTargetAltitude*0.95: #Trigger just below target alt. + print " Altitude: ", vehicle.location.global_relative_frame.alt + if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: #Trigger just below target alt. print "Reached target altitude" break time.sleep(1) From c7082062f2b2b9362ecff2806d18c00c4ce62861 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 16 Nov 2015 15:29:03 -0800 Subject: [PATCH 210/475] Populates frames with None values. Fixes float bug in alt. --- dronekit/lib/__init__.py | 93 +++++++++++++++------------- dronekit/test/sitl/test_locations.py | 8 +++ 2 files changed, 57 insertions(+), 44 deletions(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index bb3b42bdd..a5dc3ad80 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -657,17 +657,57 @@ class Locations(HasObservers): Location in local NED frame (a :py:class:`LocationGlobalRelative`). This location will not start to update until the vehicle is armed. - - - - """ - def __init__(self): + def __init__(self, vehicle): super(Locations, self).__init__() - self.local_frame = None - self.global_frame = None - self.global_relative_frame = None + + self._lat = None + self._lon = None + self._alt = None + self._relative_alt = None + + @vehicle.on_message('GLOBAL_POSITION_INT') + def listener(vehicle, name, m): + (self._lat, self._lon) = (m.lat / 1.0e7, m.lon / 1.0e7) + self._relative_alt = m.relative_alt/1000.0 + self.notify_attribute_listeners('global_relative_frame', self.global_relative_frame) + vehicle.notify_attribute_listeners('location.global_relative_frame', vehicle.location.global_relative_frame) + + if self._alt != None or m.alt != 0: + # Require first alt value to be non-0 + # TODO is this the proper check to do? + self._alt = m.alt/1000.0 + self.notify_attribute_listeners('global_frame', self.global_frame) + vehicle.notify_attribute_listeners('location.global_frame', vehicle.location.global_frame) + + vehicle.notify_attribute_listeners('location', vehicle.location) + + self._north = None + self._east = None + self._down = None + + @vehicle.on_message('LOCAL_POSITION_NED') + def listener(vehicle, name, m): + self._north = m.x + self._east = m.y + self._down = m.z + self.notify_attribute_listeners('local_frame', self.local_frame) + vehicle.notify_attribute_listeners('location.local_frame', vehicle.location.local_frame) + vehicle.notify_attribute_listeners('location', vehicle.location) + + @property + def local_frame(self): + return LocationLocal(self._north, self._east, self._down) + + @property + def global_frame(self): + return LocationGlobal(self._lat, self._lon, self._alt) + + @property + def global_relative_frame(self): + return LocationGlobalRelative(self._lat, self._lon, self._relative_alt) + class Vehicle(HasObservers): """ @@ -787,51 +827,16 @@ def listener(_, name, value): def listener(_, msg): self.notify_message_listeners(msg.get_type(), msg) - self._location = Locations() - - self._lat = None - self._lon = None - self._alt = None - self._relative_alt = None + self._location = Locations(self) self._vx = None self._vy = None self._vz = None @self.on_message('GLOBAL_POSITION_INT') def listener(self, name, m): - (self._lat, self._lon) = (m.lat / 1.0e7, m.lon / 1.0e7) - self._relative_alt = m.relative_alt/1000 - self._location.global_relative_frame = LocationGlobalRelative(self._lat, self._lon, self._relative_alt) - - self.notify_attribute_listeners('location', self.location) - self.notify_attribute_listeners('location.global_relative_frame', self.location.global_relative_frame) - self.location.notify_attribute_listeners('global_relative_frame', self.location.global_relative_frame) - - if self._alt != None or m.alt != 0: - # Require first alt value to be non-0 - # TODO is this the proper check to do? - self._alt = m.alt/1000 - self._location.global_frame = LocationGlobal(self._lat, self._lon, self._alt) - self.notify_attribute_listeners('location.global_frame', self.location.global_frame) - self.location.notify_attribute_listeners('global_frame', self.location.global_frame) - (self._vx, self._vy, self._vz) = (m.vx / 100.0, m.vy / 100.0, m.vz / 100.0) self.notify_attribute_listeners('velocity', self.velocity) - self._north = None - self._east = None - self._down = None - - @self.on_message('LOCAL_POSITION_NED') - def listener(self, name, m): - self._north = m.x - self._east = m.y - self._down = m.z - self._location.local_frame = LocationLocal(self._north, self._east, self._down) - self.notify_attribute_listeners('location', self.location) - self.notify_attribute_listeners('location.local_frame', self.location.local_frame) - self.location.notify_attribute_listeners('local_frame', self.location.local_frame) - self._pitch = None self._yaw = None self._roll = None diff --git a/dronekit/test/sitl/test_locations.py b/dronekit/test/sitl/test_locations.py index 47e50e466..a7c48327b 100644 --- a/dronekit/test/sitl/test_locations.py +++ b/dronekit/test/sitl/test_locations.py @@ -68,6 +68,14 @@ def arm_and_takeoff(aTargetAltitude): assert_not_equals(vehicle.location.local_frame.east, None) assert_not_equals(vehicle.location.local_frame.down, None) + # global_frame + assert_not_equals(vehicle.location.global_frame.lat, None) + assert_not_equals(vehicle.location.global_frame.lon, None) + assert_not_equals(vehicle.location.global_frame.alt, None) + assert_equals(type(vehicle.location.global_frame.lat), float) + assert_equals(type(vehicle.location.global_frame.lon), float) + assert_equals(type(vehicle.location.global_frame.alt), float) + vehicle.close() @with_sitl From cfc072bcaab1048c9983c55e029e046cc396cfd3 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 17 Nov 2015 16:35:59 +1100 Subject: [PATCH 211/475] Update docs to reflect new Location behaviour - ie None values for alt, lat, etc --- docs/examples/drone_delivery.rst | 5 +- docs/examples/vehicle_state.rst | 6 +- docs/guide/migrating.rst | 25 +++++++- docs/guide/taking_off.rst | 8 +-- dronekit/lib/__init__.py | 71 +++++++++++++++-------- examples/drone_delivery/drone_delivery.py | 2 +- 6 files changed, 82 insertions(+), 35 deletions(-) diff --git a/docs/examples/drone_delivery.rst b/docs/examples/drone_delivery.rst index 88f781287..4cb321ac6 100644 --- a/docs/examples/drone_delivery.rst +++ b/docs/examples/drone_delivery.rst @@ -105,7 +105,8 @@ How it works Using attribute observers ------------------------- -All attributes in DroneKit can have observers - this is the primary mechanism you should use to be notified of changes in vehicle state. For instance, `drone_delivery.py `_ calls: +All attributes in DroneKit can have observers - this is the primary mechanism you should use to be notified of changes in vehicle state. +For instance, `drone_delivery.py `_ calls: .. code-block:: python @@ -114,7 +115,7 @@ All attributes in DroneKit can have observers - this is the primary mechanism yo ... def location_callback(self, location): - location = self.vehicle.location.global_frame + location = location.global_frame if location.alt is not None: self.altitude = location.alt diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index e44c9d3c1..5e1c91989 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -58,9 +58,9 @@ On the command prompt you should see (something like): >>> GROUND START Get all vehicle attribute values: - Global Location: None - Global Location (relative altitude): LocationGlobalRelative:lat=-35.363261,lon=149.1652299,alt=362 - Local Location: None + Global Location: LocationGlobal:lat=-35.363261,lon=149.1652299,alt=None + Global Location (relative altitude): LocationGlobalRelative:lat=-35.363261,lon=149.1652299,alt=0.0 + Local Location: LocationLocal:north=None,east=None,down=None Attitude: Attitude:pitch=0.00294387154281,yaw=-0.11805768311,roll=0.00139428151306 Velocity: [-0.03, 0.02, 0.0] GPS: GPSInfo:fix=3,num_sat=10 diff --git a/docs/guide/migrating.rst b/docs/guide/migrating.rst index 0ed49cd63..b4f88333f 100644 --- a/docs/guide/migrating.rst +++ b/docs/guide/migrating.rst @@ -170,6 +170,27 @@ Instead, use normal Python methods for getting file system information: full_directory_path_of_current_script = os.path.dirname(os.path.abspath(__file__)) +Vehicle.location +---------------- + +DroneKit-Python v1.x had a ``Vehicle.location`` attribute which provided latitude and longitude information in the +global frame, and altitude either relative to sea-level or the home location (depending on the value of its ``is_relative`` member). + +DKPY2.0 uses and attribute with the same name to provide location in +global, global-relative and local (NED) frames: + +.. code-block:: python + + print "Global Location: %s" % vehicle.location.global_frame + print "Global Location (relative altitude): %s" % vehicle.location.global_relative_frame + print "Local Location: %s" % vehicle.location.local_frame + +For more information see: :py:attr:`Vehicle.location `, +:py:attr:`Vehicle.location.global_frame `, +:py:attr:`Vehicle.location.global_relative_frame `, +:py:attr:`Vehicle.location.local_frame `, and :ref:`vehicle-information`. + + .. _migrating_dkpy2_0_home_location: Home location @@ -278,8 +299,8 @@ See :ref:`mavlink_messages` for more information. New attributes -------------- -In addition to the :ref:`home_location `, a few more attributes have been added, -including: +In addition to the :ref:`home_location `, +a few more attributes have been added, including: :py:func:`Vehicle.system_status `, :py:func:`Vehicle.heading `, :py:func:`Vehicle.mount_status `, diff --git a/docs/guide/taking_off.rst b/docs/guide/taking_off.rst index 242fca390..2093821be 100644 --- a/docs/guide/taking_off.rst +++ b/docs/guide/taking_off.rst @@ -55,8 +55,8 @@ The code below shows a function to arm a Copter, take off, and fly to a specifie # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.commands.takeoff will execute immediately). while True: - print " Altitude: ", vehicle.location.global_frame.alt - if vehicle.location.global_frame.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. + print " Altitude: ", vehicle.location.global_relative_frame.alt + if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. print "Reached target altitude" break time.sleep(1) @@ -127,8 +127,8 @@ concerned about reaching a particular height, a simpler implementation might jus .. code-block:: python while True: - print " Altitude: ", vehicle.location.global_frame.alt - if vehicle.location.global_frame.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. + print " Altitude: ", vehicle.location.global_relative_frame.alt + if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. print "Reached target altitude" break time.sleep(1) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index a5dc3ad80..e9284c3f5 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -639,25 +639,8 @@ class Locations(HasObservers): :py:class:`Vehicle` owns an object of this type. See :py:attr:`Vehicle.location` for information on reading and observing location in the different frames. - The different frames are accessed through the members. These can be read, and are observable. - - .. py:attribute:: global_frame - - Location in global frame (a :py:class:`LocationGlobal`). - - The altitude for global frame may take some time to populate. - - .. py:attribute:: global_frame_relative - - Location in global frame, with altitude relative to the home location - (a :py:class:`LocationGlobalRelative`) - - .. py:attribute:: local_frame - - Location in local NED frame (a :py:class:`LocationGlobalRelative`). - - This location will not start to update until the vehicle is armed. - + The different frames are accessed through the members, which are created with this object. + They can be read, and are observable. """ def __init__(self, vehicle): super(Locations, self).__init__() @@ -698,14 +681,48 @@ def listener(vehicle, name, m): @property def local_frame(self): + """ + Location in local NED frame (a :py:class:`LocationGlobalRelative`). + + This is accessed through the :py:attr:`Vehicle.location ` attribute: + + .. code-block:: python + + print "Local Location: %s" % vehicle.location.local_frame + + This location will not start to update until the vehicle is armed. + """ return LocationLocal(self._north, self._east, self._down) @property def global_frame(self): + """ + Location in global frame (a :py:class:`LocationGlobal`). + + This is accessed through the :py:attr:`Vehicle.location ` attribute: + + .. code-block:: python + + print "Global Location: %s" % vehicle.location.global_frame + + Its ``lat`` and ``lon`` attributes are populated shortly after GPS becomes available. + The ``alt`` can take several seconds longer to populate (from the barometer). + Listeners are not notified of changes to this attribute until it has fully populated. + """ return LocationGlobal(self._lat, self._lon, self._alt) - + @property def global_relative_frame(self): + """ + Location in global frame, with altitude relative to the home location + (a :py:class:`LocationGlobalRelative`). + + This is accessed through the :py:attr:`Vehicle.location ` attribute: + + .. code-block:: python + + print "Global Location (relative altitude): %s" % vehicle.location.global_relative_frame + """ return LocationGlobalRelative(self._lat, self._lon, self._relative_alt) @@ -1249,9 +1266,9 @@ def location(self): The different frames are accessed through its members: - * ``global_frame`` (a :py:class:`LocationGlobal`) - * ``global_frame_relative`` (a :py:class:`LocationGlobalRelative`) - * ``local_frame`` (a :py:class:`LocationLocal`) + * :py:attr:`global_frame ` (a :py:class:`LocationGlobal`) + * :py:attr:`global_relative_frame ` (a :py:class:`LocationGlobalRelative`) + * :py:attr:`local_frame ` (a :py:class:`LocationLocal`) For example, to print the location in each frame for a ``vehicle``: @@ -1266,6 +1283,14 @@ def location(self): print "Altitude (global frame): %s" % vehicle.location.global_frame.alt print "Altitude (global relative frame): %s" % vehicle.location.global_relative_frame.alt print "Altitude (NED frame): %s" % vehicle.location.local_frame.down + + .. note:: + + All the location "values" (e.g. ``global_frame.lat``) are initially + created with value ``None``. The ``global_frame``, ``global_relative_frame`` + latitude and longitude values are populated shortly after initialisation but + ``global_frame.alt`` may take a few seconds longer to be updated. + The ``local_frame`` does not populate until the vehicle is armed. The attribute and its members are observable. To watch for changes in all frames using a listener created using a decorator (you can also define a listener and explicitly add it). diff --git a/examples/drone_delivery/drone_delivery.py b/examples/drone_delivery/drone_delivery.py index 947be6234..b754ed30a 100644 --- a/examples/drone_delivery/drone_delivery.py +++ b/examples/drone_delivery/drone_delivery.py @@ -129,7 +129,7 @@ def get_location(self): return [self.current_location.lat, self.current_location.lon] def location_callback(self, vehicle, name, location): - if location.alt is not None: + if location.global_relative_frame.alt is not None: self.altitude = location.alt self.current_location = location From a06884d06881f4cbd4e68c9bc2a8bf12322ff7d1 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 17 Nov 2015 12:44:01 -0800 Subject: [PATCH 212/475] 2.0.0rc11 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 3f7e5ba04..bb3401b5a 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.0.0rc10' +version = '2.0.0rc11' setup(name='dronekit', zip_safe=True, From 0588aa1862700919172978f5a880384106d5460a Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 18 Nov 2015 10:45:03 +1100 Subject: [PATCH 213/475] updates target_system information in connect, and also the send_mavlink information that relates to it --- docs/guide/copter/guided_mode.rst | 36 ++++++++++++++++++++++++------ dronekit/lib/__init__.py | 37 ++++++++++++++++++++++--------- 2 files changed, 55 insertions(+), 18 deletions(-) diff --git a/docs/guide/copter/guided_mode.rst b/docs/guide/copter/guided_mode.rst index a467a27be..9940b2978 100644 --- a/docs/guide/copter/guided_mode.rst +++ b/docs/guide/copter/guided_mode.rst @@ -133,7 +133,10 @@ The command can be interrupted by a later movement command. When moving the vehi .. tip:: - You can also control the velocity using the `SET_POSITION_TARGET_GLOBAL_INT `_ MAVLink command in almost exactly the same way (there is no real benefit in sending one command over the other). For more information on this option see :ref:`example_guided_mode_send_global_velocity` in the example code. + You can also control the velocity using the + `SET_POSITION_TARGET_GLOBAL_INT `_ + MAVLink command in almost exactly the same way (there is no real benefit in sending one command over the other). + For more information on this option see :ref:`example_guided_mode_send_global_velocity` in the example code. @@ -166,15 +169,27 @@ This section explains how to send MAVLink commands, what commands can be sent, a Sending messages/commands ------------------------- -MAVLink commands are sent by first using :py:func:`message_factory ` to encode the message and then calling :py:func:`send_mavlink ` to send them. +MAVLink commands are sent by first using :py:func:`message_factory() ` +to encode the message and then calling :py:func:`send_mavlink() ` to send them. -``message_factory()`` uses a factory method for the encoding. The name of this method will always be the lower case version of the message/command name with ``_encode`` appended. For example, to encode a `SET_POSITION_TARGET_LOCAL_NED `_ message we call ``message_factory.set_position_target_local_ned_encode()`` with values for all the message fields as arguments: +.. note:: + + Vehicles support a subset of the messages defined in the MAVLink standard. For more information + about the supported sets see wiki topics: + `Copter Commands in Guided Mode `_ + and `Plane Commands in Guided Mode `_. + +``message_factory()`` uses a factory method for the encoding. The name of this method will always be the +lower case version of the message/command name with ``_encode`` appended. For example, to encode a +`SET_POSITION_TARGET_LOCAL_NED `_ +message we call ``message_factory.set_position_target_local_ned_encode()`` with values for all the +message fields as arguments: .. code-block:: python msg = vehicle.message_factory.set_position_target_local_ned_encode( 0, # time_boot_ms (not used) - 0, 0, # target system, target component + 0, 0, # target_system, target_component mavutil.mavlink.MAV_FRAME_BODY_NED, # frame 0b0000111111000111, # type_mask (only speeds enabled) 0, 0, 0, # x, y, z positions @@ -184,16 +199,23 @@ MAVLink commands are sent by first using :py:func:`message_factory `) before sending. +The ``target_component`` should be set to 0 (broadcast) unless the message is to specific component. +CRC fields and sequence numbers (if defined in the message type) are automatically set by DroneKit and can also +be ignored/set to zero. .. _guided_mode_how_to_send_commands_command_long: -In Copter, the `COMMAND_LONG message `_ can be used send/package *a number* of different `supported MAV_CMD commands `_. The factory function is again the lower case message name with suffix ``_encode`` (``message_factory.command_long_encode``). The message parameters include the actual command to be sent (in the code fragment below ``MAV_CMD_CONDITION_YAW``) and its fields. +In Copter, the `COMMAND_LONG message `_ can be used send/package +*a number* of different `supported MAV_CMD commands `_. +The factory function is again the lower case message name with suffix ``_encode`` (``message_factory.command_long_encode``). +The message parameters include the actual command to be sent (in the code fragment below ``MAV_CMD_CONDITION_YAW``) and its fields. .. code-block:: python msg = vehicle.message_factory.command_long_encode( - 0, 0, # target system, target component + 0, 0, # target_system, target_component mavutil.mavlink.MAV_CMD_CONDITION_YAW, #command 0, #confirmation heading, # param 1, yaw in degrees diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index e9284c3f5..a0eb71f9e 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -51,6 +51,10 @@ This can be any sub-class of ``Vehicle`` (and defaults to ``Vehicle``). :param int rate: Data sream refresh rate. The default is 4Hz (4 updates per second). :param int baud: The baud rate for the connection. The default is 115200. + :param int target_system: The MAVLink target_system for the connected vehicle. The default value is 0 (MAVLink broadcast id). + This setting overrides any value for the target system obtained from the vehicle, + and is used in place of any value set by the user in :py:class:`Commands` or when sending messages + (see :py:func:`Vehicle.send_mavlink() `). :returns: A connected vehicle of the type defined in ``vehicle_class`` (a superclass of :py:class:`Vehicle`). @@ -1539,11 +1543,12 @@ def send_mavlink(self, message): """ This method is used to send raw MAVLink "custom messages" to the vehicle. - The function can send arbitrary messages/commands to a vehicle at any time and in any vehicle mode. It is particularly useful for - controlling vehicles outside of missions (for example, in GUIDED mode). + The function can send arbitrary messages/commands to the connected vehicle at any time and in any vehicle mode. + It is particularly useful for controlling vehicles outside of missions (for example, in GUIDED mode). The :py:func:`message_factory ` is used to create messages in the appropriate format. - Callers do not need to populate sysId/componentId/crc in the packet as the method will take care of that before sending. + + For more information see the guide topic: :ref:`guided_mode_how_to_send_commands`. :param message: A ``MAVLink_message`` instance, created using :py:func:`message_factory `. There is need to specify the system id, component id or sequence number of messages as the API will set these appropriately. @@ -1555,8 +1560,15 @@ def message_factory(self): """ Returns an object that can be used to create 'raw' MAVLink messages that are appropriate for this vehicle. The message can then be sent using :py:func:`send_mavlink(message) `. + + .. note:: + + Vehicles support a subset of the messages defined in the MAVLink standard. For more information + about the supported sets see wiki topics: + `Copter Commands in Guided Mode `_ + and `Plane Commands in Guided Mode `_. - These message types are defined in the central MAVLink github repository. For example, a Pixhawk understands + All message types are defined in the central MAVLink github repository. For example, a Pixhawk understands the following messages (from `pixhawk.xml `_): .. code:: xml @@ -1574,12 +1586,13 @@ def message_factory(self): msg = vehicle.message_factory.image_trigger_control_encode(True) vehicle.send_mavlink(msg) - There is no need to specify the system id, component id or sequence number of messages (if defined in the message type) as the - API will set these appropriately when the message is sent. - - .. todo:: When I have a custom message guide topic. Link from here to it. - - .. todo:: Check if the standard MAV_CMD messages can be sent this way too, and if so add link. + There is no need to specify the ``target_system`` id in messages (just set to zero) as DroneKit will automatically + update messages with the vehicle's internal ``target_system`` (see :py:func:`connect() `) before sending. + The ``target_component`` should be set to 0 (broadcast) unless the message is to specific component. + CRC fields and sequence numbers (if defined in the message type) are automatically set by DroneKit and can also + be ignored/set to zero. + + For more information see the guide topic: :ref:`guided_mode_how_to_send_commands`. """ return self._master.mav @@ -1876,7 +1889,9 @@ class Command(mavutil.mavlink.MAVLink_mission_item_message): mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0,-34.364114, 149.166022, 30) :param target_system: The id number of the message's target system (drone, GSC) within the MAVLink network. - Set this to zero (broadcast) when communicating with a companion computer. + This can be set to any value (nominally 0) because it will be overridden by the + vehicle's internal ``target_system`` (as set :py:func:`connect() `). By + default this is the broadcast id. :param target_component: The id of a component the message should be routed to within the target system (for example, the camera). Set to zero (broadcast) in most cases. :param seq: The sequence number within the mission (the autopilot will reject messages sent out of sequence). From 5142a90f37e66ff413492e9581db96d05d03a948 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 17 Nov 2015 18:01:13 -0800 Subject: [PATCH 214/475] Implements target_system lookup. Implements better target semantics. --- dronekit/__init__.py | 4 ++-- dronekit/lib/__init__.py | 5 +++++ dronekit/mavlink.py | 26 ++++++++++++++++++++------ 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 516de230a..2d3b550e0 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -25,8 +25,8 @@ LocationLocal = dronekit.lib.LocationLocal CloudClient = dronekit.lib.CloudClient -def connect(ip, _initialize=True, wait_ready=None, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200, heartbeat_timeout=30, target_system=0): - handler = MAVConnection(ip, baud=baud, target_system=target_system) +def connect(ip, _initialize=True, wait_ready=None, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200, heartbeat_timeout=30, source_system=255): + handler = MAVConnection(ip, baud=baud, source_system=source_system) vehicle = vehicle_class(handler) if status_printer: diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index a0eb71f9e..1a304dd16 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1102,6 +1102,7 @@ def listener(self, name, msg): self._heartbeat_warning = 5 self._heartbeat_error = 30 + self._heartbeat_system = None @handler.forward_loop def listener(_): @@ -1121,6 +1122,7 @@ def listener(_): @self.on_message(['HEARTBEAT']) def listener(self, name, msg): + self._heartbeat_system = msg.get_srcSystem() self._heartbeat_lastreceived = time.time() if self._heartbeat_timeout: errprinter('>>> ...link restored.') @@ -1614,6 +1616,9 @@ def initialize(self, rate=4, heartbeat_timeout=30): if not self._handler._alive: raise APIException('Timeout in initializing connection.') + # Register target_system now. + self._handler.target_system = self._heartbeat_system + # Wait until board has booted. while True: if self._flightmode not in [None, 'INITIALISING', 'MAV']: diff --git a/dronekit/mavlink.py b/dronekit/mavlink.py index 78e5b3ceb..cb63fe368 100644 --- a/dronekit/mavlink.py +++ b/dronekit/mavlink.py @@ -5,6 +5,7 @@ import os import platform import re +import copy import dronekit.lib from dronekit.lib import APIException from dronekit.util import errprinter @@ -34,8 +35,9 @@ def read(self): class MAVConnection(object): def __init__(self, ip, baud=115200, - target_system=0): - self.master = mavutil.mavlink_connection(ip, baud=baud) + target_system=0, + source_system=255): + self.master = mavutil.mavlink_connection(ip, baud=baud, source_system=source_system) # TODO get rid of "master" object as exposed, # keep it private, expose something smaller for dronekit @@ -45,6 +47,13 @@ def __init__(self, ip, srcSystem=self.master.source_system, use_native=False) + # Monkey-patch MAVLink object for fix_targets. + sendfn = self.master.mav.send + def newsendfn(mavmsg): + self.fix_targets(mavmsg) + return sendfn(mavmsg) + self.master.mav.send = newsendfn + # Targets self.target_system = target_system @@ -78,7 +87,6 @@ def mavlink_thread(): while True: try: msg = self.out_queue.get_nowait() - self.fix_targets(msg) self.master.write(msg) except socket.error as error: # If connection reset (closed), stop polling. @@ -178,12 +186,18 @@ def close(self): self.master.close() def pipe(self, target): + target.target_system = self.target_system + + # vehicle -> self -> target @self.forward_message - def callback(self, msg): - target.out_queue.put(msg.pack(self.master.mav)) + def callback(_, msg): + target.out_queue.put(msg.pack(target.master.mav)) + # target -> self -> vehicle @target.forward_message - def callback(self, msg): + def callback(_, msg): + msg = copy.copy(msg) + target.fix_targets(msg) self.out_queue.put(msg.pack(self.master.mav)) return target From 476f44ec2869f93e05a27e22e16861cf9cde1b57 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 18 Nov 2015 17:34:52 +1100 Subject: [PATCH 215/475] Tidies up connect() and related docs for heartbeat and source_system --- docs/guide/copter/guided_mode.rst | 11 +++--- dronekit/lib/__init__.py | 60 ++++++++++++++++++++----------- 2 files changed, 46 insertions(+), 25 deletions(-) diff --git a/docs/guide/copter/guided_mode.rst b/docs/guide/copter/guided_mode.rst index 9940b2978..dedb5dcfa 100644 --- a/docs/guide/copter/guided_mode.rst +++ b/docs/guide/copter/guided_mode.rst @@ -199,11 +199,12 @@ message fields as arguments: # send command to vehicle vehicle.send_mavlink(msg) -There is no need to specify the ``target_system`` id in messages (just set to zero) as DroneKit will automatically -update messages with the vehicle's internal ``target_system`` (see :py:func:`connect() `) before sending. -The ``target_component`` should be set to 0 (broadcast) unless the message is to specific component. -CRC fields and sequence numbers (if defined in the message type) are automatically set by DroneKit and can also -be ignored/set to zero. +If a message includes ``target_system`` id you can set it to zero (DroneKit will automatically +update the value with the correct ID for the connected vehicle). Similarly CRC fields and sequence numbers +(if defined in the message type) can be set to zero as they are automatically updated by DroneKit. +The ``target_component`` is not updated by DroneKit, but should be set to 0 (broadcast) unless the message is +really intended for a specific component. + .. _guided_mode_how_to_send_commands_command_long: diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 1a304dd16..32cc8cf96 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -30,14 +30,25 @@ ---- -.. py:function:: connect(ip, wait_ready=False, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200) +.. py:function:: connect(ip, wait_ready=None, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200, heartbeat_timeout=30, source_system=255) Returns a :py:class:`Vehicle` object connected to the address specified by string parameter ``ip``. Connection string parameters (``ip``) for different targets are listed in the :ref:`getting started guide `. + + The method is usually called with ``wait_ready=True`` to ensure that vehicle parameters and (most) attributes are + available when ``connect()`` returns. + + .. code:: python + + from dronekit import connect + + # Connect to the Vehicle using "connection string" (in this case an address on network) + vehicle = connect('127.0.0.1:14550', wait_ready=True) - :param String ip: Connection string for target address - e.g. 127.0.0.1:14550. + :param String ip: :ref:`Connection string ` for target address - e.g. 127.0.0.1:14550. + :param Bool/Array wait_ready: If ``True`` wait until all default attributes have downloaded before - the method returns (default is ``False``). + the method returns (default is ``None``). The default attributes to wait on are: :py:attr:`parameters`, :py:attr:`gps_0`, :py:attr:`armed`, :py:attr:`mode`, and :py:attr:`attitude`. @@ -45,16 +56,26 @@ For more information see :py:func:`Vehicle.wait_ready `. - :param status_printer: Method of signature ``def status_printer(txt)`` that prints STATUS_TEXT messages from the Vehicle and other diagnostic information. + :param status_printer: Method of signature ``def status_printer(txt)`` that prints + STATUS_TEXT messages from the Vehicle and other diagnostic information. By default the status information is printed to the command prompt in which the script is running. :param Vehicle vehicle_class: The class that will be instantiated by the ``connect()`` method. This can be any sub-class of ``Vehicle`` (and defaults to ``Vehicle``). - :param int rate: Data sream refresh rate. The default is 4Hz (4 updates per second). + :param int rate: Data stream refresh rate. The default is 4Hz (4 updates per second). :param int baud: The baud rate for the connection. The default is 115200. - :param int target_system: The MAVLink target_system for the connected vehicle. The default value is 0 (MAVLink broadcast id). - This setting overrides any value for the target system obtained from the vehicle, - and is used in place of any value set by the user in :py:class:`Commands` or when sending messages - (see :py:func:`Vehicle.send_mavlink() `). + :param int heartbeat_timeout: Connection timeout value in seconds (default is 30s). + If a link is not set up within this time, an exception will be raised. + :param int source_system: The MAVLink ID of the :py:class:`Vehicle` object returned by this method (by default 255). + + .. note:: + + The returned :py:class:`Vehicle` object is acting as like a ground control station from the + perspective of the connected "real" vehicle. It will process/receive messages from the real vehicle + if they are addressed to this ``source_system`` id. Messages sent to the real vehicle are + automatically updated to use the vehicle's ``target_system`` id. + + It is *good practice* to assign a unique id for every system on the MAVLink network. + It is possible to configure the autopilot to only respond to guided-mode commands from a specified GCS ID. :returns: A connected vehicle of the type defined in ``vehicle_class`` (a superclass of :py:class:`Vehicle`). @@ -199,10 +220,10 @@ class GPSInfo(object): If there is no GPS lock the parameters are set to ``None``. - :param IntType eph: GPS horizontal dilution of position (HDOP). - :param IntType epv: GPS horizontal dilution of position (VDOP). - :param IntType fix_type: 0-1: no fix, 2: 2D fix, 3: 3D fix - :param IntType satellites_visible: Number of satellites visible. + :param Int eph: GPS horizontal dilution of position (HDOP). + :param Int epv: GPS horizontal dilution of position (VDOP). + :param Int fix_type: 0-1: no fix, 2: 2D fix, 3: 3D fix + :param Int satellites_visible: Number of satellites visible. .. todo:: FIXME: GPSInfo class - possibly normalize eph/epv? report fix type as string? """ @@ -1588,8 +1609,9 @@ def message_factory(self): msg = vehicle.message_factory.image_trigger_control_encode(True) vehicle.send_mavlink(msg) - There is no need to specify the ``target_system`` id in messages (just set to zero) as DroneKit will automatically - update messages with the vehicle's internal ``target_system`` (see :py:func:`connect() `) before sending. + Some message types include "addressing information". If present, there is no need to specify the ``target_system`` + id (just set to zero) as DroneKit will automatically update messages with the correct ID for the connected + vehicle before sending. The ``target_component`` should be set to 0 (broadcast) unless the message is to specific component. CRC fields and sequence numbers (if defined in the message type) are automatically set by DroneKit and can also be ignored/set to zero. @@ -1893,11 +1915,9 @@ class Command(mavutil.mavlink.MAVLink_mission_item_message): cmd = Command(0,0,0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0,-34.364114, 149.166022, 30) - :param target_system: The id number of the message's target system (drone, GSC) within the MAVLink network. - This can be set to any value (nominally 0) because it will be overridden by the - vehicle's internal ``target_system`` (as set :py:func:`connect() `). By - default this is the broadcast id. - :param target_component: The id of a component the message should be routed to within the target system + :param target_system: This can be set to any value + (DroneKit changes the value to the MAVLink ID of the connected vehicle before the command is sent). + :param target_component: The component id if the message is intended for a particular component within the target system (for example, the camera). Set to zero (broadcast) in most cases. :param seq: The sequence number within the mission (the autopilot will reject messages sent out of sequence). This should be set to zero as the API will automatically set the correct value when uploading a mission. From 46857126c685c1034fd60a300013b4f716f7c450 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 18 Nov 2015 20:16:28 +1100 Subject: [PATCH 216/475] Fix the connection timeout information --- dronekit/lib/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 32cc8cf96..f2193ff3b 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -64,7 +64,7 @@ :param int rate: Data stream refresh rate. The default is 4Hz (4 updates per second). :param int baud: The baud rate for the connection. The default is 115200. :param int heartbeat_timeout: Connection timeout value in seconds (default is 30s). - If a link is not set up within this time, an exception will be raised. + If a heartbeat is not detected up within this time an exception will be raised. :param int source_system: The MAVLink ID of the :py:class:`Vehicle` object returned by this method (by default 255). .. note:: From 67782a8c5d064569f77864f79416af11330adf22 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 18 Nov 2015 20:19:56 +1100 Subject: [PATCH 217/475] Fix the connection timeout typo --- dronekit/lib/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index f2193ff3b..7a85a0df1 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -64,7 +64,7 @@ :param int rate: Data stream refresh rate. The default is 4Hz (4 updates per second). :param int baud: The baud rate for the connection. The default is 115200. :param int heartbeat_timeout: Connection timeout value in seconds (default is 30s). - If a heartbeat is not detected up within this time an exception will be raised. + If a heartbeat is not detected within this time an exception will be raised. :param int source_system: The MAVLink ID of the :py:class:`Vehicle` object returned by this method (by default 255). .. note:: From 407c327b054c82319b282793a6b3ecd665968533 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 16 Nov 2015 15:43:13 -0800 Subject: [PATCH 218/475] Adds last_heartbeat property. --- dronekit/lib/__init__.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 7a85a0df1..8533d0d80 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1149,6 +1149,18 @@ def listener(self, name, msg): errprinter('>>> ...link restored.') self._heartbeat_timeout = False + self._last_heartbeat = None + + @handler.forward_loop + def listener(_): + if self._heartbeat_lastreceived: + self._last_heartbeat = time.time() - self._heartbeat_lastreceived + self.notify_attribute_listeners('last_heartbeat', self.last_heartbeat) + + @property + def last_heartbeat(self): + return self._last_heartbeat + def on_message(self, name): """ Decorator for message listener callback functions. From 550d9f8b7a627fbb5fb71b105102f62fb627a4bf Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 18 Nov 2015 21:29:39 +1100 Subject: [PATCH 219/475] Add documentation/examples for the last_heartbeat attribute --- docs/examples/vehicle_state.rst | 1 + docs/guide/migrating.rst | 8 ++--- docs/guide/vehicle_state_and_parameters.rst | 8 +++-- dronekit/lib/__init__.py | 33 +++++++++++++++++++++ examples/vehicle_state/vehicle_state.py | 4 +-- 5 files changed, 44 insertions(+), 10 deletions(-) diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index 5e1c91989..624e3f571 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -69,6 +69,7 @@ On the command prompt you should see (something like): Mount status: [None, None, None] Battery: Battery:voltage=12.587,current=0.0,level=100 EKF OK?: False + Last Heartbeat: 0.769999980927 Rangefinder: Rangefinder: distance=None, voltage=None Rangefinder distance: None Rangefinder voltage: None diff --git a/docs/guide/migrating.rst b/docs/guide/migrating.rst index b4f88333f..04d3c0619 100644 --- a/docs/guide/migrating.rst +++ b/docs/guide/migrating.rst @@ -72,8 +72,8 @@ values as were passed to *MAVProxy* when setting up a connection in DKPY 1.x (in populated with values from the vehicle. Check out :py:func:`Vehicle.wait_ready() ` for more information (this method is used by the ``connect()`` implementation). - :py:func:`connect() ` also has arguments for setting the baud rate - and returning your own :ref:`custom vehicle classes `. + :py:func:`connect() ` also has arguments for setting the baud rate, + returning your own :ref:`custom vehicle classes ` and setting the length of the connection timeout. After connecting, the returned ``vehicle`` can be used in exactly the same way as in DKPY 1.x. @@ -112,7 +112,6 @@ Remove code that checks the ``api.exit`` status (note that the ``api.exit`` call In fact you should delete all references to ``APIConnection`` class and its methods (``get_vehicles()``, ``exit()`` and ``stop()``). -.. todo:: Find out how to check the connection status is still valid. That would go in separate section. Script completion checks @@ -305,7 +304,8 @@ a few more attributes have been added, including: :py:func:`Vehicle.heading `, :py:func:`Vehicle.mount_status `, :py:func:`Vehicle.ekf_ok `, -:py:func:`Vehicle.is_armable `. +:py:func:`Vehicle.is_armable `, +:py:func:`Vehicle.last_heartbeat `. Channel Overrides diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index ca2ac97a0..9c2713fdb 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -33,6 +33,7 @@ Vehicle state information is exposed through vehicle *attributes*. DroneKit-Pyth :py:attr:`Vehicle.battery `, :py:attr:`Vehicle.rangefinder `, :py:attr:`Vehicle.ekf_ok `, +:py:attr:`Vehicle.last_heartbeat `, :py:attr:`Vehicle.home_location `, :py:func:`Vehicle.system_status `, :py:func:`Vehicle.heading `, @@ -76,6 +77,7 @@ regularly updated from MAVLink messages sent by the vehicle). print "Mount status: %s" % vehicle.mount_status print "Battery: %s" % vehicle.battery print "EKF OK?: %s" % vehicle.ekf_ok + print "Last Heartbeat: %s" % vehicle.last_heartbeat print "Rangefinder: %s" % vehicle.rangefinder print "Rangefinder distance: %s" % vehicle.rangefinder.distance print "Rangefinder voltage: %s" % vehicle.rangefinder.voltage @@ -239,7 +241,7 @@ callback that will be called for any/all attribute changes: def wildcard_callback(self, attr_name, value): print " CALLBACK: (%s): %s" % (attr_name,value) - print "\nAdd attribute calback detecting any attribute change" + print "\nAdd attribute callback detecting any attribute change" vehicle.add_attribute_listener('*', wildcard_callback) @@ -324,7 +326,7 @@ Parameters ========== Vehicle parameters provide the information used to configure the autopilot for the vehicle-specific hardware/capabilities. -The available parameters for each platform are documented in the ardupilot wiki here: +The available parameters for each platform are documented in the ArduPilot wiki here: `Copter Parameters `_, `Plane Parameters `_, `Rover Parameters `_ @@ -436,4 +438,4 @@ for "any parameter") using the Known issues ============ -Known issues and improvement suggestions can viewed on `github here `_. \ No newline at end of file +Known issues and improvement suggestions can viewed on `Github here `_. \ No newline at end of file diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py index 8533d0d80..cd3da80b4 100644 --- a/dronekit/lib/__init__.py +++ b/dronekit/lib/__init__.py @@ -1159,6 +1159,39 @@ def listener(_): @property def last_heartbeat(self): + """ + Time since last MAVLink heartbeat was received (in seconds). + + The attribute can be used to monitor link activity and implement script-specific timeout handling. + + For example, to pause the script if no heartbeat is received for more than 1 second you might implement + the following observer, and use ``pause_script`` in a program loop to wait until the link is recovered: + + .. code-block:: python + + pause_script=False + + @vehicle.on_attribute('last_heartbeat') + def listener(self, attr_name, value): + global pause_script + if value > 1 and not pause_script: + print "Pausing script due to bad link" + pause_script=True; + if value < 1 and pause_script: + pause_script=False; + print "Un-pausing script" + + The observer will be called at the period of the messaging loop (about every 0.01 seconds). Testing + on SITL indicates that ``last_heartbeat`` averages about .5 seconds, but will rarely exceed 1.5 seconds + when connected. Whether heartbeat monitoring can be useful will very much depend on the application. + + + .. note:: + + If you just want to change the heartbeat timeout you can modify the ``heartbeat_timeout`` + parameter passed to the :py:func:`connect() ` function. + + """ return self._last_heartbeat def on_message(self, name): diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index f4a83b568..71dc28060 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -38,6 +38,7 @@ print " Mount status: %s" % vehicle.mount_status print " Battery: %s" % vehicle.battery print " EKF OK?: %s" % vehicle.ekf_ok +print " Last Heartbeat: %s" % vehicle.last_heartbeat print " Rangefinder: %s" % vehicle.rangefinder print " Rangefinder distance: %s" % vehicle.rangefinder.distance print " Rangefinder voltage: %s" % vehicle.rangefinder.voltage @@ -151,9 +152,6 @@ def decorated_mode_callback(self, attr_name, value): # Demonstrate getting callback on any attribute change def wildcard_callback(self, attr_name, value): - # `attr_name` - attribute name (useful if callback is used for multiple attributes) - # `self` - associated vehicle object (used if callback behaviour is different for multiple vehicles) - # `value` - updated attribute value. print " CALLBACK: (%s): %s" % (attr_name,value) print "\nAdd attribute callback detecting ANY attribute change" From 94db70bb70aabc4c32413335737ad74cb95c036f Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 18 Nov 2015 10:23:28 -0800 Subject: [PATCH 220/475] 2.0.0rc12 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index bb3401b5a..0166b3bd4 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.0.0rc11' +version = '2.0.0rc12' setup(name='dronekit', zip_safe=True, From cbc57237eabc1f566b1895c957b29296e7f7fe98 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 18 Nov 2015 11:02:53 -0800 Subject: [PATCH 221/475] Restructures dronekit.lib to be just dronekit. --- README.md | 3 +- docs/automodule.rst | 2 +- docs/examples/channel_overrides.rst | 4 +- docs/examples/create_attribute.rst | 14 +- docs/examples/drone_delivery.rst | 2 +- docs/examples/follow_me.rst | 2 +- docs/examples/mission_basic.rst | 8 +- docs/examples/simple_goto.rst | 12 +- docs/examples/vehicle_state.rst | 6 +- docs/guide/auto_mode.rst | 34 +- docs/guide/copter/guided_mode.rst | 12 +- docs/guide/getting_started.rst | 4 +- docs/guide/mavlink_messages.rst | 14 +- docs/guide/migrating.rst | 82 +- docs/guide/taking_off.rst | 8 +- docs/guide/vehicle_state_and_parameters.rst | 98 +- dronekit/__init__.py | 2216 ++++++++++++++++- dronekit/{lib => cloud}/CloudClient.py | 0 dronekit/cloud/__init__.py | 0 dronekit/lib.py | 2 + dronekit/lib/__init__.py | 2202 ---------------- dronekit/mavlink.py | 4 +- dronekit/test/sitl/test_channels.py | 2 - dronekit/test/unit/test_api.py | 3 +- dronekit/test/web/cloud_client_test.py | 2 +- examples/flight_replay/flight_replay.py | 3 +- examples/follow_me/follow_me.py | 3 +- examples/gcs/microgcs.py | 3 +- .../guided_set_speed_yaw.py | 3 +- examples/mission_basic/mission_basic.py | 3 +- .../mission_import_export.py | 3 +- examples/perf/perf_test.py | 3 +- examples/simple_goto/simple_goto.py | 3 +- examples/vehicle_state/vehicle_state.py | 3 +- setup.py | 2 +- 35 files changed, 2371 insertions(+), 2394 deletions(-) rename dronekit/{lib => cloud}/CloudClient.py (100%) create mode 100644 dronekit/cloud/__init__.py create mode 100644 dronekit/lib.py delete mode 100644 dronekit/lib/__init__.py diff --git a/README.md b/README.md index e27f6856e..b4bc8eff9 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,7 @@ The [Getting Started](http://python.dronekit.io/guide/getting_started.html) guid A basic script looks like this: ```python -from dronekit import connect -from dronekit.lib import VehicleMode +from dronekit import connect, VehicleMode # Connect to UDP endpoint. vehicle = connect('127.0.0.1:14550', wait_ready=True) diff --git a/docs/automodule.rst b/docs/automodule.rst index 3fdb2e34a..ef3dd5414 100644 --- a/docs/automodule.rst +++ b/docs/automodule.rst @@ -5,7 +5,7 @@ DroneKit-Python API Reference ============================= -.. automodule:: dronekit.lib +.. automodule:: dronekit :members: :inherited-members: diff --git a/docs/examples/channel_overrides.rst b/docs/examples/channel_overrides.rst index c93eb954a..b571d14c7 100644 --- a/docs/examples/channel_overrides.rst +++ b/docs/examples/channel_overrides.rst @@ -110,7 +110,7 @@ In general a value of 0 set for a specific ``RCn_FUNCTION`` indicates that the c `mission controlled `_ (i.e. it will not directly be controlled by normal autopilot code). -You can read the values of the channels using the :py:attr:`Vehicle.channels ` attribute. The values are regularly updated, +You can read the values of the channels using the :py:attr:`Vehicle.channels ` attribute. The values are regularly updated, from the UAV, based on the RC inputs from the transmitter. These can be read either as a set or individually: .. code:: python @@ -123,7 +123,7 @@ from the UAV, based on the RC inputs from the transmitter. These can be read eit print " Ch1: %s" % vehicle.channels['1'] print " Ch2: %s" % vehicle.channels['2'] -You can override the values sent to the vehicle by the autopilot using :py:attr:`Vehicle.channels.overrides ` +You can override the values sent to the vehicle by the autopilot using :py:attr:`Vehicle.channels.overrides ` (although this is not recommended)! The overrides can be written individually using an indexing syntax or as a set using a dictionary syntax. .. code:: python diff --git a/docs/examples/create_attribute.rst b/docs/examples/create_attribute.rst index dd65c5458..45bed93ca 100644 --- a/docs/examples/create_attribute.rst +++ b/docs/examples/create_attribute.rst @@ -4,23 +4,23 @@ Example: Create Attribute in App ================================ -This example shows how you can subclass :py:class:`Vehicle ` in order to support +This example shows how you can subclass :py:class:`Vehicle ` in order to support new attributes for MAVLink messages within your DroneKit-Python script. The new class is defined in a separate file (making re-use easy) and is very similar to the code used to implement the in-built attributes. The new attributes are used *in the same way* as the built-in -:py:class:`Vehicle ` attributes. +:py:class:`Vehicle ` attributes. -The new class uses the :py:func:`Vehicle.on_message() ` decorator +The new class uses the :py:func:`Vehicle.on_message() ` decorator to set a function that is called to process a specific message, copy its values into an attribute, and notify observers. An observer is then set on the new attribute using -:py:func:`Vehicle.add_attribute_listener() `. +:py:func:`Vehicle.add_attribute_listener() `. Additional information is provided in the guide topic :ref:`mavlink_messages`. .. tip:: This approach is useful when you urgently need to access messages that are not yet supported as - :py:class:`Vehicle ` attributes. + :py:class:`Vehicle ` attributes. Please :ref:`contribute your code to the API ` so that it is available to (and can be tested by) the whole DroneKit-Python community. @@ -150,7 +150,7 @@ The example file **my_vehicle.py** defines a class for the new attribute (``RawI ``MyVehicle`` is a superclass of ``Vehicle`` (and hence inherits all its attributes). This first creates a private instance of ``RawIMU``. -We create a listener using the :py:func:`Vehicle.on_message() ` +We create a listener using the :py:func:`Vehicle.on_message() ` decorator. The listener is called for messages that contain the string "RAW_IMU", with arguments for the vehicle, message name, and the message. It copies the message information into the attribute and then notifies all observers. @@ -198,7 +198,7 @@ the attribute and then notifies all observers. .. note:: - The notifier function (:py:func:`Vehicle.notify_attribute_listeners() `) + The notifier function (:py:func:`Vehicle.notify_attribute_listeners() `) should be called every time there is an update from the vehicle. You can set a third parameter (``cache=True``) so that it only invokes the listeners when the value *changes*. diff --git a/docs/examples/drone_delivery.rst b/docs/examples/drone_delivery.rst index 4cb321ac6..aeec2fb43 100644 --- a/docs/examples/drone_delivery.rst +++ b/docs/examples/drone_delivery.rst @@ -26,7 +26,7 @@ install the CherryPy dependencies and view the behaviour in a web browser. If you're using a simulated vehicle remember to :ref:`disable arming checks ` so that the example can run. You can also `add a virtual rangefinder `_ -(otherwise the :py:attr:`Vehicle.rangefinder ` attribute may return values of ``None`` for the distance +(otherwise the :py:attr:`Vehicle.rangefinder ` attribute may return values of ``None`` for the distance and voltage). In summary, after cloning the repository: diff --git a/docs/examples/follow_me.rst b/docs/examples/follow_me.rst index 78a886d2d..d01a5e077 100644 --- a/docs/examples/follow_me.rst +++ b/docs/examples/follow_me.rst @@ -108,7 +108,7 @@ Most of the example should be fairly familiar as it uses the same code as other :ref:`taking off `, and closing the vehicle object. The example-specific code is shown below. All this does is attempt to get a gps socket and read the location in a two second loop. If it is successful it -reports the value and uses :py:func:`Vehicle.commands.goto ` to move to the new position. The loop exits when +reports the value and uses :py:func:`Vehicle.commands.goto ` to move to the new position. The loop exits when the mode is changed. .. code-block:: python diff --git a/docs/examples/mission_basic.rst b/docs/examples/mission_basic.rst index ee29857c4..446d166d6 100644 --- a/docs/examples/mission_basic.rst +++ b/docs/examples/mission_basic.rst @@ -134,7 +134,7 @@ operations are explained in the guide topic :ref:`auto_mode_vehicle_control` . In overview, the example calls ``adds_square_mission(vehicle.location.global_frame,50)`` to first clear the current mission and then define a new mission with a takeoff command and four waypoints arranged in a square around the central position (two waypoints are added in the last position - -we use :py:func:`next ` to determine when we've reached the final point). +we use :py:func:`next ` to determine when we've reached the final point). The clear command and new mission items are then uploaded to the vehicle. After taking off (in guided mode using the ``takeoff()`` function) the example starts the mission by setting the mode to AUTO: @@ -148,11 +148,11 @@ After taking off (in guided mode using the ``takeoff()`` function) the example s The progress of the mission is monitored in a loop. The convenience function :ref:`distance_to_current_waypoint() ` gets the distance to the next waypoint and -:py:func:`Vehicle.commands.next ` gets the value of +:py:func:`Vehicle.commands.next ` gets the value of the next command. We also show how to move to a specified command using -:py:func:`Vehicle.commands.next ` (note how we skip the third command below): +:py:func:`Vehicle.commands.next ` (note how we skip the third command below): .. code:: python @@ -179,7 +179,7 @@ Known issues This example has the following issues: -* :py:func:`next ` does not appear to be writable, so the example does not skip steps as documented. +* :py:func:`next ` does not appear to be writable, so the example does not skip steps as documented. This is tracked as `#390 <#https://github.com/dronekit/dronekit-python/issues/390>`_. diff --git a/docs/examples/simple_goto.rst b/docs/examples/simple_goto.rst index 496df27de..04f7d7b04 100644 --- a/docs/examples/simple_goto.rst +++ b/docs/examples/simple_goto.rst @@ -5,8 +5,8 @@ Example: Simple Go To (Copter) ============================== This example demonstrates how to arm and launch a Copter in GUIDED mode, travel towards a number of target points, and then return -to the home location. It uses :py:func:`Vehicle.commands.takeoff() `, -:py:func:`Vehicle.commands.goto() ` and :py:attr:`Vehicle.mode `. +to the home location. It uses :py:func:`Vehicle.commands.takeoff() `, +:py:func:`Vehicle.commands.goto() ` and :py:attr:`Vehicle.mode `. The target locations are centred around the home location when the :ref:`Simulated Vehicle ` is booted; you can edit the latitude and longitude to use more appropriate positions for your own vehicle. @@ -100,7 +100,7 @@ On the command prompt you should see (something like): .. tip:: - The code waits on :py:func:`Vehicle.is_armable `, so you shouldn't get stuck in ``Waiting for arming...``. + The code waits on :py:func:`Vehicle.is_armable `, so you shouldn't get stuck in ``Waiting for arming...``. If you do, then: * On a real device you can view the controller LEDs to determine possible causes. @@ -120,9 +120,9 @@ The code has three distinct sections: arming and takeoff, flight to two location Takeoff ------- -To launch *Copter* you need to first check that the vehicle :py:func:`Vehicle.is_armable `. +To launch *Copter* you need to first check that the vehicle :py:func:`Vehicle.is_armable `. Then set the mode to ``GUIDED``, arm the vehicle, and call -:py:func:`Vehicle.commands.takeoff() `. The takeoff code in this example +:py:func:`Vehicle.commands.takeoff() `. The takeoff code in this example is explained in the guide topic :ref:`taking-off`. @@ -130,7 +130,7 @@ Flying to a point - Goto ------------------------ The vehicle is already in ``GUIDED`` mode, so to send it to a certain point we just need to -call :py:func:`Vehicle.commands.goto() ` with the target ``LocationGlobal``: +call :py:func:`Vehicle.commands.goto() ` with the target ``LocationGlobal``: .. code-block:: python diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index 624e3f571..80606e3bd 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -20,7 +20,7 @@ the vehicle and DroneKit have been set up as described in :ref:`get-started`). If you're using a simulated vehicle remember to :ref:`disable arming checks ` so that the example can run. You can also `add a virtual rangefinder `_ -(otherwise the :py:attr:`Vehicle.rangefinder ` attribute may return +(otherwise the :py:attr:`Vehicle.rangefinder ` attribute may return values of ``None`` for the distance and voltage). In summary, after cloning the repository: @@ -123,13 +123,13 @@ On the command prompt you should see (something like): Wait 1s so callback invoked before observer removed CALLBACK: (attitude): Attitude:pitch=0.00716688157991,yaw=-0.0950401723385,roll=0.00759896961972 CALLBACK: (heading): 354 - CALLBACK: (location): + CALLBACK: (location): CALLBACK: (airspeed): 0.0 CALLBACK: (groundspeed): 0.0 CALLBACK: (ekf_ok): True CALLBACK: (battery): Battery:voltage=12.538,current=3.48,level=99 CALLBACK: (gps_0): GPSInfo:fix=3,num_sat=10 - CALLBACK: (location): + CALLBACK: (location): CALLBACK: (velocity): [-0.14, 0.1, 0.0] CALLBACK: (local_position): LocationLocal:north=-0.136136248708,east=-0.0430941730738,down=-0.00938374921679 CALLBACK: (channels): {'1': 1500, '3': 1000, '2': 1500, '5': 1800, '4': 1500, '7': 1000, '6': 1000, '8': 1800} diff --git a/docs/guide/auto_mode.rst b/docs/guide/auto_mode.rst index 4a4e8dcd6..745b689b8 100644 --- a/docs/guide/auto_mode.rst +++ b/docs/guide/auto_mode.rst @@ -61,12 +61,12 @@ wiki topic provides a more detailed overview of commands. Download current mission ======================== -The mission commands for a vehicle are accessed using the :py:attr:`Vehicle.commands ` -attribute. The attribute is of type :py:class:`CommandSequence `, a class that provides ‘array style’ indexed access to the +The mission commands for a vehicle are accessed using the :py:attr:`Vehicle.commands ` +attribute. The attribute is of type :py:class:`CommandSequence `, a class that provides ‘array style’ indexed access to the waypoints which make up the mission. -Waypoints are not downloaded from vehicle until :py:func:`download() ` is called. The download is asynchronous; -use :py:func:`wait_ready() ` to block your thread until the download is complete: +Waypoints are not downloaded from vehicle until :py:func:`download() ` is called. The download is asynchronous; +use :py:func:`wait_ready() ` to block your thread until the download is complete: .. code:: python @@ -80,7 +80,7 @@ use :py:func:`wait_ready() ` to block y .. note:: - In DroneKit-Python 2 :py:attr:`Vehicle.commands ` contains just the editable waypoints (in version 1.x, the + In DroneKit-Python 2 :py:attr:`Vehicle.commands ` contains just the editable waypoints (in version 1.x, the commands included the non-editable home location as the first item). @@ -90,8 +90,8 @@ use :py:func:`wait_ready() ` to block y Clearing current mission ======================== -To clear a mission you call :py:func:`clear() ` and then -:py:func:`Vehicle.commands.upload() ` (to upload the changes to the vehicle): +To clear a mission you call :py:func:`clear() ` and then +:py:func:`Vehicle.commands.upload() ` (to upload the changes to the vehicle): .. code:: python @@ -118,10 +118,10 @@ Creating/adding mission commands ================================ After :ref:`downloading ` or :ref:`clearing ` a mission new commands -can be added and uploaded to the vehicle. Commands are added to the mission using :py:func:`add() ` -and are sent to the vehicle (either individually or in batches) using :py:func:`upload() `. +can be added and uploaded to the vehicle. Commands are added to the mission using :py:func:`add() ` +and are sent to the vehicle (either individually or in batches) using :py:func:`upload() `. -Each command is packaged in a :py:class:`Command ` object (see that class for the order/meaning of the parameters). +Each command is packaged in a :py:class:`Command ` object (see that class for the order/meaning of the parameters). The supported commands for each vehicle are :ref:`linked above `. @@ -187,7 +187,7 @@ modify them as needed, then clear ``Vehicle.commands`` and upload the list as a The changes are not guaranteed to be complete until -:py:func:`upload() ` is called on the parent ``Vehicle.commands`` object. +:py:func:`upload() ` is called on the parent ``Vehicle.commands`` object. .. _auto_mode_monitoring_controlling: @@ -219,7 +219,7 @@ AUTO mode the mission will either restart at the beginning or resume at the curr `MIS_RESTART `_ parameter (available on all vehicle types). -You can monitor the progress of the mission by polling the :py:func:`Vehicle.commands.next ` attribute +You can monitor the progress of the mission by polling the :py:func:`Vehicle.commands.next ` attribute to get the current command number. You can also change the current command by setting the attribute to the desired command number. .. code:: python @@ -245,7 +245,7 @@ AUTO mode to start it running again. Currently there is no notification in DroneKit when a mission completes. If you need to detect mission end (in order to perform some other operation) then you can either: -* Add a dummy mission command and poll :py:func:`Vehicle.commands.next ` for the +* Add a dummy mission command and poll :py:func:`Vehicle.commands.next ` for the transition to the final command, or * Compare the current position to the target position in the final waypoint. @@ -292,10 +292,10 @@ Adding mission commands is discussed :ref:`here in the guide ` objects. +``readmission()`` reads a mission from the specified file and returns a list of :py:class:`Command ` objects. Each line is split up. The first line is used to test whether the file has the correct (stated) format. -For subsequent lines the values are stored in a :py:class:`Command ` object +For subsequent lines the values are stored in a :py:class:`Command ` object (the values are first cast to the correct ``float`` and ``int`` types for their associated parameters). The commands are added to a list which is returned by the function. @@ -357,7 +357,7 @@ It uses ``download_mission()`` (below) to get them mission, and then writes the with open(aFileName, 'w') as file_: file_.write(output) -``download_mission()`` downloads the :py:attr:`Vehicle.commands ` from the vehicle and +``download_mission()`` downloads the :py:attr:`Vehicle.commands ` from the vehicle and adds them to a list. Downloading mission is discussed :ref:`in the guide `. .. code:: python @@ -404,7 +404,7 @@ Get distance to waypoint distancetopoint = get_distance_metres(vehicle.location.global_frame, targetWaypointLocation) return distancetopoint -The function determines the current target waypoint number with :py:func:`Vehicle.commands.next ` +The function determines the current target waypoint number with :py:func:`Vehicle.commands.next ` and uses it to index the commands to get the latitude, longitude and altitude of the target waypoint. The ``get_distance_metres()`` function (see :ref:`guided_mode_copter_useful_conversion_functions`) is then used to calculate and return the (horizontal) distance from the current vehicle location. diff --git a/docs/guide/copter/guided_mode.rst b/docs/guide/copter/guided_mode.rst index dedb5dcfa..79e71aa68 100644 --- a/docs/guide/copter/guided_mode.rst +++ b/docs/guide/copter/guided_mode.rst @@ -37,8 +37,8 @@ Position control Controlling the vehicle by explicitly setting the target position is useful when the final position is known/fixed. -The recommended method for position control is :py:func:`Vehicle.commands.goto() `. -This takes a :py:class:`LocationGlobal ` argument for the target position in the +The recommended method for position control is :py:func:`Vehicle.commands.goto() `. +This takes a :py:class:`LocationGlobal ` argument for the target position in the global `WGS84 coordinate system `_, but with altitude relative to the home location (home altitude = 0). @@ -169,8 +169,8 @@ This section explains how to send MAVLink commands, what commands can be sent, a Sending messages/commands ------------------------- -MAVLink commands are sent by first using :py:func:`message_factory() ` -to encode the message and then calling :py:func:`send_mavlink() ` to send them. +MAVLink commands are sent by first using :py:func:`message_factory() ` +to encode the message and then calling :py:func:`send_mavlink() ` to send them. .. note:: @@ -235,7 +235,7 @@ Supported commands `Copter Commands in Guided Mode `_ lists all the commands that *can* be sent to Copter in GUIDED mode (in fact most of the commands can be sent in any mode!) -DroneKit-Python provides a friendly Python API that abstracts many of the commands. Where possible you should use the API rather than send messages directly. For example it is better to use :py:func:`Vehicle.commands.takeoff() ` than to explicitly send the ``MAV_CMD_NAV_TAKEOFF`` command. +DroneKit-Python provides a friendly Python API that abstracts many of the commands. Where possible you should use the API rather than send messages directly. For example it is better to use :py:func:`Vehicle.commands.takeoff() ` than to explicitly send the ``MAV_CMD_NAV_TAKEOFF`` command. Some of the MAV_CMD commands that you might want to send include: :ref:`MAV_CMD_CONDITION_YAW `, :ref:`MAV_CMD_DO_CHANGE_SPEED `, :ref:`MAV_CMD_DO_SET_ROI `, ``MAV_CMD_DO_SET_SERVO``, ``MAV_CMD_DO_REPEAT_SERVO``, ``MAV_CMD_DO_SET_RELAY``, ``MAV_CMD_DO_REPEAT_RELAY``, ``MAV_CMD_DO_FENCE_ENABLE``, ``MAV_CMD_DO_PARACHUTE``, ``MAV_CMD_DO_GRIPPER``, ``MAV_CMD_MISSION_START``. These would be sent in a ``COMMAND_LONG`` message :ref:`as discussed above `. @@ -318,7 +318,7 @@ The command is useful when setting the vehicle position directly. It is not need Setting the ROI --------------- -Send the `MAV_CMD_DO_SET_ROI `_ command to point camera gimbal at a specified region of interest (:py:class:`LocationGlobal `). The vehicle may also turn to face the ROI. +Send the `MAV_CMD_DO_SET_ROI `_ command to point camera gimbal at a specified region of interest (:py:class:`LocationGlobal `). The vehicle may also turn to face the ROI. .. code-block:: python diff --git a/docs/guide/getting_started.rst b/docs/guide/getting_started.rst index f771a7dbd..9ce99ff01 100644 --- a/docs/guide/getting_started.rst +++ b/docs/guide/getting_started.rst @@ -105,7 +105,7 @@ Connecting to a Vehicle ======================= The connection to the vehicle is set up within the DroneKit script. Scripts import and call the :py:func:`connect()` method. -After connecting this returns a :py:class:`Vehicle ` object from which you can get/set parameters +After connecting this returns a :py:class:`Vehicle ` object from which you can get/set parameters and attributes, and control vehicle movement. .. code:: python @@ -118,7 +118,7 @@ and attributes, and control vehicle movement. .. note:: Calling ``connect()`` with ``wait_ready=True`` (as shown above) ensures that the method will not return until - :py:attr:`Vehicle.parameters ` is fully populated with values from the vehicle. + :py:attr:`Vehicle.parameters ` is fully populated with values from the vehicle. Vehicle *attributes* are populated in parallel but are not guaranteed to have values when ``connect()`` completes (an attribute will have value ``None`` if a corresponding MAVLink message has not been received - for example, if the attribute is not supported by the vehicle). diff --git a/docs/guide/mavlink_messages.rst b/docs/guide/mavlink_messages.rst index 67d3d0922..16cac5747 100644 --- a/docs/guide/mavlink_messages.rst +++ b/docs/guide/mavlink_messages.rst @@ -5,14 +5,14 @@ MAVLink Messages ================ Some useful MAVLink messages sent by the autopilot are not (yet) directly available to DroneKit-Python scripts -through the :ref:`observable attributes ` in :py:class:`Vehicle `. +through the :ref:`observable attributes ` in :py:class:`Vehicle `. This topic shows how you can intercept specific MAVLink messages by defining a listener callback function -using the :py:func:`Vehicle.on_message() ` decorator. +using the :py:func:`Vehicle.on_message() ` decorator. .. tip:: - :ref:`example_create_attribute` shows how you can extend this approach to create a new :py:class:`Vehicle ` + :ref:`example_create_attribute` shows how you can extend this approach to create a new :py:class:`Vehicle ` attribute in your client code. @@ -22,7 +22,7 @@ using the :py:func:`Vehicle.on_message() ` deco Creating a message listener =========================== -The :py:func:`Vehicle.on_message() ` decorator can be used to +The :py:func:`Vehicle.on_message() ` decorator can be used to set a particular function as the callback handler for a particular message type. You can create listeners for as many messages as you like, or even multiple listeners for the same message. @@ -79,9 +79,9 @@ You can register a callback for *all messages* by setting the message name as th Removing an observer ==================== -Callbacks registered using the :py:func:`Vehicle.on_message() ` decorator *cannot be removed*. +Callbacks registered using the :py:func:`Vehicle.on_message() ` decorator *cannot be removed*. This is generally not a problem, because in most cases you're interested in messages for the lifetime of a session. If you do need to be able to remove messages you can instead add the callback using -:py:func:`Vehicle.add_message_listener `, and then remove it by calling -:py:func:`Vehicle.remove_message_listener `. +:py:func:`Vehicle.add_message_listener `, and then remove it by calling +:py:func:`Vehicle.remove_message_listener `. diff --git a/docs/guide/migrating.rst b/docs/guide/migrating.rst index 04d3c0619..c7403a691 100644 --- a/docs/guide/migrating.rst +++ b/docs/guide/migrating.rst @@ -54,8 +54,8 @@ Connecting to a vehicle You must specify the target vehicle address in your script (in DKPY 1.x this was done when you launched MAVProxy). -The code fragment below shows how you import the :py:func:`connect() ` method and use it to return a -connected :py:class:`Vehicle ` object. The address string passed to ``connect()`` takes the same +The code fragment below shows how you import the :py:func:`connect() ` method and use it to return a +connected :py:class:`Vehicle ` object. The address string passed to ``connect()`` takes the same values as were passed to *MAVProxy* when setting up a connection in DKPY 1.x (in this case, a SITL instance running on the same computer). .. code:: python @@ -68,11 +68,11 @@ values as were passed to *MAVProxy* when setting up a connection in DKPY 1.x (in .. note:: The ``wait_ready=True`` parameter ensures that ``connect()`` won't return until - :py:attr:`Vehicle.parameters ` and most other default attributes have been - populated with values from the vehicle. Check out :py:func:`Vehicle.wait_ready() ` for more + :py:attr:`Vehicle.parameters ` and most other default attributes have been + populated with values from the vehicle. Check out :py:func:`Vehicle.wait_ready() ` for more information (this method is used by the ``connect()`` implementation). - :py:func:`connect() ` also has arguments for setting the baud rate, + :py:func:`connect() ` also has arguments for setting the baud rate, returning your own :ref:`custom vehicle classes ` and setting the length of the connection timeout. @@ -117,7 +117,7 @@ Remove code that checks the ``api.exit`` status (note that the ``api.exit`` call Script completion checks ------------------------ -Examples that might possibly have outstanding messages should call :py:func:`Vehicle.close() ` +Examples that might possibly have outstanding messages should call :py:func:`Vehicle.close() ` before exiting to ensure that all messages have flushed before the script completes: .. code:: python @@ -184,10 +184,10 @@ global, global-relative and local (NED) frames: print "Global Location (relative altitude): %s" % vehicle.location.global_relative_frame print "Local Location: %s" % vehicle.location.local_frame -For more information see: :py:attr:`Vehicle.location `, -:py:attr:`Vehicle.location.global_frame `, -:py:attr:`Vehicle.location.global_relative_frame `, -:py:attr:`Vehicle.location.local_frame `, and :ref:`vehicle-information`. +For more information see: :py:attr:`Vehicle.location `, +:py:attr:`Vehicle.location.global_frame `, +:py:attr:`Vehicle.location.global_relative_frame `, +:py:attr:`Vehicle.location.local_frame `, and :ref:`vehicle-information`. .. _migrating_dkpy2_0_home_location: @@ -195,14 +195,14 @@ For more information see: :py:attr:`Vehicle.location `. -This code must be replaced with the DroneKit-Python 2.x :py:attr:`Vehicle.home_location ` attribute. +DroneKit-Python 1.x code retrieved the home location from the first element in :py:attr:`Vehicle.commands `. +This code must be replaced with the DroneKit-Python 2.x :py:attr:`Vehicle.home_location ` attribute. .. tip:: - Even though the home location is no longer returned as the first waypoint in :py:attr:`Vehicle.commands `, + Even though the home location is no longer returned as the first waypoint in :py:attr:`Vehicle.commands `, you will still need to download the commands in order to populate the value of - :py:attr:`Vehicle.home_location `. + :py:attr:`Vehicle.home_location `. Missions and Waypoints @@ -210,10 +210,10 @@ Missions and Waypoints The API for working with missions has been improved and made significantly more robust. -One of the major changes is that the :py:attr:`Vehicle.commands ` list no +One of the major changes is that the :py:attr:`Vehicle.commands ` list no longer includes the :ref:`home location ` waypoint in the 0th index. Another change is that we now wait for command download to complete using -:py:attr:`Vehicle.commands.wait_ready() `. +:py:attr:`Vehicle.commands.wait_ready() `. All the known bugs have been fixed. It is now much easier to download, clear, and add items to the mission because there is no need to work around race conditions and other issues with the API. @@ -225,9 +225,9 @@ Observing attribute changes --------------------------- The DroneKit-Python 1.x observer function ``vehicle.add_attribute_observer`` has been replaced by -:py:func:`Vehicle.add_attribute_listener() ` or -:py:func:`Vehicle.on_attribute() ` in DKYP2.x, and ``Vehicle.remove_attribute_observer`` -has been repaced by :py:func:`remove_attribute_listener() `. +:py:func:`Vehicle.add_attribute_listener() ` or +:py:func:`Vehicle.on_attribute() ` in DKYP2.x, and ``Vehicle.remove_attribute_observer`` +has been repaced by :py:func:`remove_attribute_listener() `. The main difference is that the callback function now takes three arguments (the vehicle object, attribute name, attribute value) rather than just the attribute name. This allows you to more easily write callbacks that support attribute-specific and @@ -236,15 +236,15 @@ the vehicle. .. note:: - The difference between :py:func:`Vehicle.add_attribute_listener() ` and - :py:func:`Vehicle.on_attribute() ` is that attribute listeners added using - :py:func:`Vehicle.on_attribute() ` cannot be removed (while ``on_attribute()`` + The difference between :py:func:`Vehicle.add_attribute_listener() ` and + :py:func:`Vehicle.on_attribute() ` is that attribute listeners added using + :py:func:`Vehicle.on_attribute() ` cannot be removed (while ``on_attribute()`` has a more elegant syntax). A few attributes have been modified so that they only notify when the value changes: -:py:func:`Vehicle.system_status `, -:py:attr:`Vehicle.armed `, and -:py:attr:`Vehicle.mode `. Users no longer need to add caching code +:py:func:`Vehicle.system_status `, +:py:attr:`Vehicle.armed `, and +:py:attr:`Vehicle.mode `. Users no longer need to add caching code for these attributes in their listeners. Attributes that provide "streams" of information (i.e. sensor output) remain unchanged. @@ -252,7 +252,7 @@ Attributes that provide "streams" of information (i.e. sensor output) remain unc If you're :ref:`creating your own attributes ` this caching is trivially provided using the ``cache=True`` argument to - :py:func:`Vehicle.notify_attribute_listeners() `. + :py:func:`Vehicle.notify_attribute_listeners() `. See :ref:`vehicle_state_observe_attributes` for more information. @@ -262,7 +262,7 @@ Parameter changes In DKPY2 you can now :ref:`observe ` parameters in order to be notified of changes, and also :ref:`iterate ` -:py:attr:`Vehicle.parameters ` to get a list of off the supported +:py:attr:`Vehicle.parameters ` to get a list of off the supported values in the connected vehicle. In addition, the code to download parameters and keep information in sync with the vehicle @@ -278,18 +278,18 @@ Intercepting MAVLink Messages DroneKit-Python 1.x used ``Vehicle.set_mavlink_callback()`` and ``Vehicle.unset_mavlink_callback`` to set/unset a callback function that was invoked for every single mavlink message. -In DKPY2 this has been replaced by the :py:func:`Vehicle.on_message() ` +In DKPY2 this has been replaced by the :py:func:`Vehicle.on_message() ` decorator, which allows you to specify a callback function that will be invoked for a single message (or all messages, by specifying the message name as the wildcard string '``*``'). .. tip:: - :py:func:`Vehicle.on_message() ` is used in core DroneKit code for + :py:func:`Vehicle.on_message() ` is used in core DroneKit code for message capture and to create ``Vehicle`` attributes. - The API also adds :py:func:`Vehicle.add_message_listener() ` - and :py:func:`Vehicle.remove_message_listener() `. - These can be used instead of :py:func:`Vehicle.on_message() ` when you need to be + The API also adds :py:func:`Vehicle.add_message_listener() ` + and :py:func:`Vehicle.remove_message_listener() `. + These can be used instead of :py:func:`Vehicle.on_message() ` when you need to be able to *remove* an added listener. Typically you won't need to! See :ref:`mavlink_messages` for more information. @@ -300,12 +300,12 @@ New attributes In addition to the :ref:`home_location `, a few more attributes have been added, including: -:py:func:`Vehicle.system_status `, -:py:func:`Vehicle.heading `, -:py:func:`Vehicle.mount_status `, -:py:func:`Vehicle.ekf_ok `, -:py:func:`Vehicle.is_armable `, -:py:func:`Vehicle.last_heartbeat `. +:py:func:`Vehicle.system_status `, +:py:func:`Vehicle.heading `, +:py:func:`Vehicle.mount_status `, +:py:func:`Vehicle.ekf_ok `, +:py:func:`Vehicle.is_armable `, +:py:func:`Vehicle.last_heartbeat `. Channel Overrides @@ -317,10 +317,10 @@ Channel Overrides simulating user input and when implementing certain types of joystick control). DKPY v2 replaces the ``vehicle.channel_readback`` attribute with -:py:attr:`Vehicle.channels ` (and the :py:class:`Channels ` +:py:attr:`Vehicle.channels ` (and the :py:class:`Channels ` class) and the ``vehicle.channel_override`` attribute with -:py:attr:`Vehicle.channels.overrides ` -(and the :py:class:`ChannelsOverrides ` class). +:py:attr:`Vehicle.channels.overrides ` +(and the :py:class:`ChannelsOverrides ` class). Documentation and example code for how to use the new API are provided in :ref:`example_channel_overrides`. diff --git a/docs/guide/taking_off.rst b/docs/guide/taking_off.rst index 2093821be..ee856db1a 100644 --- a/docs/guide/taking_off.rst +++ b/docs/guide/taking_off.rst @@ -6,7 +6,7 @@ Taking Off This article explains how to get your *Copter* to take off. At high level, the steps are: check that the vehicle is able to arm (can pass pre-arm checks), set the mode to ``GUIDED``, arm the vehicle, -and then call :py:func:`Vehicle.commands.takeoff() `. +and then call :py:func:`Vehicle.commands.takeoff() `. .. todo:: @@ -73,7 +73,7 @@ The function first performs some pre-arm checks. DroneKit-Python can't check every possible symptom that might prevent arming, but we can confirm that the vehicle has booted, EKF is ready, and it has a GPS lock. These checks are encapsulated in the -:py:func:`Vehicle.is_armable ` attribute: +:py:func:`Vehicle.is_armable ` attribute: .. code-block:: python @@ -96,11 +96,11 @@ vehicle has booted, EKF is ready, and it has a GPS lock. These checks are encaps print "Waiting for GPS...:", vehicle.gps_0.fix_type time.sleep(1) - You should always do a final check on :py:func:`Vehicle.is_armable `! + You should always do a final check on :py:func:`Vehicle.is_armable `! Once the vehicle is ready we set the mode to ``GUIDED`` and arm it. We then wait until arming is confirmed -before sending the :py:func:`takeoff ` command. +before sending the :py:func:`takeoff ` command. .. code-block:: python diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index 9c2713fdb..d8dbbde55 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -4,9 +4,9 @@ Vehicle State and Settings =========================== -The :py:class:`Vehicle ` class exposes *most* state information (position, speed, etc.) through python +The :py:class:`Vehicle ` class exposes *most* state information (position, speed, etc.) through python :ref:`attributes `, while vehicle :ref:`parameters ` (settings) -are accessed though named elements of :py:attr:`Vehicle.parameters `. +are accessed though named elements of :py:attr:`Vehicle.parameters `. This topic explains how to get, set and observe vehicle state and parameter information (including getting the :ref:`Home location `). @@ -21,38 +21,38 @@ Attributes Vehicle state information is exposed through vehicle *attributes*. DroneKit-Python currently supports the following "standard" attributes: -:py:attr:`Vehicle.location.global_frame `, -:py:attr:`Vehicle.location.global_relative_frame `, -:py:attr:`Vehicle.location.local_frame `, -:py:attr:`Vehicle.attitude `, -:py:attr:`Vehicle.velocity `, -:py:attr:`Vehicle.airspeed `, -:py:attr:`Vehicle.groundspeed `, -:py:attr:`Vehicle.gps_0 `, -:py:attr:`Vehicle.mount_status `, -:py:attr:`Vehicle.battery `, -:py:attr:`Vehicle.rangefinder `, -:py:attr:`Vehicle.ekf_ok `, -:py:attr:`Vehicle.last_heartbeat `, -:py:attr:`Vehicle.home_location `, -:py:func:`Vehicle.system_status `, -:py:func:`Vehicle.heading `, -:py:func:`Vehicle.is_armable `, -:py:attr:`Vehicle.armed `, -:py:attr:`Vehicle.mode `. +:py:attr:`Vehicle.location.global_frame `, +:py:attr:`Vehicle.location.global_relative_frame `, +:py:attr:`Vehicle.location.local_frame `, +:py:attr:`Vehicle.attitude `, +:py:attr:`Vehicle.velocity `, +:py:attr:`Vehicle.airspeed `, +:py:attr:`Vehicle.groundspeed `, +:py:attr:`Vehicle.gps_0 `, +:py:attr:`Vehicle.mount_status `, +:py:attr:`Vehicle.battery `, +:py:attr:`Vehicle.rangefinder `, +:py:attr:`Vehicle.ekf_ok `, +:py:attr:`Vehicle.last_heartbeat `, +:py:attr:`Vehicle.home_location `, +:py:func:`Vehicle.system_status `, +:py:func:`Vehicle.heading `, +:py:func:`Vehicle.is_armable `, +:py:attr:`Vehicle.armed `, +:py:attr:`Vehicle.mode `. Attributes are initially created with ``None`` values for their members. In most cases the members are populated (and repopulated) as new MAVLink messages of the associated types are received from the vehicle. All of the attributes can be :ref:`read `, -but only the :py:attr:`Vehicle.home_location `, -:py:attr:`Vehicle.mode ` and -:py:attr:`Vehicle.armed ` +but only the :py:attr:`Vehicle.home_location `, +:py:attr:`Vehicle.mode ` and +:py:attr:`Vehicle.armed ` status can be :ref:`written `. Almost all of the attributes can be :ref:`observed `. -The behaviour of :py:attr:`Vehicle.home_location ` is different +The behaviour of :py:attr:`Vehicle.home_location ` is different from the other attributes, and is :ref:`discussed in its own section below `. .. _vehicle_state_read_attributes: @@ -91,8 +91,8 @@ regularly updated from MAVLink messages sent by the vehicle). .. note:: A value of ``None`` for an attribute member indicates that the value has not yet been populated from the vehicle. - For example, before GPS lock :py:attr:`Vehicle.gps_0 ` will return a - :py:class:`GPSInfo ` with ``None`` values for ``eph``, ``satellites_visible`` etc. + For example, before GPS lock :py:attr:`Vehicle.gps_0 ` will return a + :py:class:`GPSInfo ` with ``None`` values for ``eph``, ``satellites_visible`` etc. Attributes will also return ``None`` if the associated hardware is not present on the connected device. @@ -112,7 +112,7 @@ regularly updated from MAVLink messages sent by the vehicle). Setting attributes ------------------ -Only the :py:attr:`Vehicle.mode ` and :py:attr:`Vehicle.armed ` +Only the :py:attr:`Vehicle.mode ` and :py:attr:`Vehicle.armed ` attributes can be written (``Vehicle.home_location`` is a special case, as :ref:`discussed below `). The attributes are set by assigning a value: @@ -155,14 +155,14 @@ You can observe any of the vehicle attributes and monitor for changes without th Listeners ("observer callback functions") are invoked differently based on the *type of observed attribute*. Attributes that represent sensor values or other "streams of information" are updated whenever a message is received from the vehicle. Attributes which reflect vehicle "state" are only updated when their values change (for example -:py:func:`Vehicle.system_status `, -:py:attr:`Vehicle.armed `, and -:py:attr:`Vehicle.mode `). +:py:func:`Vehicle.system_status `, +:py:attr:`Vehicle.armed `, and +:py:attr:`Vehicle.mode `). -Callbacks are added using :py:func:`Vehicle.add_attribute_listener() ` or the -:py:func:`Vehicle.on_attribute() ` decorator method. The main difference between these methods -is that only attribute callbacks added with :py:func:`Vehicle.add_attribute_listener() ` -can be removed (see :py:func:`remove_attribute_listener() `). +Callbacks are added using :py:func:`Vehicle.add_attribute_listener() ` or the +:py:func:`Vehicle.on_attribute() ` decorator method. The main difference between these methods +is that only attribute callbacks added with :py:func:`Vehicle.add_attribute_listener() ` +can be removed (see :py:func:`remove_attribute_listener() `). The ``observer`` callback function is invoked with the following arguments: @@ -173,8 +173,8 @@ The ``observer`` callback function is invoked with the following arguments: * ``value`` - the attribute value (so you don't need to re-query the vehicle object). The code snippet below shows how to add (and remove) a callback function to observe changes -in :py:attr:`Vehicle.location.global_frame ` using -:py:func:`Vehicle.add_attribute_listener() `. +in :py:attr:`Vehicle.location.global_frame ` using +:py:func:`Vehicle.add_attribute_listener() `. The two second ``sleep()`` is required because otherwise the observer might be removed before the the callback is first run. @@ -209,7 +209,7 @@ callback is first run. The example below shows how you can declare an attribute callback using the -:py:func:`Vehicle.on_attribute() ` decorator function. +:py:func:`Vehicle.on_attribute() ` decorator function. .. code-block:: python @@ -229,7 +229,7 @@ The example below shows how you can declare an attribute callback using the .. note:: The fragment above stores the result of the previous callback and only prints the output when there is a - signficant change in :py:attr:`Vehicle.rangefinder `. You might want to + signficant change in :py:attr:`Vehicle.rangefinder `. You might want to perform caching like this to ignore updates that are not significant to your code. The examples above show how you can monitor a single attribute. You can pass the special name ('``*``') to specify a @@ -263,10 +263,10 @@ The *Home location* is set when a vehicle first gets a good location fix from th as the target when the vehicle does a "return to launch". In Copter missions (and often Plane) missions, the altitude of waypoints is set relative to this position. -:py:attr:`Vehicle.home_location ` has the following behaviour: +:py:attr:`Vehicle.home_location ` has the following behaviour: -* In order to *get* the current value (in a :py:class:`LocationGlobal ` object) you must first download - :py:attr:`Vehicle.commands `, as shown: +* In order to *get* the current value (in a :py:class:`LocationGlobal ` object) you must first download + :py:attr:`Vehicle.commands `, as shown: .. code:: python @@ -291,7 +291,7 @@ waypoints is set relative to this position. # We have a home location. print "\n Home location: %s" % vehicle.home_location -* The attribute can be *set* to a :py:class:`LocationGlobal ` object +* The attribute can be *set* to a :py:class:`LocationGlobal ` object (the code fragment below sets it to the current location): .. code:: python @@ -311,7 +311,7 @@ waypoints is set relative to this position. .. note:: - :py:attr:`Vehicle.home_location ` behaves this way because + :py:attr:`Vehicle.home_location ` behaves this way because ArduPilot implements/stores the home location as a waypoint rather than sending them as messages. While DroneKit-Python hides this fact from you when working with commands, to access the value you still need to download the commands. @@ -338,8 +338,8 @@ until the download completes), and subsequently keeps the values updated by moni for changes to individual parameters. This process ensures that it is always safe to read supported parameters, and that their values will match the information on the vehicle. -Parameters can be read, set, observed and iterated using the :py:attr:`Vehicle.parameters ` -attribute (a :py:class:`Parameters ` object). +Parameters can be read, set, observed and iterated using the :py:attr:`Vehicle.parameters ` +attribute (a :py:class:`Parameters ` object). Getting parameters @@ -374,7 +374,7 @@ Vehicle parameters are set as shown in the code fragment below, using the parame Listing all parameters ---------------------- -:py:attr:`Vehicle.parameters ` can be iterated to list all parameters and their values: +:py:attr:`Vehicle.parameters ` can be iterated to list all parameters and their values: .. code:: python @@ -417,8 +417,8 @@ The ``observer`` callback function is invoked with the following arguments: The code snippet below demonstrates how you can add and remove a listener (in this case for "any parameter") using the -:py:func:`Parameters.add_attribute_listener() ` and -:py:func:`Parameters.remove_attribute_listener() `. +:py:func:`Parameters.add_attribute_listener() ` and +:py:func:`Parameters.remove_attribute_listener() `. .. code-block:: python diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 2d3b550e0..539c9ee14 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1,3 +1,86 @@ +# DroneAPI module +""" +This is the API Reference for the DroneKit-Python API. + +The main API is the :py:class:`Vehicle ` class. +The code snippet below shows how to use :py:func:`connect` to obtain an instance a connected vehicle: + +.. code:: python + + from dronekit import connect + + # Connect to the Vehicle using "connection string" (in this case an address on network) + vehicle = connect('127.0.0.1:14550', wait_ready=True) + +:py:class:`Vehicle ` provides access to vehicle *state* through python attributes +(e.g. :py:attr:`Vehicle.mode `) +and to settings/parameters though the :py:attr:`Vehicle.parameters ` attribute. +Asynchronous notification on vehicle attribute changes is available by registering observers. + +:py:class:`Vehicle ` provides two main ways to control vehicle movement and other operations: + +* Direct control of movement outside of missions is also supported. To set a target position you can use + :py:func:`CommandSequence.goto `. + Control over speed, direction, altitude, camera trigger and any other aspect of the vehicle is supported using custom MAVLink messages + (:py:func:`Vehicle.send_mavlink `, :py:func:`Vehicle.message_factory `). +* Missions are downloaded and uploaded through the :py:attr:`Vehicle.commands ` attribute + (see :py:class:`CommandSequence ` for more information). + +A number of other useful classes and methods are listed below. + +---- + +.. py:function:: connect(ip, wait_ready=None, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200, heartbeat_timeout=30, source_system=255) + + Returns a :py:class:`Vehicle` object connected to the address specified by string parameter ``ip``. + Connection string parameters (``ip``) for different targets are listed in the :ref:`getting started guide `. + + The method is usually called with ``wait_ready=True`` to ensure that vehicle parameters and (most) attributes are + available when ``connect()`` returns. + + .. code:: python + + from dronekit import connect + + # Connect to the Vehicle using "connection string" (in this case an address on network) + vehicle = connect('127.0.0.1:14550', wait_ready=True) + + :param String ip: :ref:`Connection string ` for target address - e.g. 127.0.0.1:14550. + + :param Bool/Array wait_ready: If ``True`` wait until all default attributes have downloaded before + the method returns (default is ``None``). + The default attributes to wait on are: :py:attr:`parameters`, :py:attr:`gps_0`, + :py:attr:`armed`, :py:attr:`mode`, and :py:attr:`attitude`. + + You can also specify a named set of parameters to wait on (e.g. ``wait_ready=['system_status','mode']``). + + For more information see :py:func:`Vehicle.wait_ready `. + + :param status_printer: Method of signature ``def status_printer(txt)`` that prints + STATUS_TEXT messages from the Vehicle and other diagnostic information. + By default the status information is printed to the command prompt in which the script is running. + :param Vehicle vehicle_class: The class that will be instantiated by the ``connect()`` method. + This can be any sub-class of ``Vehicle`` (and defaults to ``Vehicle``). + :param int rate: Data stream refresh rate. The default is 4Hz (4 updates per second). + :param int baud: The baud rate for the connection. The default is 115200. + :param int heartbeat_timeout: Connection timeout value in seconds (default is 30s). + If a heartbeat is not detected within this time an exception will be raised. + :param int source_system: The MAVLink ID of the :py:class:`Vehicle` object returned by this method (by default 255). + + .. note:: + + The returned :py:class:`Vehicle` object is acting as like a ground control station from the + perspective of the connected "real" vehicle. It will process/receive messages from the real vehicle + if they are addressed to this ``source_system`` id. Messages sent to the real vehicle are + automatically updated to use the vehicle's ``target_system`` id. + + It is *good practice* to assign a unique id for every system on the MAVLink network. + It is possible to configure the autopilot to only respond to guided-mode commands from a specified GCS ID. + + + :returns: A connected vehicle of the type defined in ``vehicle_class`` (a superclass of :py:class:`Vehicle`). +""" + from __future__ import print_function import time import socket @@ -5,25 +88,2132 @@ import os import platform import re -import dronekit.lib -from dronekit.lib import APIException -from dronekit.mavlink import MAVConnection from dronekit.util import errprinter from pymavlink import mavutil, mavwp from Queue import Queue, Empty from threading import Thread import types +import threading +import math +import copy +import collections +from pymavlink.dialects.v10 import ardupilotmega +from pymavlink import mavutil, mavwp +from dronekit.util import errprinter + +class APIException(Exception): + """ + Base class for DroneKit related exceptions. + + :param String message: Message string describing the exception + """ + + def __init__(self, message): + super(APIException, self).__init__(message) + +class Attitude(object): + """ + Attitude information. + + .. figure:: http://upload.wikimedia.org/wikipedia/commons/thumb/c/c1/Yaw_Axis_Corrected.svg/500px-Yaw_Axis_Corrected.svg.png + :width: 400px + :alt: Diagram showing Pitch, Roll, Yaw + :target: http://commons.wikimedia.org/wiki/File:Yaw_Axis_Corrected.svg + + Diagram showing Pitch, Roll, Yaw (`Creative Commons `_) + + :param pitch: Pitch in radians + :param yaw: Yaw in radians + :param roll: Roll in radians + """ + def __init__(self, pitch, yaw, roll): + self.pitch = pitch + self.yaw = yaw + self.roll = roll + + def __str__(self): + return "Attitude:pitch=%s,yaw=%s,roll=%s" % (self.pitch, self.yaw, self.roll) + +class LocationGlobal(object): + """ + A global location object. + + The latitude and longitude are relative to the `WGS84 coordinate system `_. + The altitude is relative to mean sea-level (MSL). + + For example, a global location object with altitude 30 metres above sea level might be defined as: + + .. code:: python + + LocationGlobal(-34.364114, 149.166022, 30) + + .. todo:: FIXME: Location class - possibly add a vector3 representation. + + An object of this type is owned by :py:attr:`Vehicle.location`. See that class for information on + reading and observing location in the global frame. + + :param lat: Latitude. + :param lon: Longitude. + :param alt: Altitude in meters relative to mean sea-level (MSL). + """ + def __init__(self, lat, lon, alt=None): + self.lat = lat + self.lon = lon + self.alt = alt + + # This is for backward compatibility. + self.local_frame = None + self.global_frame = None + + def __str__(self): + return "LocationGlobal:lat=%s,lon=%s,alt=%s" % (self.lat, self.lon, self.alt) + + +class LocationGlobalRelative(object): + """ + A global location object, with attitude relative to home location altitude. + + The latitude and longitude are relative to the `WGS84 coordinate system `_. + The altitude is relative to the *home position*. + + For example, a ``LocationGlobalRelative`` object with an altitude of 30 metres above the home location might be defined as: + + .. code:: python + + LocationGlobalRelative(-34.364114, 149.166022, 30) + + .. todo:: FIXME: Location class - possibly add a vector3 representation. + + An object of this type is owned by :py:attr:`Vehicle.location`. See that class for information on + reading and observing location in the global-relative frame. + + :param lat: Latitude. + :param lon: Longitude. + :param alt: Altitude in meters (relative to the home location). + """ + def __init__(self, lat, lon, alt=None): + self.lat = lat + self.lon = lon + self.alt = alt + + # This is for backward compatibility. + self.local_frame = None + self.global_frame = None + + def __str__(self): + return "LocationGlobalRelative:lat=%s,lon=%s,alt=%s" % (self.lat, self.lon, self.alt) + + +class LocationLocal(object): + """ + A local location object. + + The north, east and down are relative to the EKF origin. This is most likely the location where the vehicle was turned on. + + An object of this type is owned by :py:attr:`Vehicle.location`. See that class for information on + reading and observing location in the local frame. + + :param north: Position north of the EKF origin in meters. + :param east: Position east of the EKF origin in meters. + :param down: Position down from the EKF origin in meters. (i.e. negative altitude in meters) + """ + def __init__(self, north, east, down): + self.north = north + self.east = east + self.down = down + + def __str__(self): + return "LocationLocal:north=%s,east=%s,down=%s" % (self.north, self.east, self.down) + +class GPSInfo(object): + """ + Standard information about GPS. + + If there is no GPS lock the parameters are set to ``None``. + + :param Int eph: GPS horizontal dilution of position (HDOP). + :param Int epv: GPS horizontal dilution of position (VDOP). + :param Int fix_type: 0-1: no fix, 2: 2D fix, 3: 3D fix + :param Int satellites_visible: Number of satellites visible. + + .. todo:: FIXME: GPSInfo class - possibly normalize eph/epv? report fix type as string? + """ + def __init__(self, eph, epv, fix_type, satellites_visible): + self.eph = eph + self.epv = epv + self.fix_type = fix_type + self.satellites_visible = satellites_visible + + def __str__(self): + return "GPSInfo:fix=%s,num_sat=%s" % (self.fix_type, self.satellites_visible) + +class Battery(object): + """ + System battery information. + + :param voltage: Battery voltage in millivolts. + :param current: Battery current, in 10 * milliamperes. ``None`` if the autopilot does not support current measurement. + :param level: Remaining battery energy. ``None`` if the autopilot cannot estimate the remaining battery. + """ + def __init__(self, voltage, current, level): + self.voltage = voltage / 1000.0 + if current == -1: + self.current = None + else: + self.current = current / 100.0 + if level == -1: + self.level = None + else: + self.level = level + + def __str__(self): + return "Battery:voltage={},current={},level={}".format(self.voltage, self.current, self.level) + +class Rangefinder(object): + """ + Rangefinder readings. + + :param distance: Distance (metres). ``None`` if the vehicle doesn't have a rangefinder. + :param voltage: Voltage (volts). ``None`` if the vehicle doesn't have a rangefinder. + """ + def __init__(self, distance, voltage): + self.distance = distance + self.voltage = voltage + + def __str__(self): + return "Rangefinder: distance={}, voltage={}".format(self.distance, self.voltage) + +class VehicleMode(object): + """ + This object is used to get and set the current "flight mode". + + The flight mode determines the behaviour of the vehicle and what commands it can obey. + The recommended flight modes for *DroneKit-Python* apps depend on the vehicle type: + + * Copter apps should use ``AUTO`` mode for "normal" waypoint missions and ``GUIDED`` mode otherwise. + * Plane and Rover apps should use the ``AUTO`` mode in all cases, re-writing the mission commands if "dynamic" + behaviour is required (they support only a limited subset of commands in ``GUIDED`` mode). + * Some modes like ``RETURN_TO_LAUNCH`` can be used on all platforms. Care should be taken + when using manual modes as these may require remote control input from the user. + + The available set of supported flight modes is vehicle-specific (see + `Copter `_, + `Plane `_, + `Rover `_). If an unsupported mode is set the script + will raise a ``KeyError`` exception. + + The :py:attr:`Vehicle.mode ` attribute can be queried for the current mode. + The code snippet below shows how to observe changes to the mode and then read the value: + + .. code:: python + + #Callback definition for mode observer + def mode_callback(self, attr_name): + print "Vehicle Mode", self.mode + + #Add observer callback for attribute `mode` + vehicle.add_attribute_listener('mode', mode_callback) + + The code snippet below shows how to change the vehicle mode to AUTO: + + .. code:: python + + # Set the vehicle into auto mode + vehicle.mode = VehicleMode("AUTO") + + For more information on getting/setting/observing the :py:attr:`Vehicle.mode ` + (and other attributes) see the :ref:`attributes guide `. + + .. py:attribute:: name + + The mode name, as a ``string``. + """ + def __init__(self, name): + self.name = name + + def __str__(self): + return "VehicleMode:%s" % self.name + + def __eq__(self, other): + return self.name == other + + def __ne__(self, other): + return self.name != other + +class SystemStatus(object): + """ + This object is used to get and set the current "system status". + + .. py:attribute:: state + + The system state, as a ``string``. + """ + def __init__(self, state): + self.state = state + + def __str__(self): + return "SystemStatus:%s" % self.state + + def __eq__(self, other): + return self.state == other + + def __ne__(self, other): + return self.state != other + +class HasObservers(object): + def __init__(self): + # A mapping from attr_name to a list of observers + self._attribute_listeners = {} + self._attribute_cache = {} + + """ + Provides callback based notification on attribute changes. + + The argument list for observer is ``observer(object, attr_name, attribute_value)``. + """ + def add_attribute_listener(self, attr_name, observer): + """ + Add an attribute listener callback. + + The callback function (``observer``) is invoked differently depending on the *type of attribute*. + Attributes that represent sensor values or which are used to monitor connection status are updated + whenever a message is received from the vehicle. Attributes which reflect vehicle "state" are + only updated when their values change (for example :py:func:`Vehicle.system_status `, + :py:attr:`Vehicle.armed `, and :py:attr:`Vehicle.mode `). + + The callback can be removed using :py:func:`remove_attribute_listener`. + + .. note:: + + The :py:func:`on_attribute` decorator performs the same operation as this method, but with + a more elegant syntax. Use ``add_attribute_listener`` by preference if you will need to remove + the observer. + + The callback arguments are: + + * ``self`` - the associated :py:class:`Vehicle`. This may be compared to a global vehicle handle + to implement vehicle-specific callback handling (if needed). + * ``attr_name`` - the attribute name. This can be used to infer which attribute has triggered + if the same callback is used for watching several attributes. + * ``value`` - the attribute value (so you don't need to re-query the vehicle object). + + The example below shows how to get callbacks for (global) location changes: + + .. code:: python + + #Callback to print the location in global frame + def location_callback(self, attr_name, msg): + print "Location (Global): ", msg + + #Add observer for the vehicle's current location + vehicle.add_attribute_listener('global_frame', location_callback) + + See :ref:`vehicle_state_observe_attributes` for more information. + + :param String attr_name: The name of the attribute to watch (or '*' to watch all attributes). + :param observer: The callback to invoke when a change in the attribute is detected. + + """ + l = self._attribute_listeners.get(attr_name) + if l is None: + l = [] + self._attribute_listeners[attr_name] = l + if not observer in l: + l.append(observer) + + def remove_attribute_listener(self, attr_name, observer): + """ + Remove an attribute listener (observer) that was previously added using :py:func:`add_attribute_listener`. + + For example, the following line would remove a previously added vehicle 'global_frame' + observer called ``location_callback``: + + .. code:: python + + vehicle.remove_attribute_listener('global_frame', location_callback) + + See :ref:`vehicle_state_observe_attributes` for more information. + + :param String attr_name: The attribute name that is to have an observer removed (or '*' to remove an 'all attribute' observer). + :param observer: The callback function to remove. + + """ + l = self._attribute_listeners.get(attr_name) + if l is not None: + l.remove(observer) + if len(l) == 0: + del self._attribute_listeners[attr_name] + + + def notify_attribute_listeners(self, attr_name, value, cache=False): + """ + This method is used to update attribute observers when the named attribute is updated. + + You should call it in your message listeners after updating an attribute with + information from a vehicle message. + + By default the value of ``cache`` is ``False`` and every update from the vehicle is sent to listeners + (whether or not the attribute has changed). This is appropriate for attributes which represent sensor + or heartbeat-type monitoring. + + Set ``cache=True`` to update listeners only when the value actually changes (cache the previous + attribute value). This should be used where clients will only ever need to know the value when it has + changed. For example, this setting has been used for notifying :py:attr:`mode` changes. + + See :ref:`example_create_attribute` for more information. + + :param String attr_name: The name of the attribute that has been updated. + :param value: The current value of the attribute that has been updated. + :param Boolean cache: Set ``True`` to only notify observers when the attribute value changes. + """ + # Cached values are not re-sent if they are unchanged. + if cache: + if attr_name in self._attribute_cache and self._attribute_cache[attr_name] == value: + return + self._attribute_cache[attr_name] = value + + # Notify observers. + for fn in self._attribute_listeners.get(attr_name, []): + fn(self, attr_name, value) + for fn in self._attribute_listeners.get('*', []): + fn(self, attr_name, value) + + def on_attribute(self, name): + """ + Decorator for attribute listeners. + + The decorated function (``observer``) is invoked differently depending on the *type of attribute*. + Attributes that represent sensor values or which are used to monitor connection status are updated + whenever a message is received from the vehicle. Attributes which reflect vehicle "state" are + only updated when their values change (for example :py:func:`Vehicle.system_status `, + :py:attr:`Vehicle.armed `, and :py:attr:`Vehicle.mode `). + + The callback arguments are: + + * ``self`` - the associated :py:class:`Vehicle`. This may be compared to a global vehicle handle + to implement vehicle-specific callback handling (if needed). + * ``attr_name`` - the attribute name. This can be used to infer which attribute has triggered + if the same callback is used for watching several attributes. + * ``msg`` - the attribute value (so you don't need to re-query the vehicle object). + + .. note:: + + There is no way to remove an attribute listener added with this decorator. Use + :py:func:`add_attribute_listener` if you need to be able to remove + the :py:func:`attribute listener `. + + The code fragment below shows how you can create a listener for the attitude attribute. + + .. code:: python + + @vehicle.on_attribute('attitude') + def attitude_listener(self, name, msg): + print '%s attribute is: %s' % (name, msg) + + See :ref:`vehicle_state_observe_attributes` for more information. + + :param String attr_name: The name of the attribute to watch (or '*' to watch all attributes). + :param observer: The callback to invoke when a change in the attribute is detected. + """ + def decorator(fn): + if isinstance(name, list): + for n in name: + self.add_attribute_listener(n, fn) + else: + self.add_attribute_listener(name, fn) + return decorator + +class ChannelsOverride(dict): + """ + A dictionary class for managing Vehicle channel overrides. + + Channels can be read, written, or cleared by index or using a dictionary syntax. + To clear a value, set it to ``None`` or use ``del`` on the item. + + For more information and examples see :ref:`example_channel_overrides`. + """ + def __init__(self, vehicle): + self._vehicle = vehicle + self._count = 8 # Fixed by MAVLink + self._active = True + + def __getitem__(self, key): + return dict.__getitem__(self, str(key)) + + def __setitem__(self, key, value): + if not (int(key) > 0 and int(key) <= self._count): + raise Exception('Invalid channel index %s' % key) + if not value: + try: + dict.__delitem__(self, str(key)) + except: + pass + else: + dict.__setitem__(self, str(key), value) + self._send() + + def __delitem__(self, key): + dict.__delitem__(self, str(key)) + self._send() + + def __len__(self): + return self._count + + def _send(self): + if self._active: + overrides = [0] * 8 + for k, v in self.iteritems(): + overrides[int(k)-1] = v + self._vehicle._master.mav.rc_channels_override_send(0, 0, *overrides) + + +class Channels(dict): + """ + A dictionary class for managing RC channel information associated with a :py:class:`Vehicle`. + + An object of this type is accessed through :py:attr:`Vehicle.channels`. This object also stores + the current vehicle channel overrides through its :py:attr:`overrides` attribute. + + For more information and examples see :ref:`example_channel_overrides`. + """ + + def __init__(self, vehicle, count): + self._vehicle = vehicle + self._count = count + self._overrides = ChannelsOverride(vehicle) + + # populate readback + self._readonly = False + for k in range(0, count): + self[k + 1] = None + self._readonly = True + + @property + def count(self): + """ + The number of channels defined in the dictionary (currently 8). + """ + return self._count + + def __getitem__(self, key): + return dict.__getitem__(self, str(key)) + + def __setitem__(self, key, value): + if self._readonly: + raise TypeError('__setitem__ is not supported on Channels object') + return dict.__setitem__(self, str(key), value) + + def __len__(self): + return self._count + + def _update_channel(self, channel, value): + # If we have channels on different ports, we expand the Channels + # object to support them. + channel = int(channel) + self._readonly = False + self[channel] = value + self._readonly = True + self._count = max(self._count, channel) + + @property + def overrides(self): + """ + Attribute to read, set and clear channel overrides (also known as "rc overrides") + associated with a :py:class:`Vehicle` (via :py:class:`Vehicle.channels`). This is an + object of type :py:class:`ChannelsOverride`. + + For more information and examples see :ref:`example_channel_overrides`. + + To set channel overrides: + + .. code:: python + + # Set and clear overrids using dictionary syntax (clear by setting override to none) + vehicle.channels.overrides = {'5':None, '6':None,'3':500} + + # You can also set and clear overrides using indexing syntax + vehicle.channels.overrides['2'] = 200 + vehicle.channels.overrides['2'] = None + + # Clear using 'del' + del vehicle.channels.overrides['3'] + + # Clear all overrides by setting an empty dictionary + vehicle.channels.overrides = {} + + Read the channel overrides either as a dictionary or by index. Note that you'll get + a ``KeyError`` exception if you read a channel override that has not been set. + + .. code:: python + + # Get all channel overrides + print " Channel overrides: %s" % vehicle.channels.overrides + # Print just one channel override + print " Ch2 override: %s" % vehicle.channels.overrides['2'] + """ + return self._overrides + + @overrides.setter + def overrides(self, newch): + self._overrides._active = False + self._overrides.clear() + for k, v in newch.iteritems(): + if v: + self._overrides[str(k)] = v + else: + try: + del self._overrides[str(k)] + except: + pass + self._overrides._active = True + self._overrides._send() + +class Locations(HasObservers): + """ + An object for holding location information in global, global relative and local frames. + + :py:class:`Vehicle` owns an object of this type. See :py:attr:`Vehicle.location` for information on + reading and observing location in the different frames. + + The different frames are accessed through the members, which are created with this object. + They can be read, and are observable. + """ + def __init__(self, vehicle): + super(Locations, self).__init__() + + self._lat = None + self._lon = None + self._alt = None + self._relative_alt = None + + @vehicle.on_message('GLOBAL_POSITION_INT') + def listener(vehicle, name, m): + (self._lat, self._lon) = (m.lat / 1.0e7, m.lon / 1.0e7) + self._relative_alt = m.relative_alt/1000.0 + self.notify_attribute_listeners('global_relative_frame', self.global_relative_frame) + vehicle.notify_attribute_listeners('location.global_relative_frame', vehicle.location.global_relative_frame) + + if self._alt != None or m.alt != 0: + # Require first alt value to be non-0 + # TODO is this the proper check to do? + self._alt = m.alt/1000.0 + self.notify_attribute_listeners('global_frame', self.global_frame) + vehicle.notify_attribute_listeners('location.global_frame', vehicle.location.global_frame) + + vehicle.notify_attribute_listeners('location', vehicle.location) + + self._north = None + self._east = None + self._down = None + + @vehicle.on_message('LOCAL_POSITION_NED') + def listener(vehicle, name, m): + self._north = m.x + self._east = m.y + self._down = m.z + self.notify_attribute_listeners('local_frame', self.local_frame) + vehicle.notify_attribute_listeners('location.local_frame', vehicle.location.local_frame) + vehicle.notify_attribute_listeners('location', vehicle.location) + + @property + def local_frame(self): + """ + Location in local NED frame (a :py:class:`LocationGlobalRelative`). + + This is accessed through the :py:attr:`Vehicle.location ` attribute: + + .. code-block:: python + + print "Local Location: %s" % vehicle.location.local_frame + + This location will not start to update until the vehicle is armed. + """ + return LocationLocal(self._north, self._east, self._down) + + @property + def global_frame(self): + """ + Location in global frame (a :py:class:`LocationGlobal`). + + This is accessed through the :py:attr:`Vehicle.location ` attribute: + + .. code-block:: python + + print "Global Location: %s" % vehicle.location.global_frame + + Its ``lat`` and ``lon`` attributes are populated shortly after GPS becomes available. + The ``alt`` can take several seconds longer to populate (from the barometer). + Listeners are not notified of changes to this attribute until it has fully populated. + """ + return LocationGlobal(self._lat, self._lon, self._alt) + + @property + def global_relative_frame(self): + """ + Location in global frame, with altitude relative to the home location + (a :py:class:`LocationGlobalRelative`). + + This is accessed through the :py:attr:`Vehicle.location ` attribute: + + .. code-block:: python + + print "Global Location (relative altitude): %s" % vehicle.location.global_relative_frame + """ + return LocationGlobalRelative(self._lat, self._lon, self._relative_alt) + + +class Vehicle(HasObservers): + """ + The main vehicle API + + Asynchronous notification on change of vehicle state is available by registering observers (callbacks) for attribute changes. + + Most vehicle state is exposed through python attributes (e.g. ``vehicle.location``). Most of these attributes are + auto-populated based on the capabilities of the connected autopilot/vehicle. + + Particular autopilots/vehicles may define different attributes from this standard list (extra batteries, GPIOs, etc.) + However if a standard attribute is defined it must follow the rules specified below. + + **Autopilot specific attributes & types:** + + To prevent name clashes the following naming convention should be used: + + * ``ap_`` - For autopilot specific parameters (apm 2.5, pixhawk etc.). For example "ap_pin5_mode" and "ap_pin5_value". + * ``user_`` - For user specific parameters + + **Standard attributes & types:** + + .. py:attribute:: attitude + + Current vehicle :py:class:`Attitude` (pitch, yaw, roll). + + .. py:attribute:: velocity + + Current velocity as a three element list ``[ vx, vy, vz ]`` (in meter/sec). + + .. py:attribute:: mode + + This attribute is used to get and set the current flight mode (:py:class:`VehicleMode`). + + .. py:attribute:: airspeed + + Current airspeed in metres/second (``double``). + + .. todo:: FIXME: Should airspeed value move somewhere else from "Standard attributes & types" table? + + .. py:attribute:: groundspeed + + Groundspeed in metres/second (``double``). + + .. py:attribute:: gps_0 + + GPS position information (:py:class:`GPSInfo`). + + .. py:attribute:: armed + + This attribute can be used to get and set the ``armed`` state of the vehicle (``boolean``). + + The code below shows how to read the state, and to arm/disam the vehicle: + + .. code:: python + + # Print the armed state for the vehicle + print "Armed: %s" % vehicle.armed + + # Disarm the vehicle + vehicle.armed = False + + # Arm the vehicle + vehicle.armed = True + + .. py:attribute:: mount_status + + Current status of the camera mount (gimbal) as a three element list: ``[ pitch, yaw, roll ]``. + + The values in the list are set to ``None`` if no mount is configured. + + .. py:attribute:: battery + + Current system :py:class:`Battery` status. + + .. py:attribute:: rangefinder + + :py:class:`Rangefinder` distance and voltage values. + + + + **Autopilot specific attributes & types:** + + .. py:attribute:: ap_pin5_mode + + string (adc, dout, din) + + .. py:attribute:: ap_pin5_value + + ? double (0, 1, 2.3 etc...) + + .. todo:: Add waypoint_home attribute IF this is added: https://github.com/dronekit/dronekit-python/issues/105 + + """ + + def __init__(self, handler): + super(Vehicle, self).__init__() + + self._handler = handler + self._master = handler.master + + # Cache all updated attributes for wait_ready. + # By default, we presume all "commands" are loaded. + self._ready_attrs = set(['commands']) + + # Default parameters when calling wait_ready() or wait_ready(True). + self._default_ready_attrs = ['parameters', 'gps_0', 'armed', 'mode', 'attitude'] + + @self.on_attribute('*') + def listener(_, name, value): + self._ready_attrs.add(name) + + # Attaches message listeners. + self._message_listeners = dict() + + @handler.forward_message + def listener(_, msg): + self.notify_message_listeners(msg.get_type(), msg) + + self._location = Locations(self) + self._vx = None + self._vy = None + self._vz = None + + @self.on_message('GLOBAL_POSITION_INT') + def listener(self, name, m): + (self._vx, self._vy, self._vz) = (m.vx / 100.0, m.vy / 100.0, m.vz / 100.0) + self.notify_attribute_listeners('velocity', self.velocity) + + self._pitch = None + self._yaw = None + self._roll = None + self._pitchspeed = None + self._yawspeed = None + self._rollspeed = None + + @self.on_message('ATTITUDE') + def listener(self, name, m): + self._pitch = m.pitch + self._yaw = m.yaw + self._roll = m.roll + self._pitchspeed = m.pitchspeed + self._yawspeed = m.yawspeed + self._rollspeed = m.rollspeed + self.notify_attribute_listeners('attitude', self.attitude) + + self._heading = None + self._airspeed = None + self._groundspeed = None + + @self.on_message('VFR_HUD') + def listener(self, name, m): + self._heading = m.heading + self.notify_attribute_listeners('heading', self.heading) + self._airspeed = m.airspeed + self.notify_attribute_listeners('airspeed', self.airspeed) + self._groundspeed = m.groundspeed + self.notify_attribute_listeners('groundspeed', self.groundspeed) + + self._rngfnd_distance = None + self._rngfnd_voltage = None + + @self.on_message('RANGEFINDER') + def listener(self, name, m): + self._rngfnd_distance = m.distance + self._rngfnd_voltage = m.voltage + self.notify_attribute_listeners('rangefinder', self.rangefinder) + + self._mount_pitch = None + self._mount_yaw = None + self._mount_roll = None + + @self.on_message('MOUNT_STATUS') + def listener(self, name, m): + self._mount_pitch = m.pointing_a / 100 + self._mount_roll = m.pointing_b / 100 + self._mount_yaw = m.pointing_c / 100 + self.notify_attribute_listeners('mount', self.mount_status) + + # All keys are strings. + self._channels = Channels(self, 8) + + @self.on_message('RC_CHANNELS_RAW') + def listener(self, name, m): + def set_rc(chnum, v): + '''Private utility for handling rc channel messages''' + # use port to allow ch nums greater than 8 + self._channels._update_channel(str(m.port * 8 + chnum), v) -# Public re-exports -Vehicle = dronekit.lib.Vehicle -Command = dronekit.lib.Command -CommandSequence = dronekit.lib.CommandSequence -VehicleMode = dronekit.lib.VehicleMode -SystemStatus = dronekit.lib.SystemStatus -LocationGlobalRelative = dronekit.lib.LocationGlobalRelative -LocationGlobal = dronekit.lib.LocationGlobal -LocationLocal = dronekit.lib.LocationLocal -CloudClient = dronekit.lib.CloudClient + set_rc(1, m.chan1_raw) + set_rc(2, m.chan2_raw) + set_rc(3, m.chan3_raw) + set_rc(4, m.chan4_raw) + set_rc(5, m.chan5_raw) + set_rc(6, m.chan6_raw) + set_rc(7, m.chan7_raw) + set_rc(8, m.chan8_raw) + self.notify_attribute_listeners('channels', self.channels) + + self._voltage = None + self._current = None + self._level = None + + @self.on_message('SYS_STATUS') + def listener(self, name, m): + self._voltage = m.voltage_battery + self._current = m.current_battery + self._level = m.battery_remaining + self.notify_attribute_listeners('battery', self.battery) + + self._eph = None + self._epv = None + self._satellites_visible = None + self._fix_type = None # FIXME support multiple GPSs per vehicle - possibly by using componentId + + @self.on_message('GPS_RAW_INT') + def listener(self, name, m): + self._eph = m.eph + self._epv = m.epv + self._satellites_visible = m.satellites_visible + self._fix_type = m.fix_type + self.notify_attribute_listeners('gps_0', self.gps_0) + + self._current_waypoint = 0 + + @self.on_message(['WAYPOINT_CURRENT', 'MISSION_CURRENT']) + def listener(self, name, m): + self._current_waypoint = m.seq + + self._ekf_poshorizabs = False + self._ekf_constposmode = False + self._ekf_predposhorizabs = False + + @self.on_message('EKF_STATUS_REPORT') + def listener(self, name, m): + # boolean: EKF's horizontal position (absolute) estimate is good + self._ekf_poshorizabs = (m.flags & ardupilotmega.EKF_POS_HORIZ_ABS) > 0 + # boolean: EKF is in constant position mode and does not know it's absolute or relative position + self._ekf_constposmode = (m.flags & ardupilotmega.EKF_CONST_POS_MODE) > 0 + # boolean: EKF's predicted horizontal position (absolute) estimate is good + self._ekf_predposhorizabs = (m.flags & ardupilotmega.EKF_PRED_POS_HORIZ_ABS) > 0 + + self.notify_attribute_listeners('ekf_ok', self.ekf_ok) + + self._flightmode = 'AUTO' + self._armed = False + self._system_status = None + + @self.on_message('HEARTBEAT') + def listener(self, name, m): + self._armed = (m.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED) != 0 + self.notify_attribute_listeners('armed', self.armed, cache=True) + self._flightmode = {v: k for k, v in self._master.mode_mapping().items()}[m.custom_mode] + self.notify_attribute_listeners('mode', self.mode, cache=True) + self._system_status = m.system_status + self.notify_attribute_listeners('system_status', self.system_status, cache=True) + + # Waypoints. + + self._home_location = None + self._wploader = mavwp.MAVWPLoader() + self._wp_loaded = True + self._wp_uploaded = None + self._wpts_dirty = False + self._commands = CommandSequence(self) + + @self.on_message(['WAYPOINT_COUNT','MISSION_COUNT']) + def listener(self, name, msg): + if not self._wp_loaded: + self._wploader.clear() + self._wploader.expected_count = msg.count + self._master.waypoint_request_send(0) + + @self.on_message(['WAYPOINT', 'MISSION_ITEM']) + def listener(self, name, msg): + if not self._wp_loaded: + if msg.seq == 0: + if not (msg.x == 0 and msg.y == 0 and msg.z == 0): + self._home_location = LocationGlobal(msg.x, msg.y, msg.z) + + if msg.seq > self._wploader.count(): + # Unexpected waypoint + pass + elif msg.seq < self._wploader.count(): + # Waypoint duplicate + pass + else: + self._wploader.add(msg) + + if msg.seq + 1 < self._wploader.expected_count: + self._master.waypoint_request_send(msg.seq + 1) + else: + self._wp_loaded = True + self.notify_attribute_listeners('commands', self.commands) + + # Waypoint send to master + @self.on_message(['WAYPOINT_REQUEST', 'MISSION_REQUEST']) + def listener(self, name, msg): + if self._wp_uploaded != None: + wp = self._wploader.wp(msg.seq) + handler.fix_targets(wp) + self._master.mav.send(wp) + self._wp_uploaded[msg.seq] = True + + # TODO: Waypoint loop listeners + + # Parameters. + + start_duration = 0.2 + repeat_duration = 1 + + self._params_count = -1 + self._params_set = [] + self._params_loaded = False + self._params_start = False + self._params_map = {} + self._params_last = time.time() # Last new param. + self._params_duration = start_duration + self._parameters = Parameters(self) + + @handler.forward_loop + def listener(_): + # Check the time duration for last "new" params exceeds watchdog. + if self._params_start: + if None not in self._params_set and not self._params_loaded: + self._params_loaded = True + self.notify_attribute_listeners('parameters', self.parameters) + + if not self._params_loaded and time.time() - self._params_last > self._params_duration: + c = 0 + for i, v in enumerate(self._params_set): + if v == None: + self._master.mav.param_request_read_send(0, 0, '', i) + c += 1 + if c > 50: + break + self._params_duration = repeat_duration + self._params_last = time.time() + + @self.on_message(['PARAM_VALUE']) + def listener(self, name, msg): + # If we discover a new param count, assume we + # are receiving a new param set. + if self._params_count != msg.param_count: + self._params_loaded = False + self._params_start = True + self._params_count = msg.param_count + self._params_set = [None]*msg.param_count + + # Attempt to set the params. We throw an error + # if the index is out of range of the count or + # we lack a param_id. + try: + if msg.param_index < msg.param_count and msg: + if self._params_set[msg.param_index] == None: + self._params_last = time.time() + self._params_duration = start_duration + self._params_set[msg.param_index] = msg + self._params_map[msg.param_id] = msg.param_value + self._parameters.notify_attribute_listeners(msg.param_id, msg.param_value, cache=True) + except: + import traceback + traceback.print_exc() + + # Heartbeats. + + self._heartbeat_started = False + self._heartbeat_lastsent = 0 + self._heartbeat_lastreceived = 0 + self._heartbeat_timeout = False + + self._heartbeat_warning = 5 + self._heartbeat_error = 30 + self._heartbeat_system = None + + @handler.forward_loop + def listener(_): + # Send 1 heartbeat per second + if time.time() - self._heartbeat_lastsent > 1: + self._master.mav.heartbeat_send(mavutil.mavlink.MAV_TYPE_GCS, mavutil.mavlink.MAV_AUTOPILOT_INVALID, 0, 0, 0) + self._heartbeat_lastsent = time.time() + + # Timeouts. + if self._heartbeat_started: + 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) + elif time.time() - self._heartbeat_lastreceived > self._heartbeat_warning: + if self._heartbeat_timeout == False: + errprinter('>>> Link timeout, no heartbeat in last %s seconds' % self._heartbeat_warning) + self._heartbeat_timeout = True + + @self.on_message(['HEARTBEAT']) + def listener(self, name, msg): + self._heartbeat_system = msg.get_srcSystem() + self._heartbeat_lastreceived = time.time() + if self._heartbeat_timeout: + errprinter('>>> ...link restored.') + self._heartbeat_timeout = False + + self._last_heartbeat = None + + @handler.forward_loop + def listener(_): + if self._heartbeat_lastreceived: + self._last_heartbeat = time.time() - self._heartbeat_lastreceived + self.notify_attribute_listeners('last_heartbeat', self.last_heartbeat) + + @property + def last_heartbeat(self): + """ + Time since last MAVLink heartbeat was received (in seconds). + + The attribute can be used to monitor link activity and implement script-specific timeout handling. + + For example, to pause the script if no heartbeat is received for more than 1 second you might implement + the following observer, and use ``pause_script`` in a program loop to wait until the link is recovered: + + .. code-block:: python + + pause_script=False + + @vehicle.on_attribute('last_heartbeat') + def listener(self, attr_name, value): + global pause_script + if value > 1 and not pause_script: + print "Pausing script due to bad link" + pause_script=True; + if value < 1 and pause_script: + pause_script=False; + print "Un-pausing script" + + The observer will be called at the period of the messaging loop (about every 0.01 seconds). Testing + on SITL indicates that ``last_heartbeat`` averages about .5 seconds, but will rarely exceed 1.5 seconds + when connected. Whether heartbeat monitoring can be useful will very much depend on the application. + + + .. note:: + + If you just want to change the heartbeat timeout you can modify the ``heartbeat_timeout`` + parameter passed to the :py:func:`connect() ` function. + + """ + return self._last_heartbeat + + def on_message(self, name): + """ + Decorator for message listener callback functions. + + .. tip:: + + This is the most elegant way to define message listener callback functions. + Use :py:func:`add_message_listener` only if you need to be able to + :py:func:`remove the listener ` later. + + A decorated message listener function is called with three arguments every time the + specified message is received: + + * ``self`` - the current vehicle. + * ``name`` - the name of the message that was intercepted. + * ``message`` - the actual message (a `pymavlink `_ + `class `_). + + For example, in the fragment below ``my_method`` will be called for every heartbeat message: + + .. code:: python + + @vehicle.on_message('HEARTBEAT') + def my_method(self, name, msg): + pass + + See :ref:`mavlink_messages` for more information. + + :param String name: The name of the message to be intercepted by the decorated listener function (or '*' to get all messages). + """ + def decorator(fn): + if isinstance(name, list): + for n in name: + self.add_message_listener(n, fn) + else: + self.add_message_listener(name, fn) + return decorator + + def add_message_listener(self, name, fn): + """ + Adds a message listener function that will be called every time the specified message is received. + + .. tip:: + + We recommend you use :py:func:`on_message` instead of this method as it has a more elegant syntax. + This method is only preferred if you need to be able to + :py:func:`remove the listener `. + + The callback function must have three arguments: + + * ``self`` - the current vehicle. + * ``name`` - the name of the message that was intercepted. + * ``message`` - the actual message (a `pymavlink `_ + `class `_). + + For example, in the fragment below ``my_method`` will be called for every heartbeat message: + + .. code:: python + + #Callback method for new messages + def my_method(self, name, msg): + pass + + vehicle.add_message_listener('HEARTBEAT',my_method) + + See :ref:`mavlink_messages` for more information. + + :param String name: The name of the message to be intercepted by the listener function (or '*' to get all messages). + :param fn: The listener function that will be called if a message is received. + """ + name = str(name) + if name not in self._message_listeners: + self._message_listeners[name] = [] + if fn not in self._message_listeners[name]: + self._message_listeners[name].append(fn) + + def remove_message_listener(self, name, fn): + """ + Removes a message listener (that was previously added using :py:func:`add_message_listener`). + + See :ref:`mavlink_messages` for more information. + + :param String name: The name of the message for which the listener is to be removed (or '*' to remove an 'all messages' observer). + :param fn: The listener callback function to remove. + + """ + name = str(name) + if name in self._message_listeners: + self._message_listeners[name].remove(fn) + if len(self._message_listeners[name]) == 0: + del self._message_listeners[name] + + def notify_message_listeners(self, name, msg): + for fn in self._message_listeners.get(name, []): + fn(self, name, msg) + for fn in self._message_listeners.get('*', []): + fn(self, name, msg) + + def close(self): + return self._handler.close() + + def flush(self): + """ + Call ``flush()`` after :py:func:`adding ` or :py:func:`clearing ` mission commands. + + After the return from ``flush()`` any writes are guaranteed to have completed (or thrown an + exception) and future reads will see their effects. + + .. warning:: + + This has been replaced by :py:func:`Vehicle.commands.upload() `. + """ + return self.commands.upload() + + # + # Private sugar methods + # + + @property + def _mode_mapping(self): + return self._master.mode_mapping() + + # + # Operations to support the standard API. + # + + @property + def mode(self): + if not self._flightmode: + return None + return VehicleMode(self._flightmode) + + @mode.setter + def mode(self, v): + self._master.set_mode(self._mode_mapping[v.name]) + + @property + def location(self): + """ + A :py:class:`Locations` object containing vehicle location information in + global, global relative and local frames. + + The different frames are accessed through its members: + + * :py:attr:`global_frame ` (a :py:class:`LocationGlobal`) + * :py:attr:`global_relative_frame ` (a :py:class:`LocationGlobalRelative`) + * :py:attr:`local_frame ` (a :py:class:`LocationLocal`) + + For example, to print the location in each frame for a ``vehicle``: + + .. code-block:: python + + # Print location information for `vehicle` in all frames (default printer) + print "Global Location: %s" % vehicle.location.global_frame + print "Global Location (relative altitude): %s" % vehicle.location.global_relative_frame + print "Local Location: %s" % vehicle.location.local_frame #NED + + # Print altitudes in the different frames (see class definitions for other available information) + print "Altitude (global frame): %s" % vehicle.location.global_frame.alt + print "Altitude (global relative frame): %s" % vehicle.location.global_relative_frame.alt + print "Altitude (NED frame): %s" % vehicle.location.local_frame.down + + .. note:: + + All the location "values" (e.g. ``global_frame.lat``) are initially + created with value ``None``. The ``global_frame``, ``global_relative_frame`` + latitude and longitude values are populated shortly after initialisation but + ``global_frame.alt`` may take a few seconds longer to be updated. + The ``local_frame`` does not populate until the vehicle is armed. + + The attribute and its members are observable. To watch for changes in all frames using a listener + created using a decorator (you can also define a listener and explicitly add it). + + .. code-block:: python + + @vehicle.on_attribute('location') + def listener(self, attr_name, value): + # `self`: :py:class:`Vehicle` object that has been updated. + # `attr_name`: name of the observed attribute - 'location' + # `value` is the updated attribute value (a :py:class:`Locations`). This can be queried for the frame information + print " Global: %s" % value.global_frame + print " GlobalRelative: %s" % value.global_relative_frame + print " Local: %s" % value.local_frame + + To watch for changes in just one attribute (in this case ``global_frame``): + + .. code-block:: python + + @vehicle.on_attribute('location.global_frame') + def listener(self, attr_name, value): + # `self`: :py:class:`Locations` object that has been updated. + # `attr_name`: name of the observed attribute - 'global_frame' + # `value` is the updated attribute value. + print " Global: %s" % value + + #Or watch using decorator: ``@vehicle.location.on_attribute('global_frame')``. + """ + return self._location + + @property + def battery(self): + if self._voltage == None or self._current == None or self._level == None: + return None + return Battery(self._voltage, self._current, self._level) + + @property + def rangefinder(self): + return Rangefinder(self._rngfnd_distance, self._rngfnd_voltage) + + @property + def velocity(self): + return [ self._vx, self._vy, self._vz ] + + @property + def attitude(self): + return Attitude(self._pitch, self._yaw, self._roll) + + @property + def gps_0(self): + return GPSInfo(self._eph, self._epv, self._fix_type, self._satellites_visible) + + @property + def armed(self): + return self._armed + + @armed.setter + def armed(self, value): + if bool(value) != self._armed: + if value: + self._master.arducopter_arm() + else: + self._master.arducopter_disarm() + + @property + def is_armable(self): + """ + Returns ``True`` if the vehicle is ready to arm, false otherwise. + + This attribute wraps a number of pre-arm checks, ensuring that the vehicle has booted, + has a good GPS fix, and that the EKF pre-arm is complete. + """ + # check that mode is not INITIALSING + # check that we have a GPS fix + # check that EKF pre-arm is complete + return self.mode != 'INITIALISING' and self.gps_0.fix_type > 1 and self._ekf_predposhorizabs + + @property + def system_status(self): + """ + System status. Is a ``SystemStatus`` object with a ``state`` property of: + + * ``UNINIT``: Uninitialized system, state is unknown. + * ``BOOT``: System is booting up. + * ``CALIBRATING``: System is calibrating and not flight-ready. + * ``STANDBY``: System is grounded and on standby. It can be launched any time. + * ``ACTIVE``: System is active and might be already airborne. Motors are engaged. + * ``CRITICAL``: System is in a non-normal flight mode. It can however still navigate. + * ``EMERGENCY``: System is in a non-normal flight mode. It lost control over parts + or over the whole airframe. It is in mayday and going down. + * ``POWEROFF``: System just initialized its power-down sequence, will shut down now. + """ + return { + 0: SystemStatus('UNINIT'), + 1: SystemStatus('BOOT'), + 2: SystemStatus('CALIBRATING'), + 3: SystemStatus('STANDBY'), + 4: SystemStatus('ACTIVE'), + 5: SystemStatus('CRITICAL'), + 6: SystemStatus('EMERGENCY'), + 7: SystemStatus('POWEROFF'), + }.get(self._system_status, None) + + @property + def heading(self): + """ + Current heading in degrees (0..360, where North = 0). + """ + return self._heading + + @property + def groundspeed(self): + return self._groundspeed + + @property + def airspeed(self): + return self._airspeed + + @property + def mount_status(self): + return [ self._mount_pitch, self._mount_yaw, self._mount_roll ] + + @property + def ekf_ok(self): + """ + ``True`` if the EKF status is considered acceptable, ``False`` otherwise. + """ + # legacy check for dronekit-python for solo + # use same check that ArduCopter::system.pde::position_ok() is using + if self.armed: + return self._ekf_poshorizabs and not self._ekf_constposmode + else: + return self._ekf_poshorizabs or self._ekf_predposhorizabs + + @property + def channels(self): + """ + The RC channel values from the RC Transmitter, in a :py:class:`Channels` object. + The attribute can also be used to set and read RC Override (channel override) values + via :py:attr:`Vehicle.channels.override `. + + For more information and examples see :ref:`example_channel_overrides`. + + To read the channels from the RC transmitter: + + .. code:: python + + # Get all channel values from RC transmitter + print "Channel values from RC Tx:", vehicle.channels + + # Access channels individually + print "Read channels individually:" + print " Ch1: %s" % vehicle.channels['1'] + print " Ch2: %s" % vehicle.channels['2'] + + """ + return self._channels + + @property + def home_location(self): + """ + The current home location in a :py:class:`LocationGlobal`. + + To get the attribute you must first download the :py:func:`Vehicle.commands`. + The attribute has a value of ``None`` until :py:func:`Vehicle.commands` has been downloaded + **and** the autopilot has set an initial home location (typically where the vehicle first gets GPS lock). + + .. code-block:: python + + #Connect to a vehicle object (for example, on com14) + vehicle = connect('com14', wait_ready=True) + + # Download the vehicle waypoints (commands). Wait until download is complete. + cmds = vehicle.commands + cmds.download() + cmds.wait_ready() + + # Get the home location + home = vehicle.home_location + + The ``home_location`` is not observable. + + The attribute can be written (in the same way as any other attribute) after it has successfully + been populated from the vehicle. The value sent to the vehicle is cached in the attribute + (and can potentially get out of date if you don't re-download ``Vehicle.commands``): + + .. warning:: + + Setting the value will fail silently if the specified location is more than 50km from the EKF origin. + + + """ + return copy.copy(self._home_location) + + @home_location.setter + def home_location(self, pos): + """ + Sets the home location to that of a ``LocationGlobal`` object. + + The value cannot be set until it has successfully been read from the vehicle. After being + set the value is cached in the home_location attribute and does not have to be re-read. + + .. note:: + + Setting the value will fail silently if the specified location is more than 50km from the EKF origin. + """ + + if not isinstance(pos, LocationGlobal): + raise Exception('Excepting home_location to be set to a LocationGlobal.') + + # Set cached home location. + self._home_location = copy.copy(pos) + + # Send MAVLink update. + self.send_mavlink(self.message_factory.command_long_encode( + 0, 0, # target system, target component + mavutil.mavlink.MAV_CMD_DO_SET_HOME, # command + 0, # confirmation + 2, # param 1: 1 to use current position, 2 to use the entered values. + 0, 0, 0, # params 2-4 + pos.lat, + pos.lon, + pos.alt + )) + + @property + def commands(self): + """ + Gets the editable waypoints for this vehicle (the current "mission"). + + This can be used to get, create, and modify a mission. It can also be used for direct control of vehicle position + (outside missions) using the :py:func:`goto ` method. + + :returns: A :py:class:`CommandSequence` containing the waypoints for this vehicle. + """ + return self._commands + + @property + def parameters(self): + """ + The (editable) parameters for this vehicle (:py:class:`Parameters `). + """ + return self._parameters + + def send_mavlink(self, message): + """ + This method is used to send raw MAVLink "custom messages" to the vehicle. + + The function can send arbitrary messages/commands to the connected vehicle at any time and in any vehicle mode. + It is particularly useful for controlling vehicles outside of missions (for example, in GUIDED mode). + + The :py:func:`message_factory ` is used to create messages in the appropriate format. + + For more information see the guide topic: :ref:`guided_mode_how_to_send_commands`. + + :param message: A ``MAVLink_message`` instance, created using :py:func:`message_factory `. + There is need to specify the system id, component id or sequence number of messages as the API will set these appropriately. + """ + self._master.mav.send(message) + + @property + def message_factory(self): + """ + Returns an object that can be used to create 'raw' MAVLink messages that are appropriate for this vehicle. + The message can then be sent using :py:func:`send_mavlink(message) `. + + .. note:: + + Vehicles support a subset of the messages defined in the MAVLink standard. For more information + about the supported sets see wiki topics: + `Copter Commands in Guided Mode `_ + and `Plane Commands in Guided Mode `_. + + All message types are defined in the central MAVLink github repository. For example, a Pixhawk understands + the following messages (from `pixhawk.xml `_): + + .. code:: xml + + + 0 to disable, 1 to enable + + + The name of the factory method will always be the lower case version of the message name with *_encode* appended. + Each field in the XML message definition must be listed as arguments to this factory method. So for this example + message, the call would be: + + .. code:: python + + msg = vehicle.message_factory.image_trigger_control_encode(True) + vehicle.send_mavlink(msg) + + Some message types include "addressing information". If present, there is no need to specify the ``target_system`` + id (just set to zero) as DroneKit will automatically update messages with the correct ID for the connected + vehicle before sending. + The ``target_component`` should be set to 0 (broadcast) unless the message is to specific component. + CRC fields and sequence numbers (if defined in the message type) are automatically set by DroneKit and can also + be ignored/set to zero. + + For more information see the guide topic: :ref:`guided_mode_how_to_send_commands`. + """ + return self._master.mav + + def initialize(self, rate=4, heartbeat_timeout=30): + self._handler.start() + + # Start heartbeat polling. + start = time.time() + self._heartbeat_error = heartbeat_timeout or 0 + self._heartbeat_started = True + self._heartbeat_lastreceived = start + + # Poll for first heartbeat. + # If heartbeat times out, this will interrupt. + while self._handler._alive: + time.sleep(.1) + if self._heartbeat_lastreceived != start: + break + if not self._handler._alive: + raise APIException('Timeout in initializing connection.') + + # Register target_system now. + self._handler.target_system = self._heartbeat_system + + # Wait until board has booted. + while True: + if self._flightmode not in [None, 'INITIALISING', 'MAV']: + break + time.sleep(0.1) + + # Initialize data stream. + if rate != None: + self._master.mav.request_data_stream_send(0, 0, + mavutil.mavlink.MAV_DATA_STREAM_ALL, rate, 1) + + # Ensure initial parameter download has started. + while True: + # This fn actually rate limits itself to every 2s. + # Just retry with persistence to get our first param stream. + self._master.param_fetch_all() + time.sleep(0.1) + if self._params_count > -1: + break + + def wait_ready(self, *types, **kwargs): + """ + Waits for specified attributes to be populated from the vehicle (values are initially ``None``). + + This is typically called "behind the scenes" to ensure that :py:func:`connect` does not return until + attributes have populated (via the ``wait_ready`` parameter). You can also use it after connecting to + wait on a specific value(s). + + There are two ways to call the method: + + .. code-block:: python + + #Wait on default attributes to populate + vehicle.wait_ready(True) + + #Wait on specified attributes (or array of attributes) to populate + vehicle.wait_ready('mode','airspeed') + + Using the ``wait_ready(True)`` waits on :py:attr:`parameters`, :py:attr:`gps_0`, + :py:attr:`armed`, :py:attr:`mode`, and :py:attr:`attitude`. In practice this usually + means that all supported attributes will be populated. + + By default, the method will timeout after 30 seconds and raise an exception if the + attributes were not populated. + + :param types: ``True`` to wait on the default set of attributes, or a + comma-separated list of the specific attributes to wait on. + :param int timeout: Timeout in seconds after which the method will raise an exception + (the default) or return ``False``. The default timeout is 30 seconds. + :param Boolean raise_exception: If ``True`` the method will raise an exception on timeout, + otherwise the method will return ``False``. The default is ``True`` (raise exception). + """ + timeout = kwargs.get('timeout', 30) + raise_exception = kwargs.get('raise_exception', True) + + # Vehicle defaults for wait_ready(True) or wait_ready() + if list(types) == [True] or list(types) == []: + types = self._default_ready_attrs + + if not all(isinstance(item, basestring) for item in types): + raise APIException('wait_ready expects one or more string arguments.') + + # Wait for these attributes to have been set. + await = set(types) + start = time.time() + while not await.issubset(self._ready_attrs): + time.sleep(0.1) + if time.time() - start > timeout: + if raise_exception: + raise APIException('wait_ready experienced a timeout after %s seconds.' % timeout) + else: + return False + + return True + +class Parameters(collections.MutableMapping, HasObservers): + """ + This object is used to get and set the values of named parameters for a vehicle. See the following links for information about + the supported parameters for each platform: `Copter `_, + `Plane `_, `Rover `_. + + The code fragment below shows how to get and set the value of a parameter. + + .. code:: python + + # Print the value of the THR_MIN parameter. + print "Param: %s" % vehicle.parameters['THR_MIN'] + + # Change the parameter value to something different. + vehicle.parameters['THR_MIN']=100 + + It is also possible to observe parameters and to iterate the :py:func:`Vehicle.parameters`. + + For more information see: :ref:`vehicle_state_parameters`. + """ + + def __init__(self, vehicle): + super(Parameters, self).__init__() + self._vehicle = vehicle + + def __getitem__(self, name): + name = name.upper() + self.wait_ready() + return self._vehicle._params_map[name] + + def __setitem__(self, name, value): + name = name.upper() + self.wait_ready() + self.set(name, value) + + def __delitem__(self, name): + raise APIException('Cannot delete value from parameters list.') + + def __len__(self): + return len(self._vehicle._params_map) + + def __iter__(self): + return self._vehicle._params_map.__iter__() + + def get(self, name, wait_ready=True): + name = name.upper() + if wait_ready: + self.wait_ready() + return self._vehicle._params_map.get(name, None) + + def set(self, name, value, retries=3, wait_ready=False): + if wait_ready: + self.wait_ready() + + # TODO dumbly reimplement this using timeout loops + # because we should actually be awaiting an ACK of PARAM_VALUE + # changed, but we don't have a proper ack structure, we'll + # instead just wait until the value itself was changed + + name = name.upper() + value = float(value) + success = False + remaining = retries + while True: + self._vehicle._master.param_set_send(name, value) + tstart = time.time() + if remaining == 0: + break + remaining -= 1 + while time.time() - tstart < 1: + if name in self._vehicle._params_map and self._vehicle._params_map[name] == value: + return True + time.sleep(0.1) + + if retries > 0: + errprinter("timeout setting parameter %s to %f" % (name, value)) + return False + + def wait_ready(self, **kwargs): + """ + Block the calling thread until parameters have been downloaded + """ + self._vehicle.wait_ready('parameters', **kwargs) + + def add_attribute_listener(self, attr_name, *args, **kwargs): + """ + Add a listener callback on a particular parameter. + + The callback can be removed using :py:func:`remove_attribute_listener`. + + .. note:: + + The :py:func:`on_attribute` decorator performs the same operation as this method, but with + a more elegant syntax. Use ``add_attribute_listener`` only if you will need to remove + the observer. + + The callback function is invoked only when the parameter changes. + + The callback arguments are: + + * ``self`` - the associated :py:class:`Parameters`. + * ``attr_name`` - the parameter name. This can be used to infer which parameter has triggered + if the same callback is used for watching multiple parameters. + * ``msg`` - the new parameter value (so you don't need to re-query the vehicle object). + + The example below shows how to get callbacks for the ``THR_MIN`` parameter: + + .. code:: python + + #Callback function for the THR_MIN parameter + def thr_min_callback(self, attr_name, value): + print " PARAMETER CALLBACK: %s changed to: %s" % (attr_name, value) + + #Add observer for the vehicle's THR_MIN parameter + vehicle.parameters.add_attribute_listener('THR_MIN', thr_min_callback) + + See :ref:`vehicle_state_observing_parameters` for more information. + + :param String attr_name: The name of the parameter to watch (or '*' to watch all parameters). + :param args: The callback to invoke when a change in the parameter is detected. + + """ + attr_name = attr_name.upper() + return super(Parameters, self).add_attribute_listener(attr_name, *args, **kwargs) + + def remove_attribute_listener(self, attr_name, *args, **kwargs): + """ + Remove a paremeter listener that was previously added using :py:func:`add_attribute_listener`. + + For example to remove the ``thr_min_callback()`` callback function: + + .. code:: python + + vehicle.parameters.remove_attribute_listener('thr_min', thr_min_callback) + + See :ref:`vehicle_state_observing_parameters` for more information. + + :param String attr_name: The parameter name that is to have an observer removed (or '*' to remove an 'all attribute' observer). + :param args: The callback function to remove. + + """ + attr_name = attr_name.upper() + return super(Parameters, self).remove_attribute_listener(attr_name, *args, **kwargs) + + def notify_attribute_listeners(self, attr_name, *args, **kwargs): + attr_name = attr_name.upper() + return super(Parameters, self).notify_attribute_listeners(attr_name, *args, **kwargs) + + def on_attribute(self, attr_name, *args, **kwargs): + """ + Decorator for parameter listeners. + + .. note:: + + There is no way to remove a listener added with this decorator. Use + :py:func:`add_attribute_listener` if you need to be able to remove + the :py:func:`listener `. + + The callback function is invoked only when the parameter changes. + + The callback arguments are: + + * ``self`` - the associated :py:class:`Parameters`. + * ``attr_name`` - the parameter name. This can be used to infer which parameter has triggered + if the same callback is used for watching multiple parameters. + * ``msg`` - the new parameter value (so you don't need to re-query the vehicle object). + + The code fragment below shows how to get callbacks for the ``THR_MIN`` parameter: + + .. code:: python + + @vehicle.parameters.on_attribute('THR_MIN') + def decorated_thr_min_callback(self, attr_name, value): + print " PARAMETER CALLBACK: %s changed to: %s" % (attr_name, value) + + See :ref:`vehicle_state_observing_parameters` for more information. + + :param String attr_name: The name of the parameter to watch (or '*' to watch all parameters). + :param args: The callback to invoke when a change in the parameter is detected. + + """ + attr_name = attr_name.upper() + return super(Parameters, self).on_attribute(attr_name, *args, **kwargs) + + +class Command(mavutil.mavlink.MAVLink_mission_item_message): + """ + A waypoint object. + + This object encodes a single mission item command. The set of commands that are supported by ArduPilot in Copter, Plane and Rover (along with their parameters) + are listed in the wiki article `MAVLink Mission Command Messages (MAV_CMD) `_. + + For example, to create a `NAV_WAYPOINT `_ command: + + .. code:: python + + cmd = Command(0,0,0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, + mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0,-34.364114, 149.166022, 30) + + :param target_system: This can be set to any value + (DroneKit changes the value to the MAVLink ID of the connected vehicle before the command is sent). + :param target_component: The component id if the message is intended for a particular component within the target system + (for example, the camera). Set to zero (broadcast) in most cases. + :param seq: The sequence number within the mission (the autopilot will reject messages sent out of sequence). + This should be set to zero as the API will automatically set the correct value when uploading a mission. + :param frame: The frame of reference used for the location parameters (x, y, z). In most cases this will be + ``mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT``, which uses the WGS84 global coordinate system for latitude and longitude, but sets altitude + as relative to the home position in metres (home altitude = 0). For more information `see the wiki here + `_. + :param command: The specific mission command (e.g. ``mavutil.mavlink.MAV_CMD_NAV_WAYPOINT``). The supported commands (and command parameters + are listed `on the wiki `_. + :param current: Set to zero (not supported). + :param autocontinue: Set to zero (not supported). + :param param1: Command specific parameter (depends on specific `Mission Command (MAV_CMD) `_). + :param param2: Command specific parameter. + :param param3: Command specific parameter. + :param param4: Command specific parameter. + :param x: (param5) Command specific parameter used for latitude (if relevant to command). + :param y: (param6) Command specific parameter used for longitude (if relevant to command). + :param z: (param7) Command specific parameter used for altitude (if relevant). The reference frame for altitude depends on the ``frame``. + + .. todo:: Confirm if target_sytem, target_component, seq, frame are all handled for you or not. If not, check that these are correct. + .. todo:: FIXME: Command class - for now we just inherit the standard MAVLink mission item contents. + """ + pass + +class CommandSequence(object): + """ + A sequence of vehicle waypoints (a "mission"). + + Operations include 'array style' indexed access to the various contained waypoints. + + The current commands/mission for a vehicle are accessed using the :py:attr:`Vehicle.commands ` attribute. + Waypoints are not downloaded from vehicle until :py:func:`download()` is called. The download is asynchronous; + use :py:func:`wait_ready()` to block your thread until the download is complete. + The code to download the commands from a vehicle is shown below: + + .. code-block:: python + :emphasize-lines: 5-10 + + #Connect to a vehicle object (for example, on com14) + vehicle = connect('com14', wait_ready=True) + + # Download the vehicle waypoints (commands). Wait until download is complete. + cmds = vehicle.commands + cmds.download() + cmds.wait_ready() + + The set of commands can be changed and uploaded to the client. The changes are not guaranteed to be complete until + :py:func:`upload() ` is called. + + .. code:: python + + cmds = vehicle.commands + cmds.clear() + lat = -34.364114, + lon = 149.166022 + altitude = 30.0 + cmd = Command(0,0,0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, + 0, 0, 0, 0, 0, 0, + lat, lon, altitude) + cmds.add(cmd) + cmds.upload() + + .. py:function:: takeoff(altitude) + + .. note:: This function should only be used on Copter vehicles. + + Take off and fly the vehicle to the specified altitude (in metres) and then wait for another command. + + The vehicle must be in ``GUIDED`` mode and armed before this is called. + + There is no mechanism for notification when the correct altitude is reached, and if another command arrives + before that point (e.g. :py:func:`goto`) it will be run instead. + + .. warning:: + + Apps should code to ensure that the vehicle will reach a safe altitude before other commands are executed. + A good example is provided in the guide topic :ref:`taking-off`. + + :param altitude: Target height, in metres. + + .. todo:: This is a hack. The actual function should be defined here. See https://github.com/dronekit/dronekit-python/issues/64 + """ + + def __init__(self, vehicle): + self._vehicle = vehicle + + def download(self): + ''' + Download all waypoints from the vehicle. + The download is asynchronous. Use :py:func:`wait_ready()` to block your thread until the download is complete. + ''' + self.wait_ready() + self._vehicle._ready_attrs.remove('commands') + self._vehicle._wp_loaded = False + self._vehicle._master.waypoint_request_list_send() + # BIG FIXME - wait for full wpt download before allowing any of the accessors to work + + def wait_ready(self, **kwargs): + """ + Block the calling thread until waypoints have been downloaded. + + This can be called after :py:func:`download()` to block the thread until the asynchronous download is complete. + """ + return self._vehicle.wait_ready('commands', **kwargs) + + def takeoff(self, alt=None): + if alt is not None: + altitude = float(alt) + if math.isnan(alt) or math.isinf(alt): + raise ValueError("Altitude was NaN or Infinity. Please provide a real number") + self._vehicle._master.mav.command_long_send(0, 0, + mavutil.mavlink.MAV_CMD_NAV_TAKEOFF, + 0, 0, 0, 0, 0, 0, 0, + altitude) + + def goto(self, location): + ''' + Go to a specified global location (:py:class:`LocationGlobal` or :py:class:`LocationGlobalRelative`). + + The method will change the :py:class:`VehicleMode` to ``GUIDED`` if necessary. + + .. code:: python + + # Set mode to guided - this is optional as the goto method will change the mode if needed. + vehicle.mode = VehicleMode("GUIDED") + + # Set the LocationGlobal to head towards + a_location = LocationGlobal(-34.364114, 149.166022, 30) + vehicle.commands.goto(a_location) + + :param LocationGlobal location: The target location. + ''' + if isinstance(location, LocationGlobalRelative): + frame = mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT + elif isinstance(location, LocationGlobal): + frame = mavutil.mavlink.MAV_FRAME_GLOBAL + else: + raise APIException('Expecting location to be LocationGlobal or LocationGlobalRelative.') + + self._vehicle._master.mav.mission_item_send(0, 0, 0, + frame, + mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, + 2, 0, 0, 0, 0, 0, + location.lat, location.lon, location.alt) + + def clear(self): + ''' + Clear the command list. + + This command will be sent to the vehicleonly after you call :py:func:`upload() `. + ''' + + # Add home point again. + self.wait_ready() + home = self._vehicle._wploader.wp(0) + self._vehicle._wploader.clear() + if home: + self._vehicle._wploader.add(home, comment='Added by DroneKit') + self._vehicle._wpts_dirty = True + + def add(self, cmd): + ''' + Add a new command (waypoint) at the end of the command list. + + .. note:: + + Commands are sent to the vehicle only after you call ::py:func:`upload() `. + + :param Command cmd: The command to be added. + ''' + self.wait_ready() + self._vehicle._handler.fix_targets(cmd) + self._vehicle._wploader.add(cmd, comment='Added by DroneKit') + self._vehicle._wpts_dirty = True + + def upload(self): + """ + Call ``upload()`` after :py:func:`adding ` or :py:func:`clearing ` mission commands. + + After the return from ``upload()`` any writes are guaranteed to have completed (or thrown an + exception) and future reads will see their effects. + """ + if self._vehicle._wpts_dirty: + self._vehicle._master.waypoint_clear_all_send() + if self._vehicle._wploader.count() > 0: + self._vehicle._wp_uploaded = [False]*self._vehicle._wploader.count() + self._vehicle._master.waypoint_count_send(self._vehicle._wploader.count()) + while False in self._vehicle._wp_uploaded: + time.sleep(0.1) + self._vehicle._wp_uploaded = None + self._vehicle._wpts_dirty = False + + @property + def count(self): + ''' + Return number of waypoints. + + :return: The number of waypoints in the sequence. + ''' + return max(self._vehicle._wploader.count() - 1, 0) + + @property + def next(self): + """ + Get the currently active waypoint number. + """ + return self._vehicle._current_waypoint + + @next.setter + def next(self, index): + """ + Set a new ``next`` waypoint for the vehicle. + """ + self._vehicle._master.waypoint_set_current_send(index) + + def __len__(self): + ''' + Return number of waypoints. + + :return: The number of waypoints in the sequence. + ''' + return max(self._vehicle._wploader.count() - 1, 0) + + def __getitem__(self, index): + if isinstance(index, slice): + return [self[ii] for ii in xrange(*index.indices(len(self)))] + elif isinstance(index, int): + item = self._vehicle._wploader.wp(index + 1) + if not item: + raise IndexError('Index %s out of range.' % index) + return item + else: + raise TypeError('Invalid argument type.') + + def __setitem__(self, index, value): + self._vehicle._wploader.set(value, index + 1) + self._vehicle._wpts_dirty = True + + +from dronekit.mavlink import MAVConnection def connect(ip, _initialize=True, wait_ready=None, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200, heartbeat_timeout=30, source_system=255): handler = MAVConnection(ip, baud=baud, source_system=source_system) diff --git a/dronekit/lib/CloudClient.py b/dronekit/cloud/CloudClient.py similarity index 100% rename from dronekit/lib/CloudClient.py rename to dronekit/cloud/CloudClient.py diff --git a/dronekit/cloud/__init__.py b/dronekit/cloud/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/dronekit/lib.py b/dronekit/lib.py new file mode 100644 index 000000000..d2419fcdb --- /dev/null +++ b/dronekit/lib.py @@ -0,0 +1,2 @@ +# Backwards compatibility +from dronekit import * diff --git a/dronekit/lib/__init__.py b/dronekit/lib/__init__.py deleted file mode 100644 index cd3da80b4..000000000 --- a/dronekit/lib/__init__.py +++ /dev/null @@ -1,2202 +0,0 @@ -# DroneAPI module -""" -This is the API Reference for the DroneKit-Python API. - -The main API is the :py:class:`Vehicle ` class. -The code snippet below shows how to use :py:func:`connect` to obtain an instance a connected vehicle: - -.. code:: python - - from dronekit import connect - - # Connect to the Vehicle using "connection string" (in this case an address on network) - vehicle = connect('127.0.0.1:14550', wait_ready=True) - -:py:class:`Vehicle ` provides access to vehicle *state* through python attributes -(e.g. :py:attr:`Vehicle.mode `) -and to settings/parameters though the :py:attr:`Vehicle.parameters ` attribute. -Asynchronous notification on vehicle attribute changes is available by registering observers. - -:py:class:`Vehicle ` provides two main ways to control vehicle movement and other operations: - -* Direct control of movement outside of missions is also supported. To set a target position you can use - :py:func:`CommandSequence.goto `. - Control over speed, direction, altitude, camera trigger and any other aspect of the vehicle is supported using custom MAVLink messages - (:py:func:`Vehicle.send_mavlink `, :py:func:`Vehicle.message_factory `). -* Missions are downloaded and uploaded through the :py:attr:`Vehicle.commands ` attribute - (see :py:class:`CommandSequence ` for more information). - -A number of other useful classes and methods are listed below. - ----- - -.. py:function:: connect(ip, wait_ready=None, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200, heartbeat_timeout=30, source_system=255) - - Returns a :py:class:`Vehicle` object connected to the address specified by string parameter ``ip``. - Connection string parameters (``ip``) for different targets are listed in the :ref:`getting started guide `. - - The method is usually called with ``wait_ready=True`` to ensure that vehicle parameters and (most) attributes are - available when ``connect()`` returns. - - .. code:: python - - from dronekit import connect - - # Connect to the Vehicle using "connection string" (in this case an address on network) - vehicle = connect('127.0.0.1:14550', wait_ready=True) - - :param String ip: :ref:`Connection string ` for target address - e.g. 127.0.0.1:14550. - - :param Bool/Array wait_ready: If ``True`` wait until all default attributes have downloaded before - the method returns (default is ``None``). - The default attributes to wait on are: :py:attr:`parameters`, :py:attr:`gps_0`, - :py:attr:`armed`, :py:attr:`mode`, and :py:attr:`attitude`. - - You can also specify a named set of parameters to wait on (e.g. ``wait_ready=['system_status','mode']``). - - For more information see :py:func:`Vehicle.wait_ready `. - - :param status_printer: Method of signature ``def status_printer(txt)`` that prints - STATUS_TEXT messages from the Vehicle and other diagnostic information. - By default the status information is printed to the command prompt in which the script is running. - :param Vehicle vehicle_class: The class that will be instantiated by the ``connect()`` method. - This can be any sub-class of ``Vehicle`` (and defaults to ``Vehicle``). - :param int rate: Data stream refresh rate. The default is 4Hz (4 updates per second). - :param int baud: The baud rate for the connection. The default is 115200. - :param int heartbeat_timeout: Connection timeout value in seconds (default is 30s). - If a heartbeat is not detected within this time an exception will be raised. - :param int source_system: The MAVLink ID of the :py:class:`Vehicle` object returned by this method (by default 255). - - .. note:: - - The returned :py:class:`Vehicle` object is acting as like a ground control station from the - perspective of the connected "real" vehicle. It will process/receive messages from the real vehicle - if they are addressed to this ``source_system`` id. Messages sent to the real vehicle are - automatically updated to use the vehicle's ``target_system`` id. - - It is *good practice* to assign a unique id for every system on the MAVLink network. - It is possible to configure the autopilot to only respond to guided-mode commands from a specified GCS ID. - - - :returns: A connected vehicle of the type defined in ``vehicle_class`` (a superclass of :py:class:`Vehicle`). -""" - -import threading, time, math, copy -import CloudClient -import collections -from pymavlink.dialects.v10 import ardupilotmega -from pymavlink import mavutil, mavwp -from dronekit.util import errprinter - -local_path = '' - -class APIException(Exception): - """ - Base class for DroneKit related exceptions. - - :param String message: Message string describing the exception - """ - - def __init__(self, message): - super(APIException, self).__init__(message) - -class Attitude(object): - """ - Attitude information. - - .. figure:: http://upload.wikimedia.org/wikipedia/commons/thumb/c/c1/Yaw_Axis_Corrected.svg/500px-Yaw_Axis_Corrected.svg.png - :width: 400px - :alt: Diagram showing Pitch, Roll, Yaw - :target: http://commons.wikimedia.org/wiki/File:Yaw_Axis_Corrected.svg - - Diagram showing Pitch, Roll, Yaw (`Creative Commons `_) - - :param pitch: Pitch in radians - :param yaw: Yaw in radians - :param roll: Roll in radians - """ - def __init__(self, pitch, yaw, roll): - self.pitch = pitch - self.yaw = yaw - self.roll = roll - - def __str__(self): - return "Attitude:pitch=%s,yaw=%s,roll=%s" % (self.pitch, self.yaw, self.roll) - -class LocationGlobal(object): - """ - A global location object. - - The latitude and longitude are relative to the `WGS84 coordinate system `_. - The altitude is relative to mean sea-level (MSL). - - For example, a global location object with altitude 30 metres above sea level might be defined as: - - .. code:: python - - LocationGlobal(-34.364114, 149.166022, 30) - - .. todo:: FIXME: Location class - possibly add a vector3 representation. - - An object of this type is owned by :py:attr:`Vehicle.location`. See that class for information on - reading and observing location in the global frame. - - :param lat: Latitude. - :param lon: Longitude. - :param alt: Altitude in meters relative to mean sea-level (MSL). - """ - def __init__(self, lat, lon, alt=None): - self.lat = lat - self.lon = lon - self.alt = alt - - # This is for backward compatibility. - self.local_frame = None - self.global_frame = None - - def __str__(self): - return "LocationGlobal:lat=%s,lon=%s,alt=%s" % (self.lat, self.lon, self.alt) - - -class LocationGlobalRelative(object): - """ - A global location object, with attitude relative to home location altitude. - - The latitude and longitude are relative to the `WGS84 coordinate system `_. - The altitude is relative to the *home position*. - - For example, a ``LocationGlobalRelative`` object with an altitude of 30 metres above the home location might be defined as: - - .. code:: python - - LocationGlobalRelative(-34.364114, 149.166022, 30) - - .. todo:: FIXME: Location class - possibly add a vector3 representation. - - An object of this type is owned by :py:attr:`Vehicle.location`. See that class for information on - reading and observing location in the global-relative frame. - - :param lat: Latitude. - :param lon: Longitude. - :param alt: Altitude in meters (relative to the home location). - """ - def __init__(self, lat, lon, alt=None): - self.lat = lat - self.lon = lon - self.alt = alt - - # This is for backward compatibility. - self.local_frame = None - self.global_frame = None - - def __str__(self): - return "LocationGlobalRelative:lat=%s,lon=%s,alt=%s" % (self.lat, self.lon, self.alt) - - -class LocationLocal(object): - """ - A local location object. - - The north, east and down are relative to the EKF origin. This is most likely the location where the vehicle was turned on. - - An object of this type is owned by :py:attr:`Vehicle.location`. See that class for information on - reading and observing location in the local frame. - - :param north: Position north of the EKF origin in meters. - :param east: Position east of the EKF origin in meters. - :param down: Position down from the EKF origin in meters. (i.e. negative altitude in meters) - """ - def __init__(self, north, east, down): - self.north = north - self.east = east - self.down = down - - def __str__(self): - return "LocationLocal:north=%s,east=%s,down=%s" % (self.north, self.east, self.down) - -class GPSInfo(object): - """ - Standard information about GPS. - - If there is no GPS lock the parameters are set to ``None``. - - :param Int eph: GPS horizontal dilution of position (HDOP). - :param Int epv: GPS horizontal dilution of position (VDOP). - :param Int fix_type: 0-1: no fix, 2: 2D fix, 3: 3D fix - :param Int satellites_visible: Number of satellites visible. - - .. todo:: FIXME: GPSInfo class - possibly normalize eph/epv? report fix type as string? - """ - def __init__(self, eph, epv, fix_type, satellites_visible): - self.eph = eph - self.epv = epv - self.fix_type = fix_type - self.satellites_visible = satellites_visible - - def __str__(self): - return "GPSInfo:fix=%s,num_sat=%s" % (self.fix_type, self.satellites_visible) - -class Battery(object): - """ - System battery information. - - :param voltage: Battery voltage in millivolts. - :param current: Battery current, in 10 * milliamperes. ``None`` if the autopilot does not support current measurement. - :param level: Remaining battery energy. ``None`` if the autopilot cannot estimate the remaining battery. - """ - def __init__(self, voltage, current, level): - self.voltage = voltage / 1000.0 - if current == -1: - self.current = None - else: - self.current = current / 100.0 - if level == -1: - self.level = None - else: - self.level = level - - def __str__(self): - return "Battery:voltage={},current={},level={}".format(self.voltage, self.current, self.level) - -class Rangefinder(object): - """ - Rangefinder readings. - - :param distance: Distance (metres). ``None`` if the vehicle doesn't have a rangefinder. - :param voltage: Voltage (volts). ``None`` if the vehicle doesn't have a rangefinder. - """ - def __init__(self, distance, voltage): - self.distance = distance - self.voltage = voltage - - def __str__(self): - return "Rangefinder: distance={}, voltage={}".format(self.distance, self.voltage) - -class VehicleMode(object): - """ - This object is used to get and set the current "flight mode". - - The flight mode determines the behaviour of the vehicle and what commands it can obey. - The recommended flight modes for *DroneKit-Python* apps depend on the vehicle type: - - * Copter apps should use ``AUTO`` mode for "normal" waypoint missions and ``GUIDED`` mode otherwise. - * Plane and Rover apps should use the ``AUTO`` mode in all cases, re-writing the mission commands if "dynamic" - behaviour is required (they support only a limited subset of commands in ``GUIDED`` mode). - * Some modes like ``RETURN_TO_LAUNCH`` can be used on all platforms. Care should be taken - when using manual modes as these may require remote control input from the user. - - The available set of supported flight modes is vehicle-specific (see - `Copter `_, - `Plane `_, - `Rover `_). If an unsupported mode is set the script - will raise a ``KeyError`` exception. - - The :py:attr:`Vehicle.mode ` attribute can be queried for the current mode. - The code snippet below shows how to observe changes to the mode and then read the value: - - .. code:: python - - #Callback definition for mode observer - def mode_callback(self, attr_name): - print "Vehicle Mode", self.mode - - #Add observer callback for attribute `mode` - vehicle.add_attribute_listener('mode', mode_callback) - - The code snippet below shows how to change the vehicle mode to AUTO: - - .. code:: python - - # Set the vehicle into auto mode - vehicle.mode = VehicleMode("AUTO") - - For more information on getting/setting/observing the :py:attr:`Vehicle.mode ` - (and other attributes) see the :ref:`attributes guide `. - - .. py:attribute:: name - - The mode name, as a ``string``. - """ - def __init__(self, name): - self.name = name - - def __str__(self): - return "VehicleMode:%s" % self.name - - def __eq__(self, other): - return self.name == other - - def __ne__(self, other): - return self.name != other - -class SystemStatus(object): - """ - This object is used to get and set the current "system status". - - .. py:attribute:: state - - The system state, as a ``string``. - """ - def __init__(self, state): - self.state = state - - def __str__(self): - return "SystemStatus:%s" % self.state - - def __eq__(self, other): - return self.state == other - - def __ne__(self, other): - return self.state != other - -class HasObservers(object): - def __init__(self): - # A mapping from attr_name to a list of observers - self._attribute_listeners = {} - self._attribute_cache = {} - - """ - Provides callback based notification on attribute changes. - - The argument list for observer is ``observer(object, attr_name, attribute_value)``. - """ - def add_attribute_listener(self, attr_name, observer): - """ - Add an attribute listener callback. - - The callback function (``observer``) is invoked differently depending on the *type of attribute*. - Attributes that represent sensor values or which are used to monitor connection status are updated - whenever a message is received from the vehicle. Attributes which reflect vehicle "state" are - only updated when their values change (for example :py:func:`Vehicle.system_status `, - :py:attr:`Vehicle.armed `, and :py:attr:`Vehicle.mode `). - - The callback can be removed using :py:func:`remove_attribute_listener`. - - .. note:: - - The :py:func:`on_attribute` decorator performs the same operation as this method, but with - a more elegant syntax. Use ``add_attribute_listener`` by preference if you will need to remove - the observer. - - The callback arguments are: - - * ``self`` - the associated :py:class:`Vehicle`. This may be compared to a global vehicle handle - to implement vehicle-specific callback handling (if needed). - * ``attr_name`` - the attribute name. This can be used to infer which attribute has triggered - if the same callback is used for watching several attributes. - * ``value`` - the attribute value (so you don't need to re-query the vehicle object). - - The example below shows how to get callbacks for (global) location changes: - - .. code:: python - - #Callback to print the location in global frame - def location_callback(self, attr_name, msg): - print "Location (Global): ", msg - - #Add observer for the vehicle's current location - vehicle.add_attribute_listener('global_frame', location_callback) - - See :ref:`vehicle_state_observe_attributes` for more information. - - :param String attr_name: The name of the attribute to watch (or '*' to watch all attributes). - :param observer: The callback to invoke when a change in the attribute is detected. - - """ - l = self._attribute_listeners.get(attr_name) - if l is None: - l = [] - self._attribute_listeners[attr_name] = l - if not observer in l: - l.append(observer) - - def remove_attribute_listener(self, attr_name, observer): - """ - Remove an attribute listener (observer) that was previously added using :py:func:`add_attribute_listener`. - - For example, the following line would remove a previously added vehicle 'global_frame' - observer called ``location_callback``: - - .. code:: python - - vehicle.remove_attribute_listener('global_frame', location_callback) - - See :ref:`vehicle_state_observe_attributes` for more information. - - :param String attr_name: The attribute name that is to have an observer removed (or '*' to remove an 'all attribute' observer). - :param observer: The callback function to remove. - - """ - l = self._attribute_listeners.get(attr_name) - if l is not None: - l.remove(observer) - if len(l) == 0: - del self._attribute_listeners[attr_name] - - - def notify_attribute_listeners(self, attr_name, value, cache=False): - """ - This method is used to update attribute observers when the named attribute is updated. - - You should call it in your message listeners after updating an attribute with - information from a vehicle message. - - By default the value of ``cache`` is ``False`` and every update from the vehicle is sent to listeners - (whether or not the attribute has changed). This is appropriate for attributes which represent sensor - or heartbeat-type monitoring. - - Set ``cache=True`` to update listeners only when the value actually changes (cache the previous - attribute value). This should be used where clients will only ever need to know the value when it has - changed. For example, this setting has been used for notifying :py:attr:`mode` changes. - - See :ref:`example_create_attribute` for more information. - - :param String attr_name: The name of the attribute that has been updated. - :param value: The current value of the attribute that has been updated. - :param Boolean cache: Set ``True`` to only notify observers when the attribute value changes. - """ - # Cached values are not re-sent if they are unchanged. - if cache: - if attr_name in self._attribute_cache and self._attribute_cache[attr_name] == value: - return - self._attribute_cache[attr_name] = value - - # Notify observers. - for fn in self._attribute_listeners.get(attr_name, []): - fn(self, attr_name, value) - for fn in self._attribute_listeners.get('*', []): - fn(self, attr_name, value) - - def on_attribute(self, name): - """ - Decorator for attribute listeners. - - The decorated function (``observer``) is invoked differently depending on the *type of attribute*. - Attributes that represent sensor values or which are used to monitor connection status are updated - whenever a message is received from the vehicle. Attributes which reflect vehicle "state" are - only updated when their values change (for example :py:func:`Vehicle.system_status `, - :py:attr:`Vehicle.armed `, and :py:attr:`Vehicle.mode `). - - The callback arguments are: - - * ``self`` - the associated :py:class:`Vehicle`. This may be compared to a global vehicle handle - to implement vehicle-specific callback handling (if needed). - * ``attr_name`` - the attribute name. This can be used to infer which attribute has triggered - if the same callback is used for watching several attributes. - * ``msg`` - the attribute value (so you don't need to re-query the vehicle object). - - .. note:: - - There is no way to remove an attribute listener added with this decorator. Use - :py:func:`add_attribute_listener` if you need to be able to remove - the :py:func:`attribute listener `. - - The code fragment below shows how you can create a listener for the attitude attribute. - - .. code:: python - - @vehicle.on_attribute('attitude') - def attitude_listener(self, name, msg): - print '%s attribute is: %s' % (name, msg) - - See :ref:`vehicle_state_observe_attributes` for more information. - - :param String attr_name: The name of the attribute to watch (or '*' to watch all attributes). - :param observer: The callback to invoke when a change in the attribute is detected. - """ - def decorator(fn): - if isinstance(name, list): - for n in name: - self.add_attribute_listener(n, fn) - else: - self.add_attribute_listener(name, fn) - return decorator - -class ChannelsOverride(dict): - """ - A dictionary class for managing Vehicle channel overrides. - - Channels can be read, written, or cleared by index or using a dictionary syntax. - To clear a value, set it to ``None`` or use ``del`` on the item. - - For more information and examples see :ref:`example_channel_overrides`. - """ - def __init__(self, vehicle): - self._vehicle = vehicle - self._count = 8 # Fixed by MAVLink - self._active = True - - def __getitem__(self, key): - return dict.__getitem__(self, str(key)) - - def __setitem__(self, key, value): - if not (int(key) > 0 and int(key) <= self._count): - raise Exception('Invalid channel index %s' % key) - if not value: - try: - dict.__delitem__(self, str(key)) - except: - pass - else: - dict.__setitem__(self, str(key), value) - self._send() - - def __delitem__(self, key): - dict.__delitem__(self, str(key)) - self._send() - - def __len__(self): - return self._count - - def _send(self): - if self._active: - overrides = [0] * 8 - for k, v in self.iteritems(): - overrides[int(k)-1] = v - self._vehicle._master.mav.rc_channels_override_send(0, 0, *overrides) - - -class Channels(dict): - """ - A dictionary class for managing RC channel information associated with a :py:class:`Vehicle`. - - An object of this type is accessed through :py:attr:`Vehicle.channels`. This object also stores - the current vehicle channel overrides through its :py:attr:`overrides` attribute. - - For more information and examples see :ref:`example_channel_overrides`. - """ - - def __init__(self, vehicle, count): - self._vehicle = vehicle - self._count = count - self._overrides = ChannelsOverride(vehicle) - - # populate readback - self._readonly = False - for k in range(0, count): - self[k + 1] = None - self._readonly = True - - @property - def count(self): - """ - The number of channels defined in the dictionary (currently 8). - """ - return self._count - - def __getitem__(self, key): - return dict.__getitem__(self, str(key)) - - def __setitem__(self, key, value): - if self._readonly: - raise TypeError('__setitem__ is not supported on Channels object') - return dict.__setitem__(self, str(key), value) - - def __len__(self): - return self._count - - def _update_channel(self, channel, value): - # If we have channels on different ports, we expand the Channels - # object to support them. - channel = int(channel) - self._readonly = False - self[channel] = value - self._readonly = True - self._count = max(self._count, channel) - - @property - def overrides(self): - """ - Attribute to read, set and clear channel overrides (also known as "rc overrides") - associated with a :py:class:`Vehicle` (via :py:class:`Vehicle.channels`). This is an - object of type :py:class:`ChannelsOverride`. - - For more information and examples see :ref:`example_channel_overrides`. - - To set channel overrides: - - .. code:: python - - # Set and clear overrids using dictionary syntax (clear by setting override to none) - vehicle.channels.overrides = {'5':None, '6':None,'3':500} - - # You can also set and clear overrides using indexing syntax - vehicle.channels.overrides['2'] = 200 - vehicle.channels.overrides['2'] = None - - # Clear using 'del' - del vehicle.channels.overrides['3'] - - # Clear all overrides by setting an empty dictionary - vehicle.channels.overrides = {} - - Read the channel overrides either as a dictionary or by index. Note that you'll get - a ``KeyError`` exception if you read a channel override that has not been set. - - .. code:: python - - # Get all channel overrides - print " Channel overrides: %s" % vehicle.channels.overrides - # Print just one channel override - print " Ch2 override: %s" % vehicle.channels.overrides['2'] - """ - return self._overrides - - @overrides.setter - def overrides(self, newch): - self._overrides._active = False - self._overrides.clear() - for k, v in newch.iteritems(): - if v: - self._overrides[str(k)] = v - else: - try: - del self._overrides[str(k)] - except: - pass - self._overrides._active = True - self._overrides._send() - -class Locations(HasObservers): - """ - An object for holding location information in global, global relative and local frames. - - :py:class:`Vehicle` owns an object of this type. See :py:attr:`Vehicle.location` for information on - reading and observing location in the different frames. - - The different frames are accessed through the members, which are created with this object. - They can be read, and are observable. - """ - def __init__(self, vehicle): - super(Locations, self).__init__() - - self._lat = None - self._lon = None - self._alt = None - self._relative_alt = None - - @vehicle.on_message('GLOBAL_POSITION_INT') - def listener(vehicle, name, m): - (self._lat, self._lon) = (m.lat / 1.0e7, m.lon / 1.0e7) - self._relative_alt = m.relative_alt/1000.0 - self.notify_attribute_listeners('global_relative_frame', self.global_relative_frame) - vehicle.notify_attribute_listeners('location.global_relative_frame', vehicle.location.global_relative_frame) - - if self._alt != None or m.alt != 0: - # Require first alt value to be non-0 - # TODO is this the proper check to do? - self._alt = m.alt/1000.0 - self.notify_attribute_listeners('global_frame', self.global_frame) - vehicle.notify_attribute_listeners('location.global_frame', vehicle.location.global_frame) - - vehicle.notify_attribute_listeners('location', vehicle.location) - - self._north = None - self._east = None - self._down = None - - @vehicle.on_message('LOCAL_POSITION_NED') - def listener(vehicle, name, m): - self._north = m.x - self._east = m.y - self._down = m.z - self.notify_attribute_listeners('local_frame', self.local_frame) - vehicle.notify_attribute_listeners('location.local_frame', vehicle.location.local_frame) - vehicle.notify_attribute_listeners('location', vehicle.location) - - @property - def local_frame(self): - """ - Location in local NED frame (a :py:class:`LocationGlobalRelative`). - - This is accessed through the :py:attr:`Vehicle.location ` attribute: - - .. code-block:: python - - print "Local Location: %s" % vehicle.location.local_frame - - This location will not start to update until the vehicle is armed. - """ - return LocationLocal(self._north, self._east, self._down) - - @property - def global_frame(self): - """ - Location in global frame (a :py:class:`LocationGlobal`). - - This is accessed through the :py:attr:`Vehicle.location ` attribute: - - .. code-block:: python - - print "Global Location: %s" % vehicle.location.global_frame - - Its ``lat`` and ``lon`` attributes are populated shortly after GPS becomes available. - The ``alt`` can take several seconds longer to populate (from the barometer). - Listeners are not notified of changes to this attribute until it has fully populated. - """ - return LocationGlobal(self._lat, self._lon, self._alt) - - @property - def global_relative_frame(self): - """ - Location in global frame, with altitude relative to the home location - (a :py:class:`LocationGlobalRelative`). - - This is accessed through the :py:attr:`Vehicle.location ` attribute: - - .. code-block:: python - - print "Global Location (relative altitude): %s" % vehicle.location.global_relative_frame - """ - return LocationGlobalRelative(self._lat, self._lon, self._relative_alt) - - -class Vehicle(HasObservers): - """ - The main vehicle API - - Asynchronous notification on change of vehicle state is available by registering observers (callbacks) for attribute changes. - - Most vehicle state is exposed through python attributes (e.g. ``vehicle.location``). Most of these attributes are - auto-populated based on the capabilities of the connected autopilot/vehicle. - - Particular autopilots/vehicles may define different attributes from this standard list (extra batteries, GPIOs, etc.) - However if a standard attribute is defined it must follow the rules specified below. - - **Autopilot specific attributes & types:** - - To prevent name clashes the following naming convention should be used: - - * ``ap_`` - For autopilot specific parameters (apm 2.5, pixhawk etc.). For example "ap_pin5_mode" and "ap_pin5_value". - * ``user_`` - For user specific parameters - - **Standard attributes & types:** - - .. py:attribute:: attitude - - Current vehicle :py:class:`Attitude` (pitch, yaw, roll). - - .. py:attribute:: velocity - - Current velocity as a three element list ``[ vx, vy, vz ]`` (in meter/sec). - - .. py:attribute:: mode - - This attribute is used to get and set the current flight mode (:py:class:`VehicleMode`). - - .. py:attribute:: airspeed - - Current airspeed in metres/second (``double``). - - .. todo:: FIXME: Should airspeed value move somewhere else from "Standard attributes & types" table? - - .. py:attribute:: groundspeed - - Groundspeed in metres/second (``double``). - - .. py:attribute:: gps_0 - - GPS position information (:py:class:`GPSInfo`). - - .. py:attribute:: armed - - This attribute can be used to get and set the ``armed`` state of the vehicle (``boolean``). - - The code below shows how to read the state, and to arm/disam the vehicle: - - .. code:: python - - # Print the armed state for the vehicle - print "Armed: %s" % vehicle.armed - - # Disarm the vehicle - vehicle.armed = False - - # Arm the vehicle - vehicle.armed = True - - .. py:attribute:: mount_status - - Current status of the camera mount (gimbal) as a three element list: ``[ pitch, yaw, roll ]``. - - The values in the list are set to ``None`` if no mount is configured. - - .. py:attribute:: battery - - Current system :py:class:`Battery` status. - - .. py:attribute:: rangefinder - - :py:class:`Rangefinder` distance and voltage values. - - - - **Autopilot specific attributes & types:** - - .. py:attribute:: ap_pin5_mode - - string (adc, dout, din) - - .. py:attribute:: ap_pin5_value - - ? double (0, 1, 2.3 etc...) - - .. todo:: Add waypoint_home attribute IF this is added: https://github.com/dronekit/dronekit-python/issues/105 - - """ - - def __init__(self, handler): - super(Vehicle, self).__init__() - - self._handler = handler - self._master = handler.master - - # Cache all updated attributes for wait_ready. - # By default, we presume all "commands" are loaded. - self._ready_attrs = set(['commands']) - - # Default parameters when calling wait_ready() or wait_ready(True). - self._default_ready_attrs = ['parameters', 'gps_0', 'armed', 'mode', 'attitude'] - - @self.on_attribute('*') - def listener(_, name, value): - self._ready_attrs.add(name) - - # Attaches message listeners. - self._message_listeners = dict() - - @handler.forward_message - def listener(_, msg): - self.notify_message_listeners(msg.get_type(), msg) - - self._location = Locations(self) - self._vx = None - self._vy = None - self._vz = None - - @self.on_message('GLOBAL_POSITION_INT') - def listener(self, name, m): - (self._vx, self._vy, self._vz) = (m.vx / 100.0, m.vy / 100.0, m.vz / 100.0) - self.notify_attribute_listeners('velocity', self.velocity) - - self._pitch = None - self._yaw = None - self._roll = None - self._pitchspeed = None - self._yawspeed = None - self._rollspeed = None - - @self.on_message('ATTITUDE') - def listener(self, name, m): - self._pitch = m.pitch - self._yaw = m.yaw - self._roll = m.roll - self._pitchspeed = m.pitchspeed - self._yawspeed = m.yawspeed - self._rollspeed = m.rollspeed - self.notify_attribute_listeners('attitude', self.attitude) - - self._heading = None - self._airspeed = None - self._groundspeed = None - - @self.on_message('VFR_HUD') - def listener(self, name, m): - self._heading = m.heading - self.notify_attribute_listeners('heading', self.heading) - self._airspeed = m.airspeed - self.notify_attribute_listeners('airspeed', self.airspeed) - self._groundspeed = m.groundspeed - self.notify_attribute_listeners('groundspeed', self.groundspeed) - - self._rngfnd_distance = None - self._rngfnd_voltage = None - - @self.on_message('RANGEFINDER') - def listener(self, name, m): - self._rngfnd_distance = m.distance - self._rngfnd_voltage = m.voltage - self.notify_attribute_listeners('rangefinder', self.rangefinder) - - self._mount_pitch = None - self._mount_yaw = None - self._mount_roll = None - - @self.on_message('MOUNT_STATUS') - def listener(self, name, m): - self._mount_pitch = m.pointing_a / 100 - self._mount_roll = m.pointing_b / 100 - self._mount_yaw = m.pointing_c / 100 - self.notify_attribute_listeners('mount', self.mount_status) - - # All keys are strings. - self._channels = Channels(self, 8) - - @self.on_message('RC_CHANNELS_RAW') - def listener(self, name, m): - def set_rc(chnum, v): - '''Private utility for handling rc channel messages''' - # use port to allow ch nums greater than 8 - self._channels._update_channel(str(m.port * 8 + chnum), v) - - set_rc(1, m.chan1_raw) - set_rc(2, m.chan2_raw) - set_rc(3, m.chan3_raw) - set_rc(4, m.chan4_raw) - set_rc(5, m.chan5_raw) - set_rc(6, m.chan6_raw) - set_rc(7, m.chan7_raw) - set_rc(8, m.chan8_raw) - self.notify_attribute_listeners('channels', self.channels) - - self._voltage = None - self._current = None - self._level = None - - @self.on_message('SYS_STATUS') - def listener(self, name, m): - self._voltage = m.voltage_battery - self._current = m.current_battery - self._level = m.battery_remaining - self.notify_attribute_listeners('battery', self.battery) - - self._eph = None - self._epv = None - self._satellites_visible = None - self._fix_type = None # FIXME support multiple GPSs per vehicle - possibly by using componentId - - @self.on_message('GPS_RAW_INT') - def listener(self, name, m): - self._eph = m.eph - self._epv = m.epv - self._satellites_visible = m.satellites_visible - self._fix_type = m.fix_type - self.notify_attribute_listeners('gps_0', self.gps_0) - - self._current_waypoint = 0 - - @self.on_message(['WAYPOINT_CURRENT', 'MISSION_CURRENT']) - def listener(self, name, m): - self._current_waypoint = m.seq - - self._ekf_poshorizabs = False - self._ekf_constposmode = False - self._ekf_predposhorizabs = False - - @self.on_message('EKF_STATUS_REPORT') - def listener(self, name, m): - # boolean: EKF's horizontal position (absolute) estimate is good - self._ekf_poshorizabs = (m.flags & ardupilotmega.EKF_POS_HORIZ_ABS) > 0 - # boolean: EKF is in constant position mode and does not know it's absolute or relative position - self._ekf_constposmode = (m.flags & ardupilotmega.EKF_CONST_POS_MODE) > 0 - # boolean: EKF's predicted horizontal position (absolute) estimate is good - self._ekf_predposhorizabs = (m.flags & ardupilotmega.EKF_PRED_POS_HORIZ_ABS) > 0 - - self.notify_attribute_listeners('ekf_ok', self.ekf_ok) - - self._flightmode = 'AUTO' - self._armed = False - self._system_status = None - - @self.on_message('HEARTBEAT') - def listener(self, name, m): - self._armed = (m.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED) != 0 - self.notify_attribute_listeners('armed', self.armed, cache=True) - self._flightmode = {v: k for k, v in self._master.mode_mapping().items()}[m.custom_mode] - self.notify_attribute_listeners('mode', self.mode, cache=True) - self._system_status = m.system_status - self.notify_attribute_listeners('system_status', self.system_status, cache=True) - - # Waypoints. - - self._home_location = None - self._wploader = mavwp.MAVWPLoader() - self._wp_loaded = True - self._wp_uploaded = None - self._wpts_dirty = False - self._commands = CommandSequence(self) - - @self.on_message(['WAYPOINT_COUNT','MISSION_COUNT']) - def listener(self, name, msg): - if not self._wp_loaded: - self._wploader.clear() - self._wploader.expected_count = msg.count - self._master.waypoint_request_send(0) - - @self.on_message(['WAYPOINT', 'MISSION_ITEM']) - def listener(self, name, msg): - if not self._wp_loaded: - if msg.seq == 0: - if not (msg.x == 0 and msg.y == 0 and msg.z == 0): - self._home_location = LocationGlobal(msg.x, msg.y, msg.z) - - if msg.seq > self._wploader.count(): - # Unexpected waypoint - pass - elif msg.seq < self._wploader.count(): - # Waypoint duplicate - pass - else: - self._wploader.add(msg) - - if msg.seq + 1 < self._wploader.expected_count: - self._master.waypoint_request_send(msg.seq + 1) - else: - self._wp_loaded = True - self.notify_attribute_listeners('commands', self.commands) - - # Waypoint send to master - @self.on_message(['WAYPOINT_REQUEST', 'MISSION_REQUEST']) - def listener(self, name, msg): - if self._wp_uploaded != None: - wp = self._wploader.wp(msg.seq) - handler.fix_targets(wp) - self._master.mav.send(wp) - self._wp_uploaded[msg.seq] = True - - # TODO: Waypoint loop listeners - - # Parameters. - - start_duration = 0.2 - repeat_duration = 1 - - self._params_count = -1 - self._params_set = [] - self._params_loaded = False - self._params_start = False - self._params_map = {} - self._params_last = time.time() # Last new param. - self._params_duration = start_duration - self._parameters = Parameters(self) - - @handler.forward_loop - def listener(_): - # Check the time duration for last "new" params exceeds watchdog. - if self._params_start: - if None not in self._params_set and not self._params_loaded: - self._params_loaded = True - self.notify_attribute_listeners('parameters', self.parameters) - - if not self._params_loaded and time.time() - self._params_last > self._params_duration: - c = 0 - for i, v in enumerate(self._params_set): - if v == None: - self._master.mav.param_request_read_send(0, 0, '', i) - c += 1 - if c > 50: - break - self._params_duration = repeat_duration - self._params_last = time.time() - - @self.on_message(['PARAM_VALUE']) - def listener(self, name, msg): - # If we discover a new param count, assume we - # are receiving a new param set. - if self._params_count != msg.param_count: - self._params_loaded = False - self._params_start = True - self._params_count = msg.param_count - self._params_set = [None]*msg.param_count - - # Attempt to set the params. We throw an error - # if the index is out of range of the count or - # we lack a param_id. - try: - if msg.param_index < msg.param_count and msg: - if self._params_set[msg.param_index] == None: - self._params_last = time.time() - self._params_duration = start_duration - self._params_set[msg.param_index] = msg - self._params_map[msg.param_id] = msg.param_value - self._parameters.notify_attribute_listeners(msg.param_id, msg.param_value, cache=True) - except: - import traceback - traceback.print_exc() - - # Heartbeats. - - self._heartbeat_started = False - self._heartbeat_lastsent = 0 - self._heartbeat_lastreceived = 0 - self._heartbeat_timeout = False - - self._heartbeat_warning = 5 - self._heartbeat_error = 30 - self._heartbeat_system = None - - @handler.forward_loop - def listener(_): - # Send 1 heartbeat per second - if time.time() - self._heartbeat_lastsent > 1: - self._master.mav.heartbeat_send(mavutil.mavlink.MAV_TYPE_GCS, mavutil.mavlink.MAV_AUTOPILOT_INVALID, 0, 0, 0) - self._heartbeat_lastsent = time.time() - - # Timeouts. - if self._heartbeat_started: - 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) - elif time.time() - self._heartbeat_lastreceived > self._heartbeat_warning: - if self._heartbeat_timeout == False: - errprinter('>>> Link timeout, no heartbeat in last %s seconds' % self._heartbeat_warning) - self._heartbeat_timeout = True - - @self.on_message(['HEARTBEAT']) - def listener(self, name, msg): - self._heartbeat_system = msg.get_srcSystem() - self._heartbeat_lastreceived = time.time() - if self._heartbeat_timeout: - errprinter('>>> ...link restored.') - self._heartbeat_timeout = False - - self._last_heartbeat = None - - @handler.forward_loop - def listener(_): - if self._heartbeat_lastreceived: - self._last_heartbeat = time.time() - self._heartbeat_lastreceived - self.notify_attribute_listeners('last_heartbeat', self.last_heartbeat) - - @property - def last_heartbeat(self): - """ - Time since last MAVLink heartbeat was received (in seconds). - - The attribute can be used to monitor link activity and implement script-specific timeout handling. - - For example, to pause the script if no heartbeat is received for more than 1 second you might implement - the following observer, and use ``pause_script`` in a program loop to wait until the link is recovered: - - .. code-block:: python - - pause_script=False - - @vehicle.on_attribute('last_heartbeat') - def listener(self, attr_name, value): - global pause_script - if value > 1 and not pause_script: - print "Pausing script due to bad link" - pause_script=True; - if value < 1 and pause_script: - pause_script=False; - print "Un-pausing script" - - The observer will be called at the period of the messaging loop (about every 0.01 seconds). Testing - on SITL indicates that ``last_heartbeat`` averages about .5 seconds, but will rarely exceed 1.5 seconds - when connected. Whether heartbeat monitoring can be useful will very much depend on the application. - - - .. note:: - - If you just want to change the heartbeat timeout you can modify the ``heartbeat_timeout`` - parameter passed to the :py:func:`connect() ` function. - - """ - return self._last_heartbeat - - def on_message(self, name): - """ - Decorator for message listener callback functions. - - .. tip:: - - This is the most elegant way to define message listener callback functions. - Use :py:func:`add_message_listener` only if you need to be able to - :py:func:`remove the listener ` later. - - A decorated message listener function is called with three arguments every time the - specified message is received: - - * ``self`` - the current vehicle. - * ``name`` - the name of the message that was intercepted. - * ``message`` - the actual message (a `pymavlink `_ - `class `_). - - For example, in the fragment below ``my_method`` will be called for every heartbeat message: - - .. code:: python - - @vehicle.on_message('HEARTBEAT') - def my_method(self, name, msg): - pass - - See :ref:`mavlink_messages` for more information. - - :param String name: The name of the message to be intercepted by the decorated listener function (or '*' to get all messages). - """ - def decorator(fn): - if isinstance(name, list): - for n in name: - self.add_message_listener(n, fn) - else: - self.add_message_listener(name, fn) - return decorator - - def add_message_listener(self, name, fn): - """ - Adds a message listener function that will be called every time the specified message is received. - - .. tip:: - - We recommend you use :py:func:`on_message` instead of this method as it has a more elegant syntax. - This method is only preferred if you need to be able to - :py:func:`remove the listener `. - - The callback function must have three arguments: - - * ``self`` - the current vehicle. - * ``name`` - the name of the message that was intercepted. - * ``message`` - the actual message (a `pymavlink `_ - `class `_). - - For example, in the fragment below ``my_method`` will be called for every heartbeat message: - - .. code:: python - - #Callback method for new messages - def my_method(self, name, msg): - pass - - vehicle.add_message_listener('HEARTBEAT',my_method) - - See :ref:`mavlink_messages` for more information. - - :param String name: The name of the message to be intercepted by the listener function (or '*' to get all messages). - :param fn: The listener function that will be called if a message is received. - """ - name = str(name) - if name not in self._message_listeners: - self._message_listeners[name] = [] - if fn not in self._message_listeners[name]: - self._message_listeners[name].append(fn) - - def remove_message_listener(self, name, fn): - """ - Removes a message listener (that was previously added using :py:func:`add_message_listener`). - - See :ref:`mavlink_messages` for more information. - - :param String name: The name of the message for which the listener is to be removed (or '*' to remove an 'all messages' observer). - :param fn: The listener callback function to remove. - - """ - name = str(name) - if name in self._message_listeners: - self._message_listeners[name].remove(fn) - if len(self._message_listeners[name]) == 0: - del self._message_listeners[name] - - def notify_message_listeners(self, name, msg): - for fn in self._message_listeners.get(name, []): - fn(self, name, msg) - for fn in self._message_listeners.get('*', []): - fn(self, name, msg) - - def close(self): - return self._handler.close() - - def flush(self): - """ - Call ``flush()`` after :py:func:`adding ` or :py:func:`clearing ` mission commands. - - After the return from ``flush()`` any writes are guaranteed to have completed (or thrown an - exception) and future reads will see their effects. - - .. warning:: - - This has been replaced by :py:func:`Vehicle.commands.upload() `. - """ - return self.commands.upload() - - # - # Private sugar methods - # - - @property - def _mode_mapping(self): - return self._master.mode_mapping() - - # - # Operations to support the standard API. - # - - @property - def mode(self): - if not self._flightmode: - return None - return VehicleMode(self._flightmode) - - @mode.setter - def mode(self, v): - self._master.set_mode(self._mode_mapping[v.name]) - - @property - def location(self): - """ - A :py:class:`Locations` object containing vehicle location information in - global, global relative and local frames. - - The different frames are accessed through its members: - - * :py:attr:`global_frame ` (a :py:class:`LocationGlobal`) - * :py:attr:`global_relative_frame ` (a :py:class:`LocationGlobalRelative`) - * :py:attr:`local_frame ` (a :py:class:`LocationLocal`) - - For example, to print the location in each frame for a ``vehicle``: - - .. code-block:: python - - # Print location information for `vehicle` in all frames (default printer) - print "Global Location: %s" % vehicle.location.global_frame - print "Global Location (relative altitude): %s" % vehicle.location.global_relative_frame - print "Local Location: %s" % vehicle.location.local_frame #NED - - # Print altitudes in the different frames (see class definitions for other available information) - print "Altitude (global frame): %s" % vehicle.location.global_frame.alt - print "Altitude (global relative frame): %s" % vehicle.location.global_relative_frame.alt - print "Altitude (NED frame): %s" % vehicle.location.local_frame.down - - .. note:: - - All the location "values" (e.g. ``global_frame.lat``) are initially - created with value ``None``. The ``global_frame``, ``global_relative_frame`` - latitude and longitude values are populated shortly after initialisation but - ``global_frame.alt`` may take a few seconds longer to be updated. - The ``local_frame`` does not populate until the vehicle is armed. - - The attribute and its members are observable. To watch for changes in all frames using a listener - created using a decorator (you can also define a listener and explicitly add it). - - .. code-block:: python - - @vehicle.on_attribute('location') - def listener(self, attr_name, value): - # `self`: :py:class:`Vehicle` object that has been updated. - # `attr_name`: name of the observed attribute - 'location' - # `value` is the updated attribute value (a :py:class:`Locations`). This can be queried for the frame information - print " Global: %s" % value.global_frame - print " GlobalRelative: %s" % value.global_relative_frame - print " Local: %s" % value.local_frame - - To watch for changes in just one attribute (in this case ``global_frame``): - - .. code-block:: python - - @vehicle.on_attribute('location.global_frame') - def listener(self, attr_name, value): - # `self`: :py:class:`Locations` object that has been updated. - # `attr_name`: name of the observed attribute - 'global_frame' - # `value` is the updated attribute value. - print " Global: %s" % value - - #Or watch using decorator: ``@vehicle.location.on_attribute('global_frame')``. - """ - return self._location - - @property - def battery(self): - if self._voltage == None or self._current == None or self._level == None: - return None - return Battery(self._voltage, self._current, self._level) - - @property - def rangefinder(self): - return Rangefinder(self._rngfnd_distance, self._rngfnd_voltage) - - @property - def velocity(self): - return [ self._vx, self._vy, self._vz ] - - @property - def attitude(self): - return Attitude(self._pitch, self._yaw, self._roll) - - @property - def gps_0(self): - return GPSInfo(self._eph, self._epv, self._fix_type, self._satellites_visible) - - @property - def armed(self): - return self._armed - - @armed.setter - def armed(self, value): - if bool(value) != self._armed: - if value: - self._master.arducopter_arm() - else: - self._master.arducopter_disarm() - - @property - def is_armable(self): - """ - Returns ``True`` if the vehicle is ready to arm, false otherwise. - - This attribute wraps a number of pre-arm checks, ensuring that the vehicle has booted, - has a good GPS fix, and that the EKF pre-arm is complete. - """ - # check that mode is not INITIALSING - # check that we have a GPS fix - # check that EKF pre-arm is complete - return self.mode != 'INITIALISING' and self.gps_0.fix_type > 1 and self._ekf_predposhorizabs - - @property - def system_status(self): - """ - System status. Is a ``SystemStatus`` object with a ``state`` property of: - - * ``UNINIT``: Uninitialized system, state is unknown. - * ``BOOT``: System is booting up. - * ``CALIBRATING``: System is calibrating and not flight-ready. - * ``STANDBY``: System is grounded and on standby. It can be launched any time. - * ``ACTIVE``: System is active and might be already airborne. Motors are engaged. - * ``CRITICAL``: System is in a non-normal flight mode. It can however still navigate. - * ``EMERGENCY``: System is in a non-normal flight mode. It lost control over parts - or over the whole airframe. It is in mayday and going down. - * ``POWEROFF``: System just initialized its power-down sequence, will shut down now. - """ - return { - 0: SystemStatus('UNINIT'), - 1: SystemStatus('BOOT'), - 2: SystemStatus('CALIBRATING'), - 3: SystemStatus('STANDBY'), - 4: SystemStatus('ACTIVE'), - 5: SystemStatus('CRITICAL'), - 6: SystemStatus('EMERGENCY'), - 7: SystemStatus('POWEROFF'), - }.get(self._system_status, None) - - @property - def heading(self): - """ - Current heading in degrees (0..360, where North = 0). - """ - return self._heading - - @property - def groundspeed(self): - return self._groundspeed - - @property - def airspeed(self): - return self._airspeed - - @property - def mount_status(self): - return [ self._mount_pitch, self._mount_yaw, self._mount_roll ] - - @property - def ekf_ok(self): - """ - ``True`` if the EKF status is considered acceptable, ``False`` otherwise. - """ - # legacy check for dronekit-python for solo - # use same check that ArduCopter::system.pde::position_ok() is using - if self.armed: - return self._ekf_poshorizabs and not self._ekf_constposmode - else: - return self._ekf_poshorizabs or self._ekf_predposhorizabs - - @property - def channels(self): - """ - The RC channel values from the RC Transmitter, in a :py:class:`Channels` object. - The attribute can also be used to set and read RC Override (channel override) values - via :py:attr:`Vehicle.channels.override `. - - For more information and examples see :ref:`example_channel_overrides`. - - To read the channels from the RC transmitter: - - .. code:: python - - # Get all channel values from RC transmitter - print "Channel values from RC Tx:", vehicle.channels - - # Access channels individually - print "Read channels individually:" - print " Ch1: %s" % vehicle.channels['1'] - print " Ch2: %s" % vehicle.channels['2'] - - """ - return self._channels - - @property - def home_location(self): - """ - The current home location in a :py:class:`LocationGlobal`. - - To get the attribute you must first download the :py:func:`Vehicle.commands`. - The attribute has a value of ``None`` until :py:func:`Vehicle.commands` has been downloaded - **and** the autopilot has set an initial home location (typically where the vehicle first gets GPS lock). - - .. code-block:: python - - #Connect to a vehicle object (for example, on com14) - vehicle = connect('com14', wait_ready=True) - - # Download the vehicle waypoints (commands). Wait until download is complete. - cmds = vehicle.commands - cmds.download() - cmds.wait_ready() - - # Get the home location - home = vehicle.home_location - - The ``home_location`` is not observable. - - The attribute can be written (in the same way as any other attribute) after it has successfully - been populated from the vehicle. The value sent to the vehicle is cached in the attribute - (and can potentially get out of date if you don't re-download ``Vehicle.commands``): - - .. warning:: - - Setting the value will fail silently if the specified location is more than 50km from the EKF origin. - - - """ - return copy.copy(self._home_location) - - @home_location.setter - def home_location(self, pos): - """ - Sets the home location to that of a ``LocationGlobal`` object. - - The value cannot be set until it has successfully been read from the vehicle. After being - set the value is cached in the home_location attribute and does not have to be re-read. - - .. note:: - - Setting the value will fail silently if the specified location is more than 50km from the EKF origin. - """ - - if not isinstance(pos, LocationGlobal): - raise Exception('Excepting home_location to be set to a LocationGlobal.') - - # Set cached home location. - self._home_location = copy.copy(pos) - - # Send MAVLink update. - self.send_mavlink(self.message_factory.command_long_encode( - 0, 0, # target system, target component - mavutil.mavlink.MAV_CMD_DO_SET_HOME, # command - 0, # confirmation - 2, # param 1: 1 to use current position, 2 to use the entered values. - 0, 0, 0, # params 2-4 - pos.lat, - pos.lon, - pos.alt - )) - - @property - def commands(self): - """ - Gets the editable waypoints for this vehicle (the current "mission"). - - This can be used to get, create, and modify a mission. It can also be used for direct control of vehicle position - (outside missions) using the :py:func:`goto ` method. - - :returns: A :py:class:`CommandSequence` containing the waypoints for this vehicle. - """ - return self._commands - - @property - def parameters(self): - """ - The (editable) parameters for this vehicle (:py:class:`Parameters `). - """ - return self._parameters - - def send_mavlink(self, message): - """ - This method is used to send raw MAVLink "custom messages" to the vehicle. - - The function can send arbitrary messages/commands to the connected vehicle at any time and in any vehicle mode. - It is particularly useful for controlling vehicles outside of missions (for example, in GUIDED mode). - - The :py:func:`message_factory ` is used to create messages in the appropriate format. - - For more information see the guide topic: :ref:`guided_mode_how_to_send_commands`. - - :param message: A ``MAVLink_message`` instance, created using :py:func:`message_factory `. - There is need to specify the system id, component id or sequence number of messages as the API will set these appropriately. - """ - self._master.mav.send(message) - - @property - def message_factory(self): - """ - Returns an object that can be used to create 'raw' MAVLink messages that are appropriate for this vehicle. - The message can then be sent using :py:func:`send_mavlink(message) `. - - .. note:: - - Vehicles support a subset of the messages defined in the MAVLink standard. For more information - about the supported sets see wiki topics: - `Copter Commands in Guided Mode `_ - and `Plane Commands in Guided Mode `_. - - All message types are defined in the central MAVLink github repository. For example, a Pixhawk understands - the following messages (from `pixhawk.xml `_): - - .. code:: xml - - - 0 to disable, 1 to enable - - - The name of the factory method will always be the lower case version of the message name with *_encode* appended. - Each field in the XML message definition must be listed as arguments to this factory method. So for this example - message, the call would be: - - .. code:: python - - msg = vehicle.message_factory.image_trigger_control_encode(True) - vehicle.send_mavlink(msg) - - Some message types include "addressing information". If present, there is no need to specify the ``target_system`` - id (just set to zero) as DroneKit will automatically update messages with the correct ID for the connected - vehicle before sending. - The ``target_component`` should be set to 0 (broadcast) unless the message is to specific component. - CRC fields and sequence numbers (if defined in the message type) are automatically set by DroneKit and can also - be ignored/set to zero. - - For more information see the guide topic: :ref:`guided_mode_how_to_send_commands`. - """ - return self._master.mav - - def initialize(self, rate=4, heartbeat_timeout=30): - self._handler.start() - - # Start heartbeat polling. - start = time.time() - self._heartbeat_error = heartbeat_timeout or 0 - self._heartbeat_started = True - self._heartbeat_lastreceived = start - - # Poll for first heartbeat. - # If heartbeat times out, this will interrupt. - while self._handler._alive: - time.sleep(.1) - if self._heartbeat_lastreceived != start: - break - if not self._handler._alive: - raise APIException('Timeout in initializing connection.') - - # Register target_system now. - self._handler.target_system = self._heartbeat_system - - # Wait until board has booted. - while True: - if self._flightmode not in [None, 'INITIALISING', 'MAV']: - break - time.sleep(0.1) - - # Initialize data stream. - if rate != None: - self._master.mav.request_data_stream_send(0, 0, - mavutil.mavlink.MAV_DATA_STREAM_ALL, rate, 1) - - # Ensure initial parameter download has started. - while True: - # This fn actually rate limits itself to every 2s. - # Just retry with persistence to get our first param stream. - self._master.param_fetch_all() - time.sleep(0.1) - if self._params_count > -1: - break - - def wait_ready(self, *types, **kwargs): - """ - Waits for specified attributes to be populated from the vehicle (values are initially ``None``). - - This is typically called "behind the scenes" to ensure that :py:func:`connect` does not return until - attributes have populated (via the ``wait_ready`` parameter). You can also use it after connecting to - wait on a specific value(s). - - There are two ways to call the method: - - .. code-block:: python - - #Wait on default attributes to populate - vehicle.wait_ready(True) - - #Wait on specified attributes (or array of attributes) to populate - vehicle.wait_ready('mode','airspeed') - - Using the ``wait_ready(True)`` waits on :py:attr:`parameters`, :py:attr:`gps_0`, - :py:attr:`armed`, :py:attr:`mode`, and :py:attr:`attitude`. In practice this usually - means that all supported attributes will be populated. - - By default, the method will timeout after 30 seconds and raise an exception if the - attributes were not populated. - - :param types: ``True`` to wait on the default set of attributes, or a - comma-separated list of the specific attributes to wait on. - :param int timeout: Timeout in seconds after which the method will raise an exception - (the default) or return ``False``. The default timeout is 30 seconds. - :param Boolean raise_exception: If ``True`` the method will raise an exception on timeout, - otherwise the method will return ``False``. The default is ``True`` (raise exception). - """ - timeout = kwargs.get('timeout', 30) - raise_exception = kwargs.get('raise_exception', True) - - # Vehicle defaults for wait_ready(True) or wait_ready() - if list(types) == [True] or list(types) == []: - types = self._default_ready_attrs - - if not all(isinstance(item, basestring) for item in types): - raise APIException('wait_ready expects one or more string arguments.') - - # Wait for these attributes to have been set. - await = set(types) - start = time.time() - while not await.issubset(self._ready_attrs): - time.sleep(0.1) - if time.time() - start > timeout: - if raise_exception: - raise APIException('wait_ready experienced a timeout after %s seconds.' % timeout) - else: - return False - - return True - -class Parameters(collections.MutableMapping, HasObservers): - """ - This object is used to get and set the values of named parameters for a vehicle. See the following links for information about - the supported parameters for each platform: `Copter `_, - `Plane `_, `Rover `_. - - The code fragment below shows how to get and set the value of a parameter. - - .. code:: python - - # Print the value of the THR_MIN parameter. - print "Param: %s" % vehicle.parameters['THR_MIN'] - - # Change the parameter value to something different. - vehicle.parameters['THR_MIN']=100 - - It is also possible to observe parameters and to iterate the :py:func:`Vehicle.parameters`. - - For more information see: :ref:`vehicle_state_parameters`. - """ - - def __init__(self, vehicle): - super(Parameters, self).__init__() - self._vehicle = vehicle - - def __getitem__(self, name): - name = name.upper() - self.wait_ready() - return self._vehicle._params_map[name] - - def __setitem__(self, name, value): - name = name.upper() - self.wait_ready() - self.set(name, value) - - def __delitem__(self, name): - raise APIException('Cannot delete value from parameters list.') - - def __len__(self): - return len(self._vehicle._params_map) - - def __iter__(self): - return self._vehicle._params_map.__iter__() - - def get(self, name, wait_ready=True): - name = name.upper() - if wait_ready: - self.wait_ready() - return self._vehicle._params_map.get(name, None) - - def set(self, name, value, retries=3, wait_ready=False): - if wait_ready: - self.wait_ready() - - # TODO dumbly reimplement this using timeout loops - # because we should actually be awaiting an ACK of PARAM_VALUE - # changed, but we don't have a proper ack structure, we'll - # instead just wait until the value itself was changed - - name = name.upper() - value = float(value) - success = False - remaining = retries - while True: - self._vehicle._master.param_set_send(name, value) - tstart = time.time() - if remaining == 0: - break - remaining -= 1 - while time.time() - tstart < 1: - if name in self._vehicle._params_map and self._vehicle._params_map[name] == value: - return True - time.sleep(0.1) - - if retries > 0: - errprinter("timeout setting parameter %s to %f" % (name, value)) - return False - - def wait_ready(self, **kwargs): - """ - Block the calling thread until parameters have been downloaded - """ - self._vehicle.wait_ready('parameters', **kwargs) - - def add_attribute_listener(self, attr_name, *args, **kwargs): - """ - Add a listener callback on a particular parameter. - - The callback can be removed using :py:func:`remove_attribute_listener`. - - .. note:: - - The :py:func:`on_attribute` decorator performs the same operation as this method, but with - a more elegant syntax. Use ``add_attribute_listener`` only if you will need to remove - the observer. - - The callback function is invoked only when the parameter changes. - - The callback arguments are: - - * ``self`` - the associated :py:class:`Parameters`. - * ``attr_name`` - the parameter name. This can be used to infer which parameter has triggered - if the same callback is used for watching multiple parameters. - * ``msg`` - the new parameter value (so you don't need to re-query the vehicle object). - - The example below shows how to get callbacks for the ``THR_MIN`` parameter: - - .. code:: python - - #Callback function for the THR_MIN parameter - def thr_min_callback(self, attr_name, value): - print " PARAMETER CALLBACK: %s changed to: %s" % (attr_name, value) - - #Add observer for the vehicle's THR_MIN parameter - vehicle.parameters.add_attribute_listener('THR_MIN', thr_min_callback) - - See :ref:`vehicle_state_observing_parameters` for more information. - - :param String attr_name: The name of the parameter to watch (or '*' to watch all parameters). - :param args: The callback to invoke when a change in the parameter is detected. - - """ - attr_name = attr_name.upper() - return super(Parameters, self).add_attribute_listener(attr_name, *args, **kwargs) - - def remove_attribute_listener(self, attr_name, *args, **kwargs): - """ - Remove a paremeter listener that was previously added using :py:func:`add_attribute_listener`. - - For example to remove the ``thr_min_callback()`` callback function: - - .. code:: python - - vehicle.parameters.remove_attribute_listener('thr_min', thr_min_callback) - - See :ref:`vehicle_state_observing_parameters` for more information. - - :param String attr_name: The parameter name that is to have an observer removed (or '*' to remove an 'all attribute' observer). - :param args: The callback function to remove. - - """ - attr_name = attr_name.upper() - return super(Parameters, self).remove_attribute_listener(attr_name, *args, **kwargs) - - def notify_attribute_listeners(self, attr_name, *args, **kwargs): - attr_name = attr_name.upper() - return super(Parameters, self).notify_attribute_listeners(attr_name, *args, **kwargs) - - def on_attribute(self, attr_name, *args, **kwargs): - """ - Decorator for parameter listeners. - - .. note:: - - There is no way to remove a listener added with this decorator. Use - :py:func:`add_attribute_listener` if you need to be able to remove - the :py:func:`listener `. - - The callback function is invoked only when the parameter changes. - - The callback arguments are: - - * ``self`` - the associated :py:class:`Parameters`. - * ``attr_name`` - the parameter name. This can be used to infer which parameter has triggered - if the same callback is used for watching multiple parameters. - * ``msg`` - the new parameter value (so you don't need to re-query the vehicle object). - - The code fragment below shows how to get callbacks for the ``THR_MIN`` parameter: - - .. code:: python - - @vehicle.parameters.on_attribute('THR_MIN') - def decorated_thr_min_callback(self, attr_name, value): - print " PARAMETER CALLBACK: %s changed to: %s" % (attr_name, value) - - See :ref:`vehicle_state_observing_parameters` for more information. - - :param String attr_name: The name of the parameter to watch (or '*' to watch all parameters). - :param args: The callback to invoke when a change in the parameter is detected. - - """ - attr_name = attr_name.upper() - return super(Parameters, self).on_attribute(attr_name, *args, **kwargs) - - -class Command(mavutil.mavlink.MAVLink_mission_item_message): - """ - A waypoint object. - - This object encodes a single mission item command. The set of commands that are supported by ArduPilot in Copter, Plane and Rover (along with their parameters) - are listed in the wiki article `MAVLink Mission Command Messages (MAV_CMD) `_. - - For example, to create a `NAV_WAYPOINT `_ command: - - .. code:: python - - cmd = Command(0,0,0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, - mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0,-34.364114, 149.166022, 30) - - :param target_system: This can be set to any value - (DroneKit changes the value to the MAVLink ID of the connected vehicle before the command is sent). - :param target_component: The component id if the message is intended for a particular component within the target system - (for example, the camera). Set to zero (broadcast) in most cases. - :param seq: The sequence number within the mission (the autopilot will reject messages sent out of sequence). - This should be set to zero as the API will automatically set the correct value when uploading a mission. - :param frame: The frame of reference used for the location parameters (x, y, z). In most cases this will be - ``mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT``, which uses the WGS84 global coordinate system for latitude and longitude, but sets altitude - as relative to the home position in metres (home altitude = 0). For more information `see the wiki here - `_. - :param command: The specific mission command (e.g. ``mavutil.mavlink.MAV_CMD_NAV_WAYPOINT``). The supported commands (and command parameters - are listed `on the wiki `_. - :param current: Set to zero (not supported). - :param autocontinue: Set to zero (not supported). - :param param1: Command specific parameter (depends on specific `Mission Command (MAV_CMD) `_). - :param param2: Command specific parameter. - :param param3: Command specific parameter. - :param param4: Command specific parameter. - :param x: (param5) Command specific parameter used for latitude (if relevant to command). - :param y: (param6) Command specific parameter used for longitude (if relevant to command). - :param z: (param7) Command specific parameter used for altitude (if relevant). The reference frame for altitude depends on the ``frame``. - - .. todo:: Confirm if target_sytem, target_component, seq, frame are all handled for you or not. If not, check that these are correct. - .. todo:: FIXME: Command class - for now we just inherit the standard MAVLink mission item contents. - """ - pass - -class CommandSequence(object): - """ - A sequence of vehicle waypoints (a "mission"). - - Operations include 'array style' indexed access to the various contained waypoints. - - The current commands/mission for a vehicle are accessed using the :py:attr:`Vehicle.commands ` attribute. - Waypoints are not downloaded from vehicle until :py:func:`download()` is called. The download is asynchronous; - use :py:func:`wait_ready()` to block your thread until the download is complete. - The code to download the commands from a vehicle is shown below: - - .. code-block:: python - :emphasize-lines: 5-10 - - #Connect to a vehicle object (for example, on com14) - vehicle = connect('com14', wait_ready=True) - - # Download the vehicle waypoints (commands). Wait until download is complete. - cmds = vehicle.commands - cmds.download() - cmds.wait_ready() - - The set of commands can be changed and uploaded to the client. The changes are not guaranteed to be complete until - :py:func:`upload() ` is called. - - .. code:: python - - cmds = vehicle.commands - cmds.clear() - lat = -34.364114, - lon = 149.166022 - altitude = 30.0 - cmd = Command(0,0,0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, - 0, 0, 0, 0, 0, 0, - lat, lon, altitude) - cmds.add(cmd) - cmds.upload() - - .. py:function:: takeoff(altitude) - - .. note:: This function should only be used on Copter vehicles. - - Take off and fly the vehicle to the specified altitude (in metres) and then wait for another command. - - The vehicle must be in ``GUIDED`` mode and armed before this is called. - - There is no mechanism for notification when the correct altitude is reached, and if another command arrives - before that point (e.g. :py:func:`goto`) it will be run instead. - - .. warning:: - - Apps should code to ensure that the vehicle will reach a safe altitude before other commands are executed. - A good example is provided in the guide topic :ref:`taking-off`. - - :param altitude: Target height, in metres. - - .. todo:: This is a hack. The actual function should be defined here. See https://github.com/dronekit/dronekit-python/issues/64 - """ - - def __init__(self, vehicle): - self._vehicle = vehicle - - def download(self): - ''' - Download all waypoints from the vehicle. - The download is asynchronous. Use :py:func:`wait_ready()` to block your thread until the download is complete. - ''' - self.wait_ready() - self._vehicle._ready_attrs.remove('commands') - self._vehicle._wp_loaded = False - self._vehicle._master.waypoint_request_list_send() - # BIG FIXME - wait for full wpt download before allowing any of the accessors to work - - def wait_ready(self, **kwargs): - """ - Block the calling thread until waypoints have been downloaded. - - This can be called after :py:func:`download()` to block the thread until the asynchronous download is complete. - """ - return self._vehicle.wait_ready('commands', **kwargs) - - def takeoff(self, alt=None): - if alt is not None: - altitude = float(alt) - if math.isnan(alt) or math.isinf(alt): - raise ValueError("Altitude was NaN or Infinity. Please provide a real number") - self._vehicle._master.mav.command_long_send(0, 0, - mavutil.mavlink.MAV_CMD_NAV_TAKEOFF, - 0, 0, 0, 0, 0, 0, 0, - altitude) - - def goto(self, location): - ''' - Go to a specified global location (:py:class:`LocationGlobal` or :py:class:`LocationGlobalRelative`). - - The method will change the :py:class:`VehicleMode` to ``GUIDED`` if necessary. - - .. code:: python - - # Set mode to guided - this is optional as the goto method will change the mode if needed. - vehicle.mode = VehicleMode("GUIDED") - - # Set the LocationGlobal to head towards - a_location = LocationGlobal(-34.364114, 149.166022, 30) - vehicle.commands.goto(a_location) - - :param LocationGlobal location: The target location. - ''' - if isinstance(location, LocationGlobalRelative): - frame = mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT - elif isinstance(location, LocationGlobal): - frame = mavutil.mavlink.MAV_FRAME_GLOBAL - else: - raise APIException('Expecting location to be LocationGlobal or LocationGlobalRelative.') - - self._vehicle._master.mav.mission_item_send(0, 0, 0, - frame, - mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, - 2, 0, 0, 0, 0, 0, - location.lat, location.lon, location.alt) - - def clear(self): - ''' - Clear the command list. - - This command will be sent to the vehicleonly after you call :py:func:`upload() `. - ''' - - # Add home point again. - self.wait_ready() - home = self._vehicle._wploader.wp(0) - self._vehicle._wploader.clear() - if home: - self._vehicle._wploader.add(home, comment='Added by DroneKit') - self._vehicle._wpts_dirty = True - - def add(self, cmd): - ''' - Add a new command (waypoint) at the end of the command list. - - .. note:: - - Commands are sent to the vehicle only after you call ::py:func:`upload() `. - - :param Command cmd: The command to be added. - ''' - self.wait_ready() - self._vehicle._handler.fix_targets(cmd) - self._vehicle._wploader.add(cmd, comment='Added by DroneKit') - self._vehicle._wpts_dirty = True - - def upload(self): - """ - Call ``upload()`` after :py:func:`adding ` or :py:func:`clearing ` mission commands. - - After the return from ``upload()`` any writes are guaranteed to have completed (or thrown an - exception) and future reads will see their effects. - """ - if self._vehicle._wpts_dirty: - self._vehicle._master.waypoint_clear_all_send() - if self._vehicle._wploader.count() > 0: - self._vehicle._wp_uploaded = [False]*self._vehicle._wploader.count() - self._vehicle._master.waypoint_count_send(self._vehicle._wploader.count()) - while False in self._vehicle._wp_uploaded: - time.sleep(0.1) - self._vehicle._wp_uploaded = None - self._vehicle._wpts_dirty = False - - @property - def count(self): - ''' - Return number of waypoints. - - :return: The number of waypoints in the sequence. - ''' - return max(self._vehicle._wploader.count() - 1, 0) - - @property - def next(self): - """ - Get the currently active waypoint number. - """ - return self._vehicle._current_waypoint - - @next.setter - def next(self, index): - """ - Set a new ``next`` waypoint for the vehicle. - """ - self._vehicle._master.waypoint_set_current_send(index) - - def __len__(self): - ''' - Return number of waypoints. - - :return: The number of waypoints in the sequence. - ''' - return max(self._vehicle._wploader.count() - 1, 0) - - def __getitem__(self, index): - if isinstance(index, slice): - return [self[ii] for ii in xrange(*index.indices(len(self)))] - elif isinstance(index, int): - item = self._vehicle._wploader.wp(index + 1) - if not item: - raise IndexError('Index %s out of range.' % index) - return item - else: - raise TypeError('Invalid argument type.') - - def __setitem__(self, index, value): - self._vehicle._wploader.set(value, index + 1) - self._vehicle._wpts_dirty = True diff --git a/dronekit/mavlink.py b/dronekit/mavlink.py index cb63fe368..d3abd1009 100644 --- a/dronekit/mavlink.py +++ b/dronekit/mavlink.py @@ -6,8 +6,8 @@ import platform import re import copy -import dronekit.lib -from dronekit.lib import APIException +import dronekit +from dronekit import APIException from dronekit.util import errprinter from pymavlink import mavutil, mavwp from Queue import Queue, Empty diff --git a/dronekit/test/sitl/test_channels.py b/dronekit/test/sitl/test_channels.py index 0df00ac6a..fb3d95e9e 100644 --- a/dronekit/test/sitl/test_channels.py +++ b/dronekit/test/sitl/test_channels.py @@ -1,5 +1,3 @@ -from dronekit import connect -from dronekit.lib import VehicleMode from pymavlink import mavutil import time from dronekit import connect, VehicleMode, LocationGlobal diff --git a/dronekit/test/unit/test_api.py b/dronekit/test/unit/test_api.py index b43b7ab2e..6a9f5dec0 100644 --- a/dronekit/test/unit/test_api.py +++ b/dronekit/test/unit/test_api.py @@ -1,7 +1,6 @@ import mock from mock import MagicMock -import dronekit -from dronekit.lib import VehicleMode +from dronekit import VehicleMode from nose.tools import assert_equals, assert_not_equals def test_vehicle_mode_eq(): diff --git a/dronekit/test/web/cloud_client_test.py b/dronekit/test/web/cloud_client_test.py index f55891515..005dcb631 100644 --- a/dronekit/test/web/cloud_client_test.py +++ b/dronekit/test/web/cloud_client_test.py @@ -1,6 +1,6 @@ import os from nose.tools import assert_raises -from dronekit.lib.CloudClient import * +from dronekit.cloud.CloudClient import * def setup_module(): diff --git a/examples/flight_replay/flight_replay.py b/examples/flight_replay/flight_replay.py index 6cda9042c..b90d61ec4 100644 --- a/examples/flight_replay/flight_replay.py +++ b/examples/flight_replay/flight_replay.py @@ -7,8 +7,7 @@ Full documentation is provided at http://python.dronekit.io/examples/flight_replay.html """ -from dronekit import connect -from dronekit.lib import Command +from dronekit import connect, Command from pymavlink import mavutil import json, urllib, math diff --git a/examples/follow_me/follow_me.py b/examples/follow_me/follow_me.py index 184fa7a34..661213596 100644 --- a/examples/follow_me/follow_me.py +++ b/examples/follow_me/follow_me.py @@ -10,12 +10,11 @@ Example documentation: http://python.dronekit.io/examples/follow_me.html """ -from dronekit import connect +from dronekit import connect, VehicleMode, LocationGlobal import gps import socket import time import sys -from dronekit.lib import VehicleMode, LocationGlobal #Set up option parsing to get connection string import argparse diff --git a/examples/gcs/microgcs.py b/examples/gcs/microgcs.py index 6e264d00c..78cf190af 100644 --- a/examples/gcs/microgcs.py +++ b/examples/gcs/microgcs.py @@ -2,8 +2,7 @@ # This is a small example of the python drone API - an ultra minimal GCS # -from dronekit import connect -from dronekit.lib import VehicleMode +from dronekit import connect, VehicleMode from pymavlink import mavutil from Tkinter import * diff --git a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py index 2a3f02bca..44f64bb8b 100644 --- a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py +++ b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py @@ -6,8 +6,7 @@ Example documentation: http://python.dronekit.io/examples/guided-set-speed-yaw-demo.html """ -from dronekit import connect -from dronekit.lib import VehicleMode, LocationGlobal +from dronekit import connect, VehicleMode, LocationGlobal from pymavlink import mavutil import time import math diff --git a/examples/mission_basic/mission_basic.py b/examples/mission_basic/mission_basic.py index b5c34d467..d34db9748 100644 --- a/examples/mission_basic/mission_basic.py +++ b/examples/mission_basic/mission_basic.py @@ -4,10 +4,9 @@ Full documentation is provided at http://python.dronekit.io/examples/mission_basic.html """ -from dronekit import connect +from dronekit import connect, VehicleMode, LocationGlobal, Command import time import math -from dronekit.lib import VehicleMode, LocationGlobal, Command from pymavlink import mavutil diff --git a/examples/mission_import_export/mission_import_export.py b/examples/mission_import_export/mission_import_export.py index 2514f5358..c55bc0ad6 100644 --- a/examples/mission_import_export/mission_import_export.py +++ b/examples/mission_import_export/mission_import_export.py @@ -9,8 +9,7 @@ """ -from dronekit import connect -from dronekit.lib import Command +from dronekit import connect, Command #Set up option parsing to get connection string diff --git a/examples/perf/perf_test.py b/examples/perf/perf_test.py index a4ea8efd1..96e4cb5cd 100644 --- a/examples/perf/perf_test.py +++ b/examples/perf/perf_test.py @@ -1,8 +1,7 @@ # # This is a small example of the python drone API # -from dronekit import connect -from dronekit.lib import VehicleMode +from dronekit import connect, VehicleMode from pymavlink import mavutil import time from datetime import datetime diff --git a/examples/simple_goto/simple_goto.py b/examples/simple_goto/simple_goto.py index da8c67e44..db4feb537 100644 --- a/examples/simple_goto/simple_goto.py +++ b/examples/simple_goto/simple_goto.py @@ -7,8 +7,7 @@ """ import time -from dronekit import connect -from dronekit.lib import VehicleMode, LocationGlobal, LocationGlobalRelative +from dronekit import connect, VehicleMode, LocationGlobal, LocationGlobalRelative from pymavlink import mavutil import time diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 71dc28060..5bbfcc76f 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -6,8 +6,7 @@ Full documentation is provided at http://python.dronekit.io/examples/vehicle_state.html """ -from dronekit import connect -from dronekit.lib import VehicleMode +from dronekit import connect, VehicleMode from pymavlink import mavutil import time diff --git a/setup.py b/setup.py index 0166b3bd4..20268ccfd 100644 --- a/setup.py +++ b/setup.py @@ -26,6 +26,6 @@ ], license='apache', packages=[ - 'dronekit', 'dronekit.lib', 'dronekit.test' + 'dronekit', 'dronekit.cloud', 'dronekit.test' ], ext_modules=[]) From 7e57545d2914c8c9c49c8b43f12b4c0666b4c885 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 18 Nov 2015 11:12:24 -0800 Subject: [PATCH 222/475] Formats code using yapf. --- .style.yapf | 3 + dronekit/__init__.py | 161 +++++++++++++++--------- dronekit/cloud/CloudClient.py | 3 + dronekit/cloud/__init__.py | 1 + dronekit/mavlink.py | 17 ++- dronekit/test/sitl/__init__.py | 1 + dronekit/test/sitl/test_110.py | 7 +- dronekit/test/sitl/test_115.py | 2 + dronekit/test/sitl/test_12.py | 4 +- dronekit/test/sitl/test_channels.py | 28 +++-- dronekit/test/sitl/test_earlyattrs.py | 1 + dronekit/test/sitl/test_goto.py | 5 +- dronekit/test/sitl/test_locations.py | 9 +- dronekit/test/sitl/test_mavlink.py | 4 +- dronekit/test/sitl/test_parameters.py | 7 +- dronekit/test/sitl/test_simpledemo.py | 2 + dronekit/test/sitl/test_state.py | 1 + dronekit/test/sitl/test_timeout.py | 2 + dronekit/test/sitl/test_vehicleclass.py | 18 +-- dronekit/test/sitl/test_waypoints.py | 16 ++- dronekit/test/unit/__init__.py | 1 + dronekit/test/unit/test_api.py | 2 + dronekit/util.py | 1 + 23 files changed, 191 insertions(+), 105 deletions(-) create mode 100644 .style.yapf diff --git a/.style.yapf b/.style.yapf new file mode 100644 index 000000000..728e3f0e0 --- /dev/null +++ b/.style.yapf @@ -0,0 +1,3 @@ +[style] +based_on_style = pep8 +column_limit = 100 diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 539c9ee14..9b22a69b2 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -101,6 +101,7 @@ from pymavlink import mavutil, mavwp from dronekit.util import errprinter + class APIException(Exception): """ Base class for DroneKit related exceptions. @@ -111,6 +112,7 @@ class APIException(Exception): def __init__(self, message): super(APIException, self).__init__(message) + class Attitude(object): """ Attitude information. @@ -126,6 +128,7 @@ class Attitude(object): :param yaw: Yaw in radians :param roll: Roll in radians """ + def __init__(self, pitch, yaw, roll): self.pitch = pitch self.yaw = yaw @@ -134,6 +137,7 @@ def __init__(self, pitch, yaw, roll): def __str__(self): return "Attitude:pitch=%s,yaw=%s,roll=%s" % (self.pitch, self.yaw, self.roll) + class LocationGlobal(object): """ A global location object. @@ -156,6 +160,7 @@ class LocationGlobal(object): :param lon: Longitude. :param alt: Altitude in meters relative to mean sea-level (MSL). """ + def __init__(self, lat, lon, alt=None): self.lat = lat self.lon = lon @@ -191,6 +196,7 @@ class LocationGlobalRelative(object): :param lon: Longitude. :param alt: Altitude in meters (relative to the home location). """ + def __init__(self, lat, lon, alt=None): self.lat = lat self.lon = lon @@ -217,6 +223,7 @@ class LocationLocal(object): :param east: Position east of the EKF origin in meters. :param down: Position down from the EKF origin in meters. (i.e. negative altitude in meters) """ + def __init__(self, north, east, down): self.north = north self.east = east @@ -225,6 +232,7 @@ def __init__(self, north, east, down): def __str__(self): return "LocationLocal:north=%s,east=%s,down=%s" % (self.north, self.east, self.down) + class GPSInfo(object): """ Standard information about GPS. @@ -238,6 +246,7 @@ class GPSInfo(object): .. todo:: FIXME: GPSInfo class - possibly normalize eph/epv? report fix type as string? """ + def __init__(self, eph, epv, fix_type, satellites_visible): self.eph = eph self.epv = epv @@ -247,6 +256,7 @@ def __init__(self, eph, epv, fix_type, satellites_visible): def __str__(self): return "GPSInfo:fix=%s,num_sat=%s" % (self.fix_type, self.satellites_visible) + class Battery(object): """ System battery information. @@ -255,6 +265,7 @@ class Battery(object): :param current: Battery current, in 10 * milliamperes. ``None`` if the autopilot does not support current measurement. :param level: Remaining battery energy. ``None`` if the autopilot cannot estimate the remaining battery. """ + def __init__(self, voltage, current, level): self.voltage = voltage / 1000.0 if current == -1: @@ -267,7 +278,9 @@ def __init__(self, voltage, current, level): self.level = level def __str__(self): - return "Battery:voltage={},current={},level={}".format(self.voltage, self.current, self.level) + return "Battery:voltage={},current={},level={}".format(self.voltage, self.current, + self.level) + class Rangefinder(object): """ @@ -276,6 +289,7 @@ class Rangefinder(object): :param distance: Distance (metres). ``None`` if the vehicle doesn't have a rangefinder. :param voltage: Voltage (volts). ``None`` if the vehicle doesn't have a rangefinder. """ + def __init__(self, distance, voltage): self.distance = distance self.voltage = voltage @@ -283,6 +297,7 @@ def __init__(self, distance, voltage): def __str__(self): return "Rangefinder: distance={}, voltage={}".format(self.distance, self.voltage) + class VehicleMode(object): """ This object is used to get and set the current "flight mode". @@ -328,6 +343,7 @@ def mode_callback(self, attr_name): The mode name, as a ``string``. """ + def __init__(self, name): self.name = name @@ -340,6 +356,7 @@ def __eq__(self, other): def __ne__(self, other): return self.name != other + class SystemStatus(object): """ This object is used to get and set the current "system status". @@ -348,6 +365,7 @@ class SystemStatus(object): The system state, as a ``string``. """ + def __init__(self, state): self.state = state @@ -360,6 +378,7 @@ def __eq__(self, other): def __ne__(self, other): return self.state != other + class HasObservers(object): def __init__(self): # A mapping from attr_name to a list of observers @@ -371,6 +390,7 @@ def __init__(self): The argument list for observer is ``observer(object, attr_name, attribute_value)``. """ + def add_attribute_listener(self, attr_name, observer): """ Add an attribute listener callback. @@ -444,7 +464,6 @@ def remove_attribute_listener(self, attr_name, observer): if len(l) == 0: del self._attribute_listeners[attr_name] - def notify_attribute_listeners(self, attr_name, value, cache=False): """ This method is used to update attribute observers when the named attribute is updated. @@ -515,14 +534,17 @@ def attitude_listener(self, name, msg): :param String attr_name: The name of the attribute to watch (or '*' to watch all attributes). :param observer: The callback to invoke when a change in the attribute is detected. """ + def decorator(fn): if isinstance(name, list): for n in name: self.add_attribute_listener(n, fn) else: self.add_attribute_listener(name, fn) + return decorator + class ChannelsOverride(dict): """ A dictionary class for managing Vehicle channel overrides. @@ -532,9 +554,10 @@ class ChannelsOverride(dict): For more information and examples see :ref:`example_channel_overrides`. """ + def __init__(self, vehicle): self._vehicle = vehicle - self._count = 8 # Fixed by MAVLink + self._count = 8 # Fixed by MAVLink self._active = True def __getitem__(self, key): @@ -563,7 +586,7 @@ def _send(self): if self._active: overrides = [0] * 8 for k, v in self.iteritems(): - overrides[int(k)-1] = v + overrides[int(k) - 1] = v self._vehicle._master.mav.rc_channels_override_send(0, 0, *overrides) @@ -668,6 +691,7 @@ def overrides(self, newch): self._overrides._active = True self._overrides._send() + class Locations(HasObservers): """ An object for holding location information in global, global relative and local frames. @@ -678,6 +702,7 @@ class Locations(HasObservers): The different frames are accessed through the members, which are created with this object. They can be read, and are observable. """ + def __init__(self, vehicle): super(Locations, self).__init__() @@ -689,16 +714,18 @@ def __init__(self, vehicle): @vehicle.on_message('GLOBAL_POSITION_INT') def listener(vehicle, name, m): (self._lat, self._lon) = (m.lat / 1.0e7, m.lon / 1.0e7) - self._relative_alt = m.relative_alt/1000.0 + self._relative_alt = m.relative_alt / 1000.0 self.notify_attribute_listeners('global_relative_frame', self.global_relative_frame) - vehicle.notify_attribute_listeners('location.global_relative_frame', vehicle.location.global_relative_frame) + vehicle.notify_attribute_listeners('location.global_relative_frame', + vehicle.location.global_relative_frame) if self._alt != None or m.alt != 0: # Require first alt value to be non-0 # TODO is this the proper check to do? - self._alt = m.alt/1000.0 + self._alt = m.alt / 1000.0 self.notify_attribute_listeners('global_frame', self.global_frame) - vehicle.notify_attribute_listeners('location.global_frame', vehicle.location.global_frame) + vehicle.notify_attribute_listeners('location.global_frame', + vehicle.location.global_frame) vehicle.notify_attribute_listeners('location', vehicle.location) @@ -746,7 +773,7 @@ def global_frame(self): Listeners are not notified of changes to this attribute until it has fully populated. """ return LocationGlobal(self._lat, self._lon, self._alt) - + @property def global_relative_frame(self): """ @@ -1027,7 +1054,7 @@ def listener(self, name, m): self._wpts_dirty = False self._commands = CommandSequence(self) - @self.on_message(['WAYPOINT_COUNT','MISSION_COUNT']) + @self.on_message(['WAYPOINT_COUNT', 'MISSION_COUNT']) def listener(self, name, msg): if not self._wp_loaded: self._wploader.clear() @@ -1077,28 +1104,30 @@ def listener(self, name, msg): self._params_loaded = False self._params_start = False self._params_map = {} - self._params_last = time.time() # Last new param. + self._params_last = time.time() # Last new param. self._params_duration = start_duration self._parameters = Parameters(self) @handler.forward_loop def listener(_): # Check the time duration for last "new" params exceeds watchdog. - if self._params_start: - if None not in self._params_set and not self._params_loaded: - self._params_loaded = True - self.notify_attribute_listeners('parameters', self.parameters) - - if not self._params_loaded and time.time() - self._params_last > self._params_duration: - c = 0 - for i, v in enumerate(self._params_set): - if v == None: - self._master.mav.param_request_read_send(0, 0, '', i) - c += 1 - if c > 50: - break - self._params_duration = repeat_duration - self._params_last = time.time() + if not self._params_start: + return + + if None not in self._params_set and not self._params_loaded: + self._params_loaded = True + self.notify_attribute_listeners('parameters', self.parameters) + + if not self._params_loaded and time.time() - self._params_last > self._params_duration: + c = 0 + for i, v in enumerate(self._params_set): + if v == None: + self._master.mav.param_request_read_send(0, 0, '', i) + c += 1 + if c > 50: + break + self._params_duration = repeat_duration + self._params_last = time.time() @self.on_message(['PARAM_VALUE']) def listener(self, name, msg): @@ -1108,7 +1137,7 @@ def listener(self, name, msg): self._params_loaded = False self._params_start = True self._params_count = msg.param_count - self._params_set = [None]*msg.param_count + self._params_set = [None] * msg.param_count # Attempt to set the params. We throw an error # if the index is out of range of the count or @@ -1120,7 +1149,8 @@ def listener(self, name, msg): self._params_duration = start_duration self._params_set[msg.param_index] = msg self._params_map[msg.param_id] = msg.param_value - self._parameters.notify_attribute_listeners(msg.param_id, msg.param_value, cache=True) + self._parameters.notify_attribute_listeners(msg.param_id, msg.param_value, + cache=True) except: import traceback traceback.print_exc() @@ -1140,16 +1170,20 @@ def listener(self, name, msg): def listener(_): # Send 1 heartbeat per second if time.time() - self._heartbeat_lastsent > 1: - self._master.mav.heartbeat_send(mavutil.mavlink.MAV_TYPE_GCS, mavutil.mavlink.MAV_AUTOPILOT_INVALID, 0, 0, 0) + self._master.mav.heartbeat_send(mavutil.mavlink.MAV_TYPE_GCS, + mavutil.mavlink.MAV_AUTOPILOT_INVALID, 0, 0, 0) self._heartbeat_lastsent = time.time() # Timeouts. if self._heartbeat_started: - 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) + 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) elif time.time() - self._heartbeat_lastreceived > self._heartbeat_warning: if self._heartbeat_timeout == False: - errprinter('>>> Link timeout, no heartbeat in last %s seconds' % self._heartbeat_warning) + errprinter('>>> Link timeout, no heartbeat in last %s seconds' % + self._heartbeat_warning) self._heartbeat_timeout = True @self.on_message(['HEARTBEAT']) @@ -1235,12 +1269,14 @@ def my_method(self, name, msg): :param String name: The name of the message to be intercepted by the decorated listener function (or '*' to get all messages). """ + def decorator(fn): if isinstance(name, list): for n in name: self.add_message_listener(n, fn) else: self.add_message_listener(name, fn) + return decorator def add_message_listener(self, name, fn): @@ -1416,7 +1452,7 @@ def rangefinder(self): @property def velocity(self): - return [ self._vx, self._vy, self._vz ] + return [self._vx, self._vy, self._vz] @property def attitude(self): @@ -1494,7 +1530,7 @@ def airspeed(self): @property def mount_status(self): - return [ self._mount_pitch, self._mount_yaw, self._mount_roll ] + return [self._mount_pitch, self._mount_yaw, self._mount_roll] @property def ekf_ok(self): @@ -1589,15 +1625,12 @@ def home_location(self, pos): # Send MAVLink update. self.send_mavlink(self.message_factory.command_long_encode( - 0, 0, # target system, target component - mavutil.mavlink.MAV_CMD_DO_SET_HOME, # command - 0, # confirmation - 2, # param 1: 1 to use current position, 2 to use the entered values. - 0, 0, 0, # params 2-4 - pos.lat, - pos.lon, - pos.alt - )) + 0, 0, # target system, target component + mavutil.mavlink.MAV_CMD_DO_SET_HOME, # command + 0, # confirmation + 2, # param 1: 1 to use current position, 2 to use the entered values. + 0, 0, 0, # params 2-4 + pos.lat, pos.lon, pos.alt)) @property def commands(self): @@ -1705,8 +1738,8 @@ def initialize(self, rate=4, heartbeat_timeout=30): # Initialize data stream. if rate != None: - self._master.mav.request_data_stream_send(0, 0, - mavutil.mavlink.MAV_DATA_STREAM_ALL, rate, 1) + self._master.mav.request_data_stream_send(0, 0, mavutil.mavlink.MAV_DATA_STREAM_ALL, + rate, 1) # Ensure initial parameter download has started. while True: @@ -1766,12 +1799,14 @@ def wait_ready(self, *types, **kwargs): time.sleep(0.1) if time.time() - start > timeout: if raise_exception: - raise APIException('wait_ready experienced a timeout after %s seconds.' % timeout) + raise APIException('wait_ready experienced a timeout after %s seconds.' % + timeout) else: return False return True + class Parameters(collections.MutableMapping, HasObservers): """ This object is used to get and set the values of named parameters for a vehicle. See the following links for information about @@ -1952,7 +1987,7 @@ def decorated_thr_min_callback(self, attr_name, value): :param String attr_name: The name of the parameter to watch (or '*' to watch all parameters). :param args: The callback to invoke when a change in the parameter is detected. - """ + """ attr_name = attr_name.upper() return super(Parameters, self).on_attribute(attr_name, *args, **kwargs) @@ -1998,6 +2033,7 @@ class Command(mavutil.mavlink.MAVLink_mission_item_message): """ pass + class CommandSequence(object): """ A sequence of vehicle waypoints (a "mission"). @@ -2084,10 +2120,8 @@ def takeoff(self, alt=None): altitude = float(alt) if math.isnan(alt) or math.isinf(alt): raise ValueError("Altitude was NaN or Infinity. Please provide a real number") - self._vehicle._master.mav.command_long_send(0, 0, - mavutil.mavlink.MAV_CMD_NAV_TAKEOFF, - 0, 0, 0, 0, 0, 0, 0, - altitude) + self._vehicle._master.mav.command_long_send(0, 0, mavutil.mavlink.MAV_CMD_NAV_TAKEOFF, + 0, 0, 0, 0, 0, 0, 0, altitude) def goto(self, location): ''' @@ -2113,11 +2147,10 @@ def goto(self, location): else: raise APIException('Expecting location to be LocationGlobal or LocationGlobalRelative.') - self._vehicle._master.mav.mission_item_send(0, 0, 0, - frame, - mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, - 2, 0, 0, 0, 0, 0, - location.lat, location.lon, location.alt) + self._vehicle._master.mav.mission_item_send(0, 0, 0, frame, + mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 2, 0, 0, + 0, 0, 0, location.lat, location.lon, + location.alt) def clear(self): ''' @@ -2159,7 +2192,7 @@ def upload(self): if self._vehicle._wpts_dirty: self._vehicle._master.waypoint_clear_all_send() if self._vehicle._wploader.count() > 0: - self._vehicle._wp_uploaded = [False]*self._vehicle._wploader.count() + self._vehicle._wp_uploaded = [False] * self._vehicle._wploader.count() self._vehicle._master.waypoint_count_send(self._vehicle._wploader.count()) while False in self._vehicle._wp_uploaded: time.sleep(0.1) @@ -2215,15 +2248,25 @@ def __setitem__(self, index, value): from dronekit.mavlink import MAVConnection -def connect(ip, _initialize=True, wait_ready=None, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200, heartbeat_timeout=30, source_system=255): + +def connect(ip, + _initialize=True, + wait_ready=None, + status_printer=errprinter, + vehicle_class=Vehicle, + rate=4, + baud=115200, + heartbeat_timeout=30, + source_system=255): handler = MAVConnection(ip, baud=baud, source_system=source_system) vehicle = vehicle_class(handler) if status_printer: + @vehicle.on_message('STATUSTEXT') def listener(self, name, m): status_printer(re.sub(r'(^|\n)', '>>> ', m.text.rstrip())) - + if _initialize: vehicle.initialize(rate=rate, heartbeat_timeout=heartbeat_timeout) diff --git a/dronekit/cloud/CloudClient.py b/dronekit/cloud/CloudClient.py index d04a79af8..4f663dad1 100644 --- a/dronekit/cloud/CloudClient.py +++ b/dronekit/cloud/CloudClient.py @@ -1,5 +1,6 @@ import requests + class CloudError(Exception): def __init__(self, type, message, response): self.type = type @@ -12,6 +13,7 @@ def __str__(self): def __repr__(self): return "%s(type=%s)" % (self.__class__.__name__, self.type) + class CloudClient(object): BASE_URL = 'http://api.droneshare.com/api/v1/' REST_CALLS = { @@ -40,6 +42,7 @@ def method(*args): else: action_url += "/%s/%s" % (str(args[0]), find_action[1]) return self._request(action_url, args[1:]) + return method def _request(self, url, data): diff --git a/dronekit/cloud/__init__.py b/dronekit/cloud/__init__.py index e69de29bb..8b1378917 100644 --- a/dronekit/cloud/__init__.py +++ b/dronekit/cloud/__init__.py @@ -0,0 +1 @@ + diff --git a/dronekit/mavlink.py b/dronekit/mavlink.py index d3abd1009..1986a4217 100644 --- a/dronekit/mavlink.py +++ b/dronekit/mavlink.py @@ -33,10 +33,7 @@ def read(self): class MAVConnection(object): - def __init__(self, ip, - baud=115200, - target_system=0, - source_system=255): + def __init__(self, ip, baud=115200, target_system=0, source_system=255): self.master = mavutil.mavlink_connection(ip, baud=baud, source_system=source_system) # TODO get rid of "master" object as exposed, @@ -49,9 +46,11 @@ def __init__(self, ip, # Monkey-patch MAVLink object for fix_targets. sendfn = self.master.mav.send + def newsendfn(mavmsg): self.fix_targets(mavmsg) return sendfn(mavmsg) + self.master.mav.send = newsendfn # Targets @@ -91,8 +90,7 @@ def mavlink_thread(): except socket.error as error: # If connection reset (closed), stop polling. if error.errno == ECONNABORTED: - raise APIException( - 'Connection aborting during read') + raise APIException('Connection aborting during read') raise except Empty: break @@ -106,8 +104,7 @@ def mavlink_thread(): except socket.error as error: # If connection reset (closed), stop polling. if error.errno == ECONNABORTED: - raise APIException( - 'Connection aborting during send') + raise APIException('Connection aborting during send') raise except Exception as e: # TODO this should be more rigorous. How to avoid @@ -123,7 +120,8 @@ def mavlink_thread(): try: fn(self, msg) except Exception as e: - errprinter('>>> Exception in message handler for %s' % msg.get_type()) + errprinter('>>> Exception in message handler for %s' % + msg.get_type()) errprinter('>>> ' + str(e)) except APIException as e: @@ -201,4 +199,3 @@ def callback(_, msg): self.out_queue.put(msg.pack(self.master.mav)) return target - diff --git a/dronekit/test/sitl/__init__.py b/dronekit/test/sitl/__init__.py index e69de29bb..8b1378917 100644 --- a/dronekit/test/sitl/__init__.py +++ b/dronekit/test/sitl/__init__.py @@ -0,0 +1 @@ + diff --git a/dronekit/test/sitl/test_110.py b/dronekit/test/sitl/test_110.py index c3ee2aea4..f2f9c7ab5 100644 --- a/dronekit/test/sitl/test_110.py +++ b/dronekit/test/sitl/test_110.py @@ -5,6 +5,7 @@ from dronekit.test import with_sitl from nose.tools import assert_equals + @with_sitl def test_110(connpath): vehicle = connect(connpath, wait_ready=True) @@ -18,7 +19,7 @@ def test_110(connpath): # Await armability. while not vehicle.is_armable: time.sleep(.1) - + # Change the vehicle into STABILIZE mode vehicle.mode = VehicleMode("GUIDED") @@ -28,6 +29,7 @@ def test_110(connpath): # Define example callback for mode def armed_callback(vehicle, attribute, value): armed_callback.called += 1 + armed_callback.called = 0 # When the same (event, callback) pair is passed to add_attribute_listener, @@ -61,6 +63,7 @@ def armed_callback(vehicle, attribute, value): time.sleep(3) # Ensure the callback was called zero times. - assert_equals(armed_callback.called, callcount, "Callback should not have been called once removed.") + assert_equals(armed_callback.called, callcount, + "Callback should not have been called once removed.") vehicle.close() diff --git a/dronekit/test/sitl/test_115.py b/dronekit/test/sitl/test_115.py index 19180ff3b..28f4a3f11 100644 --- a/dronekit/test/sitl/test_115.py +++ b/dronekit/test/sitl/test_115.py @@ -5,6 +5,7 @@ from dronekit.test import with_sitl from nose.tools import assert_equals + @with_sitl def test_115(connpath): v = connect(connpath, wait_ready=True) @@ -12,6 +13,7 @@ def test_115(connpath): # Dummy callback def mavlink_callback(*args): mavlink_callback.count += 1 + mavlink_callback.count = 0 # Set the callback. diff --git a/dronekit/test/sitl/test_12.py b/dronekit/test/sitl/test_12.py index e89e6a7ed..d2c55a15c 100644 --- a/dronekit/test/sitl/test_12.py +++ b/dronekit/test/sitl/test_12.py @@ -5,9 +5,11 @@ from dronekit.test import with_sitl from nose.tools import assert_equals + def current_milli_time(): return int(round(time.time() * 1000)) + @with_sitl def test_timeout(connpath): v = connect(connpath, wait_ready=True) @@ -25,6 +27,6 @@ def test_timeout(connpath): # Checks that time to set parameter was <1s # see https://github.com/dronekit/dronekit-python/issues/12 - assert end - start < 1000, 'time to set parameter was %s, over 1s' % (end - start,) + assert end - start < 1000, 'time to set parameter was %s, over 1s' % (end - start, ) v.close() diff --git a/dronekit/test/sitl/test_channels.py b/dronekit/test/sitl/test_channels.py index fb3d95e9e..73132d3ab 100644 --- a/dronekit/test/sitl/test_channels.py +++ b/dronekit/test/sitl/test_channels.py @@ -4,6 +4,7 @@ from dronekit.test import with_sitl from nose.tools import assert_equals, assert_not_equals + def assert_readback(vehicle, values): i = 10 while i > 0: @@ -16,6 +17,7 @@ def assert_readback(vehicle, values): if i <= 0: raise Exception('Did not match in channels readback %s' % values) + @with_sitl def test_timeout(connpath): vehicle = connect(connpath, wait_ready=True) @@ -42,7 +44,7 @@ def test_timeout(connpath): assert_equals(type(vehicle.channels[6]), int) assert_equals(type(vehicle.channels[7]), int) assert_equals(type(vehicle.channels[8]), int) - + vehicle.channels.overrides = {'1': 1010} assert_readback(vehicle, {'1': 1010}) @@ -61,7 +63,7 @@ def test_timeout(connpath): vehicle.channels.overrides['1'] = None assert_readback(vehicle, {'1': 1500, '2': 1500}) - #test + #test try: vehicle.channels['9'] assert False, "Can read over end of channels" @@ -93,27 +95,27 @@ def test_timeout(connpath): assert_readback(vehicle, {'1': 1500, '2': 1010}) # Set Ch3,4,5,6,7 to 300,400-700 respectively - vehicle.channels.overrides = {'3': 300, '4':400, '5':500,'6':600,'7':700} - assert_readback(vehicle, {'3': 300, '4':400, '5':500,'6':600,'7':700}) + vehicle.channels.overrides = {'3': 300, '4': 400, '5': 500, '6': 600, '7': 700} + assert_readback(vehicle, {'3': 300, '4': 400, '5': 500, '6': 600, '7': 700}) # Set Ch8 to 800 using braces vehicle.channels.overrides = {'8': 800} - assert_readback(vehicle, {'8':800}) + assert_readback(vehicle, {'8': 800}) # Set Ch8 to 800 using brackets vehicle.channels.overrides['8'] = 810 - assert_readback(vehicle, {'8':810}) + assert_readback(vehicle, {'8': 810}) - try: + try: # Try to write channel 9 override to a value with brackets - vehicle.channels.overrides['9']=900 + vehicle.channels.overrides['9'] = 900 assert False, "can write channels.overrides 9" except: pass - try: + try: # Try to write channel 9 override to a value with braces - vehicle.channels.overrides={'9': 900} + vehicle.channels.overrides = {'9': 900} assert False, "can write channels.overrides 9 with braces" except: pass @@ -131,16 +133,18 @@ def test_timeout(connpath): assert_equals(len(vehicle.channels.overrides.keys()), 0) # Set Ch2 to 33, clear channel 6 - vehicle.channels.overrides = {'2': 33, '6':None} - assert_readback(vehicle, {'2':33, '6': 1500}) + vehicle.channels.overrides = {'2': 33, '6': None} + assert_readback(vehicle, {'2': 33, '6': 1500}) assert_equals(vehicle.channels.overrides.keys(), ['2']) # Callbacks result = {'success': False} vehicle.channels.overrides = {} + def channels_callback(vehicle, name, channels): if channels['3'] == 55: result['success'] = True + vehicle.add_attribute_listener('channels', channels_callback) vehicle.channels.overrides = {'3': 55} diff --git a/dronekit/test/sitl/test_earlyattrs.py b/dronekit/test/sitl/test_earlyattrs.py index febd08fbe..91ec2c97b 100644 --- a/dronekit/test/sitl/test_earlyattrs.py +++ b/dronekit/test/sitl/test_earlyattrs.py @@ -6,6 +6,7 @@ from dronekit.test import with_sitl from nose.tools import assert_equals, assert_not_equals + @with_sitl def test_battery_none(connpath): vehicle = connect(connpath, _initialize=False) diff --git a/dronekit/test/sitl/test_goto.py b/dronekit/test/sitl/test_goto.py index 5dc67cd78..e40f5f746 100644 --- a/dronekit/test/sitl/test_goto.py +++ b/dronekit/test/sitl/test_goto.py @@ -12,6 +12,7 @@ from dronekit.test import with_sitl from nose.tools import assert_equals + @with_sitl def test_goto(connpath): vehicle = connect(connpath, wait_ready=True) @@ -53,7 +54,7 @@ def arm_and_takeoff(aTargetAltitude): assert_equals(vehicle.armed, True) # Take off to target altitude - vehicle.commands.takeoff(aTargetAltitude) + vehicle.commands.takeoff(aTargetAltitude) # Wait until the vehicle reaches a safe height before # processing the goto (otherwise the command after @@ -61,7 +62,7 @@ def arm_and_takeoff(aTargetAltitude): while True: # print " Altitude: ", vehicle.location.alt # Test for altitude just below target, in case of undershoot. - if vehicle.location.global_frame.alt >= aTargetAltitude * 0.95: + if vehicle.location.global_frame.alt >= aTargetAltitude * 0.95: # print "Reached target altitude" break diff --git a/dronekit/test/sitl/test_locations.py b/dronekit/test/sitl/test_locations.py index a7c48327b..648499428 100644 --- a/dronekit/test/sitl/test_locations.py +++ b/dronekit/test/sitl/test_locations.py @@ -3,6 +3,7 @@ from dronekit.test import with_sitl from nose.tools import assert_equals, assert_not_equals + @with_sitl def test_timeout(connpath): vehicle = connect(connpath, wait_ready=True) @@ -44,7 +45,7 @@ def arm_and_takeoff(aTargetAltitude): assert_equals(vehicle.armed, True) # Take off to target altitude - vehicle.commands.takeoff(aTargetAltitude) + vehicle.commands.takeoff(aTargetAltitude) # Wait until the vehicle reaches a safe height before # processing the goto (otherwise the command after @@ -52,7 +53,7 @@ def arm_and_takeoff(aTargetAltitude): while True: # print " Altitude: ", vehicle.location.alt # Test for altitude just below target, in case of undershoot. - if vehicle.location.global_frame.alt >= aTargetAltitude * 0.95: + if vehicle.location.global_frame.alt >= aTargetAltitude * 0.95: # print "Reached target altitude" break @@ -61,7 +62,7 @@ def arm_and_takeoff(aTargetAltitude): arm_and_takeoff(10) vehicle.wait_ready('location.local_frame', timeout=60) - + # .north, .east, and .down are initialized to None. # Any other value suggests that a LOCAL_POSITION_NED was received and parsed. assert_not_equals(vehicle.location.local_frame.north, None) @@ -78,11 +79,13 @@ def arm_and_takeoff(aTargetAltitude): vehicle.close() + @with_sitl def test_location_notify(connpath): vehicle = connect(connpath) ret = {'success': False} + @vehicle.location.on_attribute('global_frame') def callback(*args): assert_not_equals(args[2].alt, 0) diff --git a/dronekit/test/sitl/test_mavlink.py b/dronekit/test/sitl/test_mavlink.py index 35d156045..972c8ac8b 100644 --- a/dronekit/test/sitl/test_mavlink.py +++ b/dronekit/test/sitl/test_mavlink.py @@ -5,6 +5,7 @@ from dronekit.test import with_sitl from nose.tools import assert_not_equals, assert_equals + @with_sitl def test_mavlink(connpath): vehicle = connect(connpath) @@ -15,9 +16,10 @@ def test_mavlink(connpath): vehicle2 = connect('udpout:localhost:15668') result = {'success': False} + @vehicle2.on_attribute('location') def callback(*args): - result['success'] = True + result['success'] = True i = 20 while not result['success'] and i > 0: diff --git a/dronekit/test/sitl/test_parameters.py b/dronekit/test/sitl/test_parameters.py index c1c74f0e6..ecd7b75d9 100644 --- a/dronekit/test/sitl/test_parameters.py +++ b/dronekit/test/sitl/test_parameters.py @@ -5,6 +5,7 @@ from dronekit.test import with_sitl from nose.tools import assert_equals, assert_not_equals + @with_sitl def test_parameters(connpath): vehicle = connect(connpath) @@ -14,7 +15,7 @@ def test_parameters(connpath): # With wait_ready, it should not be none. assert_not_equals(vehicle.parameters.get('THR_MIN', wait_ready=True), None) - + try: assert_not_equals(vehicle.parameters['THR_MIN'], None) except: @@ -25,6 +26,7 @@ def test_parameters(connpath): vehicle.close() + @with_sitl def test_iterating(connpath): vehicle = connect(connpath, wait_ready=True) @@ -37,13 +39,14 @@ def test_iterating(connpath): vehicle.close() + @with_sitl def test_setting(connpath): vehicle = connect(connpath, wait_ready=True) assert_not_equals(vehicle.parameters['THR_MIN'], None) - result = { 'success': False } + result = {'success': False} @vehicle.parameters.on_attribute('THR_MIN') def listener(self, name, value): diff --git a/dronekit/test/sitl/test_simpledemo.py b/dronekit/test/sitl/test_simpledemo.py index ec3dc170b..0f8319d12 100644 --- a/dronekit/test/sitl/test_simpledemo.py +++ b/dronekit/test/sitl/test_simpledemo.py @@ -10,6 +10,7 @@ from dronekit.test import with_sitl from nose.tools import assert_equals + # This test runs first! @with_sitl def test_parameter(connpath): @@ -20,6 +21,7 @@ def test_parameter(connpath): v.close() + # This test runs second. Add as many tests as you like @with_sitl def test_mode(connpath): diff --git a/dronekit/test/sitl/test_state.py b/dronekit/test/sitl/test_state.py index e14f8ea16..8f6502856 100644 --- a/dronekit/test/sitl/test_state.py +++ b/dronekit/test/sitl/test_state.py @@ -6,6 +6,7 @@ from dronekit.test import with_sitl from nose.tools import assert_equals + @with_sitl def test_state(connpath): vehicle = connect(connpath, wait_ready=['system_status']) diff --git a/dronekit/test/sitl/test_timeout.py b/dronekit/test/sitl/test_timeout.py index fe310be55..b6d539682 100644 --- a/dronekit/test/sitl/test_timeout.py +++ b/dronekit/test/sitl/test_timeout.py @@ -6,6 +6,7 @@ from dronekit.test import with_sitl from nose.tools import assert_equals + @with_sitl def test_timeout(connpath): # Connect with timeout of 10s. @@ -22,6 +23,7 @@ def test_timeout(connpath): vehicle.close() + def test_timeout_empty(): # Create a dummy server. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) diff --git a/dronekit/test/sitl/test_vehicleclass.py b/dronekit/test/sitl/test_vehicleclass.py index 3f88342f1..b7d386eed 100644 --- a/dronekit/test/sitl/test_vehicleclass.py +++ b/dronekit/test/sitl/test_vehicleclass.py @@ -3,20 +3,24 @@ from dronekit.test import with_sitl from nose.tools import assert_equals + class DummyVehicle(Vehicle): - def __init__(self, *args): - super(DummyVehicle, self).__init__(*args) + def __init__(self, *args): + super(DummyVehicle, self).__init__(*args) + + self.success = False + + def success_fn(self, name, m): + self.success = True + + self.add_message_listener('HEARTBEAT', success_fn) - self.success = False - def success_fn(self, name, m): - self.success = True - self.add_message_listener('HEARTBEAT', success_fn) @with_sitl def test_timeout(connpath): v = connect(connpath, vehicle_class=DummyVehicle) while not v.success: - time.sleep(0.1) + time.sleep(0.1) v.close() diff --git a/dronekit/test/sitl/test_waypoints.py b/dronekit/test/sitl/test_waypoints.py index 27abf327f..61976fbbd 100644 --- a/dronekit/test/sitl/test_waypoints.py +++ b/dronekit/test/sitl/test_waypoints.py @@ -5,6 +5,7 @@ from dronekit.test import with_sitl from nose.tools import assert_not_equals, assert_equals + @with_sitl def test_empty_clear(connpath): vehicle = connect(connpath) @@ -17,6 +18,7 @@ def test_empty_clear(connpath): vehicle.close() + @with_sitl def test_set_home(connpath): vehicle = connect(connpath, wait_ready=True) @@ -39,13 +41,14 @@ def test_set_home(connpath): assert_equals(vehicle.home_location.lon, 149) assert_equals(vehicle.home_location.alt, 600) + @with_sitl def test_parameter(connpath): vehicle = connect(connpath, wait_ready=True) # Home should be None at first. assert_equals(vehicle.home_location, None) - + # Wait for home position to be real and not 0, 0, 0 # once we request it via cmds.download() time.sleep(10) @@ -114,6 +117,7 @@ def test_parameter(connpath): vehicle.close() + @with_sitl def test_227(connpath): """ @@ -125,13 +129,13 @@ def test_227(connpath): def assert_commands(count): vehicle.commands.download() vehicle.commands.wait_ready() - assert_equals(len(vehicle.commands), count) + assert_equals(len(vehicle.commands), count) assert_commands(0) - vehicle.commands.add(Command( 0, 0, 0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, - mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, - 0, 0, 0, 0, 10, 10, 10)) - vehicle.flush() # Send commands + vehicle.commands.add(Command(0, 0, 0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, + mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0, 10, 10, + 10)) + vehicle.flush() # Send commands assert_commands(1) diff --git a/dronekit/test/unit/__init__.py b/dronekit/test/unit/__init__.py index e69de29bb..8b1378917 100644 --- a/dronekit/test/unit/__init__.py +++ b/dronekit/test/unit/__init__.py @@ -0,0 +1 @@ + diff --git a/dronekit/test/unit/test_api.py b/dronekit/test/unit/test_api.py index 6a9f5dec0..a7224e4a8 100644 --- a/dronekit/test/unit/test_api.py +++ b/dronekit/test/unit/test_api.py @@ -3,8 +3,10 @@ from dronekit import VehicleMode from nose.tools import assert_equals, assert_not_equals + def test_vehicle_mode_eq(): assert_equals(VehicleMode('GUIDED'), VehicleMode('GUIDED')) + def test_vehicle_mode_neq(): assert_not_equals(VehicleMode('AUTO'), VehicleMode('GUIDED')) diff --git a/dronekit/util.py b/dronekit/util.py index 5cfb21600..f5800985b 100644 --- a/dronekit/util.py +++ b/dronekit/util.py @@ -1,6 +1,7 @@ from __future__ import print_function import sys + def errprinter(*args): print(*args, file=sys.stderr) sys.stderr.flush() From b5e9db830e4a1d6fa118b0fcbba28d01a13a1054 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 18 Nov 2015 11:27:12 -0800 Subject: [PATCH 223/475] 2.0.0rc13 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 20268ccfd..218721f38 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.0.0rc12' +version = '2.0.0rc13' setup(name='dronekit', zip_safe=True, From da765214ce00b5b9ef0fc5d05e674767aee4b6b6 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 19 Nov 2015 12:18:39 +1100 Subject: [PATCH 224/475] Move Vehicle docs alongside properties. Tidy up descriptions. Make linking consistent --- dronekit/__init__.py | 413 ++++++++++++++++++++++--------------------- 1 file changed, 215 insertions(+), 198 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 9b22a69b2..d1fa0d0bb 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -2,8 +2,8 @@ """ This is the API Reference for the DroneKit-Python API. -The main API is the :py:class:`Vehicle ` class. -The code snippet below shows how to use :py:func:`connect` to obtain an instance a connected vehicle: +The main API is the :py:class:`Vehicle` class. +The code snippet below shows how to use :py:func:`connect` to obtain an instance of a connected vehicle: .. code:: python @@ -12,73 +12,22 @@ # Connect to the Vehicle using "connection string" (in this case an address on network) vehicle = connect('127.0.0.1:14550', wait_ready=True) -:py:class:`Vehicle ` provides access to vehicle *state* through python attributes -(e.g. :py:attr:`Vehicle.mode `) -and to settings/parameters though the :py:attr:`Vehicle.parameters ` attribute. -Asynchronous notification on vehicle attribute changes is available by registering observers. +:py:class:`Vehicle` provides access to vehicle *state* through python attributes +(e.g. :py:attr:`Vehicle.mode`) +and to settings/parameters though the :py:attr:`Vehicle.parameters` attribute. +Asynchronous notification on vehicle attribute changes is available by registering listeners/observers. -:py:class:`Vehicle ` provides two main ways to control vehicle movement and other operations: +Vehicle movement is primarily controlled using the :py:attr:`Vehicle.armed` attribute and +:py:func:`Vehicle.commands.takeoff() ` and +:py:attr:`Vehicle.commands.goto() ` in GUIDED mode. +Control over speed, direction, altitude, camera trigger and any other aspect of the vehicle is supported using custom MAVLink messages +(:py:func:`Vehicle.send_mavlink`, :py:func:`Vehicle.message_factory`). -* Direct control of movement outside of missions is also supported. To set a target position you can use - :py:func:`CommandSequence.goto `. - Control over speed, direction, altitude, camera trigger and any other aspect of the vehicle is supported using custom MAVLink messages - (:py:func:`Vehicle.send_mavlink `, :py:func:`Vehicle.message_factory `). -* Missions are downloaded and uploaded through the :py:attr:`Vehicle.commands ` attribute - (see :py:class:`CommandSequence ` for more information). +It is also possible to work with vehicle "missions" using the :py:attr:`Vehicle.commands` attribute, and run them in AUTO mode. A number of other useful classes and methods are listed below. ---- - -.. py:function:: connect(ip, wait_ready=None, status_printer=errprinter, vehicle_class=Vehicle, rate=4, baud=115200, heartbeat_timeout=30, source_system=255) - - Returns a :py:class:`Vehicle` object connected to the address specified by string parameter ``ip``. - Connection string parameters (``ip``) for different targets are listed in the :ref:`getting started guide `. - - The method is usually called with ``wait_ready=True`` to ensure that vehicle parameters and (most) attributes are - available when ``connect()`` returns. - - .. code:: python - - from dronekit import connect - - # Connect to the Vehicle using "connection string" (in this case an address on network) - vehicle = connect('127.0.0.1:14550', wait_ready=True) - - :param String ip: :ref:`Connection string ` for target address - e.g. 127.0.0.1:14550. - - :param Bool/Array wait_ready: If ``True`` wait until all default attributes have downloaded before - the method returns (default is ``None``). - The default attributes to wait on are: :py:attr:`parameters`, :py:attr:`gps_0`, - :py:attr:`armed`, :py:attr:`mode`, and :py:attr:`attitude`. - - You can also specify a named set of parameters to wait on (e.g. ``wait_ready=['system_status','mode']``). - - For more information see :py:func:`Vehicle.wait_ready `. - - :param status_printer: Method of signature ``def status_printer(txt)`` that prints - STATUS_TEXT messages from the Vehicle and other diagnostic information. - By default the status information is printed to the command prompt in which the script is running. - :param Vehicle vehicle_class: The class that will be instantiated by the ``connect()`` method. - This can be any sub-class of ``Vehicle`` (and defaults to ``Vehicle``). - :param int rate: Data stream refresh rate. The default is 4Hz (4 updates per second). - :param int baud: The baud rate for the connection. The default is 115200. - :param int heartbeat_timeout: Connection timeout value in seconds (default is 30s). - If a heartbeat is not detected within this time an exception will be raised. - :param int source_system: The MAVLink ID of the :py:class:`Vehicle` object returned by this method (by default 255). - - .. note:: - - The returned :py:class:`Vehicle` object is acting as like a ground control station from the - perspective of the connected "real" vehicle. It will process/receive messages from the real vehicle - if they are addressed to this ``source_system`` id. Messages sent to the real vehicle are - automatically updated to use the vehicle's ``target_system`` id. - - It is *good practice* to assign a unique id for every system on the MAVLink network. - It is possible to configure the autopilot to only respond to guided-mode commands from a specified GCS ID. - - - :returns: A connected vehicle of the type defined in ``vehicle_class`` (a superclass of :py:class:`Vehicle`). """ from __future__ import print_function @@ -116,6 +65,8 @@ def __init__(self, message): class Attitude(object): """ Attitude information. + + An object of this type is returned by :py:attr:`Vehicle.attitude`. .. figure:: http://upload.wikimedia.org/wikipedia/commons/thumb/c/c1/Yaw_Axis_Corrected.svg/500px-Yaw_Axis_Corrected.svg.png :width: 400px @@ -260,6 +211,8 @@ def __str__(self): class Battery(object): """ System battery information. + + An object of this type is returned by :py:attr:`Vehicle.battery`. :param voltage: Battery voltage in millivolts. :param current: Battery current, in 10 * milliamperes. ``None`` if the autopilot does not support current measurement. @@ -285,6 +238,8 @@ def __str__(self): class Rangefinder(object): """ Rangefinder readings. + + An object of this type is returned by :py:attr:`Vehicle.rangefinder`. :param distance: Distance (metres). ``None`` if the vehicle doesn't have a rangefinder. :param voltage: Voltage (volts). ``None`` if the vehicle doesn't have a rangefinder. @@ -312,12 +267,12 @@ class VehicleMode(object): when using manual modes as these may require remote control input from the user. The available set of supported flight modes is vehicle-specific (see - `Copter `_, - `Plane `_, - `Rover `_). If an unsupported mode is set the script + `Copter Modes `_, + `Plane Modes `_, + `Rover Modes `_). If an unsupported mode is set the script will raise a ``KeyError`` exception. - The :py:attr:`Vehicle.mode ` attribute can be queried for the current mode. + The :py:attr:`Vehicle.mode` attribute can be queried for the current mode. The code snippet below shows how to observe changes to the mode and then read the value: .. code:: python @@ -336,7 +291,7 @@ def mode_callback(self, attr_name): # Set the vehicle into auto mode vehicle.mode = VehicleMode("AUTO") - For more information on getting/setting/observing the :py:attr:`Vehicle.mode ` + For more information on getting/setting/observing the :py:attr:`Vehicle.mode` (and other attributes) see the :ref:`attributes guide `. .. py:attribute:: name @@ -360,6 +315,8 @@ def __ne__(self, other): class SystemStatus(object): """ This object is used to get and set the current "system status". + + An object of this type is returned by :py:attr:`Vehicle.system_status`. .. py:attribute:: state @@ -385,11 +342,7 @@ def __init__(self): self._attribute_listeners = {} self._attribute_cache = {} - """ - Provides callback based notification on attribute changes. - The argument list for observer is ``observer(object, attr_name, attribute_value)``. - """ def add_attribute_listener(self, attr_name, observer): """ @@ -398,8 +351,8 @@ def add_attribute_listener(self, attr_name, observer): The callback function (``observer``) is invoked differently depending on the *type of attribute*. Attributes that represent sensor values or which are used to monitor connection status are updated whenever a message is received from the vehicle. Attributes which reflect vehicle "state" are - only updated when their values change (for example :py:func:`Vehicle.system_status `, - :py:attr:`Vehicle.armed `, and :py:attr:`Vehicle.mode `). + only updated when their values change (for example :py:attr:`Vehicle.system_status`, + :py:attr:`Vehicle.armed`, and :py:attr:`Vehicle.mode`). The callback can be removed using :py:func:`remove_attribute_listener`. @@ -409,7 +362,7 @@ def add_attribute_listener(self, attr_name, observer): a more elegant syntax. Use ``add_attribute_listener`` by preference if you will need to remove the observer. - The callback arguments are: + The argument list for the callback is ``observer(object, attr_name, attribute_value)``: * ``self`` - the associated :py:class:`Vehicle`. This may be compared to a global vehicle handle to implement vehicle-specific callback handling (if needed). @@ -504,10 +457,10 @@ def on_attribute(self, name): The decorated function (``observer``) is invoked differently depending on the *type of attribute*. Attributes that represent sensor values or which are used to monitor connection status are updated whenever a message is received from the vehicle. Attributes which reflect vehicle "state" are - only updated when their values change (for example :py:func:`Vehicle.system_status `, - :py:attr:`Vehicle.armed `, and :py:attr:`Vehicle.mode `). + only updated when their values change (for example :py:func:`Vehicle.system_status`, + :py:attr:`Vehicle.armed`, and :py:attr:`Vehicle.mode`). - The callback arguments are: + The argument list for the callback is ``observer(object, attr_name, attribute_value)`` * ``self`` - the associated :py:class:`Vehicle`. This may be compared to a global vehicle handle to implement vehicle-specific callback handling (if needed). @@ -552,6 +505,8 @@ class ChannelsOverride(dict): Channels can be read, written, or cleared by index or using a dictionary syntax. To clear a value, set it to ``None`` or use ``del`` on the item. + An object of this type is returned by :py:attr:`Vehicle.channels.overrides `. + For more information and examples see :ref:`example_channel_overrides`. """ @@ -747,7 +702,7 @@ def local_frame(self): """ Location in local NED frame (a :py:class:`LocationGlobalRelative`). - This is accessed through the :py:attr:`Vehicle.location ` attribute: + This is accessed through the :py:attr:`Vehicle.location` attribute: .. code-block:: python @@ -760,17 +715,33 @@ def local_frame(self): @property def global_frame(self): """ - Location in global frame (a :py:class:`LocationGlobal`). + Location in global frame (a :py:class:`LocationGlobal`). - This is accessed through the :py:attr:`Vehicle.location ` attribute: + The latitude and longitude are relative to the + `WGS84 coordinate system `_. + The altitude is relative to mean sea-level (MSL). + + This is accessed through the :py:attr:`Vehicle.location` attribute: .. code-block:: python print "Global Location: %s" % vehicle.location.global_frame + print "Sea level altitude is: %s" % vehicle.location.global_frame.alt Its ``lat`` and ``lon`` attributes are populated shortly after GPS becomes available. The ``alt`` can take several seconds longer to populate (from the barometer). - Listeners are not notified of changes to this attribute until it has fully populated. + Listeners are not notified of changes to this attribute until it has fully populated. + + To watch for changes you can use :py:func:`Vehicle.on_attribute` decorator or + :py:func:`add_attribute_listener` (decorator approach shown below): + + .. code-block:: python + + @vehicle.on_attribute('location.global_frame') + def listener(self, attr_name, value): + print " Global: %s" % value + + #Alternatively, use decorator: ``@vehicle.location.on_attribute('global_frame')``. """ return LocationGlobal(self._lat, self._lon, self._alt) @@ -780,107 +751,57 @@ def global_relative_frame(self): Location in global frame, with altitude relative to the home location (a :py:class:`LocationGlobalRelative`). - This is accessed through the :py:attr:`Vehicle.location ` attribute: + The latitude and longitude are relative to the + `WGS84 coordinate system `_. + The altitude is relative to :py:attr:`home location `. + + This is accessed through the :py:attr:`Vehicle.location` attribute: .. code-block:: python print "Global Location (relative altitude): %s" % vehicle.location.global_relative_frame + print "Altitude relative to home_location: %s" % vehicle.location.global_relative_frame.alt """ return LocationGlobalRelative(self._lat, self._lon, self._relative_alt) class Vehicle(HasObservers): """ - The main vehicle API - - Asynchronous notification on change of vehicle state is available by registering observers (callbacks) for attribute changes. - - Most vehicle state is exposed through python attributes (e.g. ``vehicle.location``). Most of these attributes are - auto-populated based on the capabilities of the connected autopilot/vehicle. - - Particular autopilots/vehicles may define different attributes from this standard list (extra batteries, GPIOs, etc.) - However if a standard attribute is defined it must follow the rules specified below. - - **Autopilot specific attributes & types:** - - To prevent name clashes the following naming convention should be used: - - * ``ap_`` - For autopilot specific parameters (apm 2.5, pixhawk etc.). For example "ap_pin5_mode" and "ap_pin5_value". - * ``user_`` - For user specific parameters - - **Standard attributes & types:** - - .. py:attribute:: attitude - - Current vehicle :py:class:`Attitude` (pitch, yaw, roll). - - .. py:attribute:: velocity - - Current velocity as a three element list ``[ vx, vy, vz ]`` (in meter/sec). - - .. py:attribute:: mode - - This attribute is used to get and set the current flight mode (:py:class:`VehicleMode`). - - .. py:attribute:: airspeed - - Current airspeed in metres/second (``double``). - - .. todo:: FIXME: Should airspeed value move somewhere else from "Standard attributes & types" table? - - .. py:attribute:: groundspeed - - Groundspeed in metres/second (``double``). - - .. py:attribute:: gps_0 - - GPS position information (:py:class:`GPSInfo`). - - .. py:attribute:: armed - - This attribute can be used to get and set the ``armed`` state of the vehicle (``boolean``). - - The code below shows how to read the state, and to arm/disam the vehicle: - - .. code:: python - - # Print the armed state for the vehicle - print "Armed: %s" % vehicle.armed - - # Disarm the vehicle - vehicle.armed = False - - # Arm the vehicle - vehicle.armed = True - - .. py:attribute:: mount_status - - Current status of the camera mount (gimbal) as a three element list: ``[ pitch, yaw, roll ]``. - - The values in the list are set to ``None`` if no mount is configured. - - .. py:attribute:: battery - - Current system :py:class:`Battery` status. - - .. py:attribute:: rangefinder - - :py:class:`Rangefinder` distance and voltage values. - - - - **Autopilot specific attributes & types:** - - .. py:attribute:: ap_pin5_mode - - string (adc, dout, din) - - .. py:attribute:: ap_pin5_value - - ? double (0, 1, 2.3 etc...) - - .. todo:: Add waypoint_home attribute IF this is added: https://github.com/dronekit/dronekit-python/issues/105 + The main vehicle API. + + Vehicle state is exposed through 'attributes' (e.g. :py:attr:`heading`). All attributes can be + read, and some are also settable + (:py:attr:`mode`, :py:attr:`armed` and :py:attr:`home_location`). + + Attributes can also be asynchronously monitored for changes by registering listener callback + functions. + + Vehicle "settings" (parameters) are read/set using the :py:attr:`parameters` attribute. + Parameters can be iterated and are also individually observable. + + Vehicle movement is primarily controlled using the :py:attr:`armed` attribute and + :py:func:`Vehicle.commands.takeoff() ` and + :py:func:`Vehicle.commands.goto() ` in GUIDED mode. + + It is also possible to work with vehicle "missions" using the :py:attr:`commands` attribute, + and run them in AUTO mode. + + The guide contains more detailed information on the different ways you can use + the ``Vehicle`` class: + + - :doc:`guide/vehicle_state_and_parameters` + - :doc:`guide/copter/guided_mode` + - :doc:`guide/auto_mode` + + .. note:: + + This class currently exposes just the attributes that are most commonly used by all + vehicle types. if you need to add additional attributes then subclass ``Vehicle`` + as demonstrated in :doc:`examples/create_attribute`. + + Please then :doc:`contribute ` your additions back + to the project! """ def __init__(self, handler): @@ -1351,7 +1272,8 @@ def flush(self): .. warning:: - This has been replaced by :py:func:`Vehicle.commands.upload() `. + This method is deprecated. It has been replaced by + :py:func:`Vehicle.commands.upload() `. """ return self.commands.upload() @@ -1369,6 +1291,9 @@ def _mode_mapping(self): @property def mode(self): + """ + This attribute is used to get and set the current flight mode (:py:class:`VehicleMode`). + """ if not self._flightmode: return None return VehicleMode(self._flightmode) @@ -1380,14 +1305,13 @@ def mode(self, v): @property def location(self): """ - A :py:class:`Locations` object containing vehicle location information in - global, global relative and local frames. + The vehicle location in global, global relative and local frames (:py:class:`Locations`). The different frames are accessed through its members: - * :py:attr:`global_frame ` (a :py:class:`LocationGlobal`) - * :py:attr:`global_relative_frame ` (a :py:class:`LocationGlobalRelative`) - * :py:attr:`local_frame ` (a :py:class:`LocationLocal`) + * :py:attr:`global_frame ` (:py:class:`LocationGlobal`) + * :py:attr:`global_relative_frame ` (:py:class:`LocationGlobalRelative`) + * :py:attr:`local_frame ` (:py:class:`LocationLocal`) For example, to print the location in each frame for a ``vehicle``: @@ -1442,28 +1366,59 @@ def listener(self, attr_name, value): @property def battery(self): + """ + Current system batter status (:py:class:`Battery`). + """ if self._voltage == None or self._current == None or self._level == None: return None return Battery(self._voltage, self._current, self._level) @property def rangefinder(self): + """ + Rangefinder distance and voltage values (:py:class:`Rangefinder`). + """ return Rangefinder(self._rngfnd_distance, self._rngfnd_voltage) @property def velocity(self): + """ + Current velocity as a three element list ``[ vx, vy, vz ]`` (in meter/sec). + """ return [self._vx, self._vy, self._vz] @property def attitude(self): + """ + Current vehicle attitude - pitch, yaw, roll (:py:class:`Attitude`). + """ return Attitude(self._pitch, self._yaw, self._roll) @property def gps_0(self): + """ + GPS position information (:py:class:`GPSInfo`). + """ return GPSInfo(self._eph, self._epv, self._fix_type, self._satellites_visible) @property def armed(self): + """ + This attribute can be used to get and set the ``armed`` state of the vehicle (``boolean``). + + The code below shows how to read the state, and to arm/disam the vehicle: + + .. code:: python + + # Print the armed state for the vehicle + print "Armed: %s" % vehicle.armed + + # Disarm the vehicle + vehicle.armed = False + + # Arm the vehicle + vehicle.armed = True + """ return self._armed @armed.setter @@ -1477,7 +1432,7 @@ def armed(self, value): @property def is_armable(self): """ - Returns ``True`` if the vehicle is ready to arm, false otherwise. + Returns ``True`` if the vehicle is ready to arm, false otherwise (``Boolean``). This attribute wraps a number of pre-arm checks, ensuring that the vehicle has booted, has a good GPS fix, and that the EKF pre-arm is complete. @@ -1490,7 +1445,9 @@ def is_armable(self): @property def system_status(self): """ - System status. Is a ``SystemStatus`` object with a ``state`` property of: + System status (:py:class:`SystemStatus`). + + The status has a ``state`` property with one of the following values: * ``UNINIT``: Uninitialized system, state is unknown. * ``BOOT``: System is booting up. @@ -1516,26 +1473,37 @@ def system_status(self): @property def heading(self): """ - Current heading in degrees (0..360, where North = 0). + Current heading in degrees - 0..360, where North = 0 (``int``). """ return self._heading @property def groundspeed(self): + """ + Groundspeed in metres/second (``double``). + """ return self._groundspeed @property def airspeed(self): + """ + Current airspeed in metres/second (``double``). + """ return self._airspeed @property def mount_status(self): + """ + Current status of the camera mount (gimbal) as a three element list: ``[ pitch, yaw, roll ]``. + + The values in the list are set to ``None`` if no mount is configured. + """ return [self._mount_pitch, self._mount_yaw, self._mount_roll] @property def ekf_ok(self): """ - ``True`` if the EKF status is considered acceptable, ``False`` otherwise. + ``True`` if the EKF status is considered acceptable, ``False`` otherwise (``boolean``). """ # legacy check for dronekit-python for solo # use same check that ArduCopter::system.pde::position_ok() is using @@ -1547,7 +1515,8 @@ def ekf_ok(self): @property def channels(self): """ - The RC channel values from the RC Transmitter, in a :py:class:`Channels` object. + The RC channel values from the RC Transmitter (:py:class:`Channels`). + The attribute can also be used to set and read RC Override (channel override) values via :py:attr:`Vehicle.channels.override `. @@ -1571,7 +1540,7 @@ def channels(self): @property def home_location(self): """ - The current home location in a :py:class:`LocationGlobal`. + The current home location (:py:class:`LocationGlobal`). To get the attribute you must first download the :py:func:`Vehicle.commands`. The attribute has a value of ``None`` until :py:func:`Vehicle.commands` has been downloaded @@ -1607,7 +1576,7 @@ def home_location(self): @home_location.setter def home_location(self, pos): """ - Sets the home location to that of a ``LocationGlobal`` object. + Sets the home location (``LocationGlobal``). The value cannot be set until it has successfully been read from the vehicle. After being set the value is cached in the home_location attribute and does not have to be re-read. @@ -1635,7 +1604,7 @@ def home_location(self, pos): @property def commands(self): """ - Gets the editable waypoints for this vehicle (the current "mission"). + Gets the editable waypoints/current mission for this vehicle (:py:class:`CommandSequence`). This can be used to get, create, and modify a mission. It can also be used for direct control of vehicle position (outside missions) using the :py:func:`goto ` method. @@ -1647,7 +1616,7 @@ def commands(self): @property def parameters(self): """ - The (editable) parameters for this vehicle (:py:class:`Parameters `). + The (editable) parameters for this vehicle (:py:class:`Parameters`). """ return self._parameters @@ -1810,8 +1779,8 @@ def wait_ready(self, *types, **kwargs): class Parameters(collections.MutableMapping, HasObservers): """ This object is used to get and set the values of named parameters for a vehicle. See the following links for information about - the supported parameters for each platform: `Copter `_, - `Plane `_, `Rover `_. + the supported parameters for each platform: `Copter Parameters `_, + `Plane Parameters `_, `Rover Parameters `_. The code fragment below shows how to get and set the value of a parameter. @@ -1823,9 +1792,9 @@ class Parameters(collections.MutableMapping, HasObservers): # Change the parameter value to something different. vehicle.parameters['THR_MIN']=100 - It is also possible to observe parameters and to iterate the :py:func:`Vehicle.parameters`. + It is also possible to observe parameters and to iterate the :py:attr:`Vehicle.parameters`. - For more information see: :ref:`vehicle_state_parameters`. + For more information see :ref:`the guide `. """ def __init__(self, vehicle): @@ -1996,8 +1965,9 @@ class Command(mavutil.mavlink.MAVLink_mission_item_message): """ A waypoint object. - This object encodes a single mission item command. The set of commands that are supported by ArduPilot in Copter, Plane and Rover (along with their parameters) - are listed in the wiki article `MAVLink Mission Command Messages (MAV_CMD) `_. + This object encodes a single mission item command. The set of commands that are supported + by ArduPilot in Copter, Plane and Rover (along with their parameters) are listed in the wiki article + `MAVLink Mission Command Messages (MAV_CMD) `_. For example, to create a `NAV_WAYPOINT `_ command: @@ -2028,8 +1998,6 @@ class Command(mavutil.mavlink.MAVLink_mission_item_message): :param y: (param6) Command specific parameter used for longitude (if relevant to command). :param z: (param7) Command specific parameter used for altitude (if relevant). The reference frame for altitude depends on the ``frame``. - .. todo:: Confirm if target_sytem, target_component, seq, frame are all handled for you or not. If not, check that these are correct. - .. todo:: FIXME: Command class - for now we just inherit the standard MAVLink mission item contents. """ pass @@ -2040,7 +2008,7 @@ class CommandSequence(object): Operations include 'array style' indexed access to the various contained waypoints. - The current commands/mission for a vehicle are accessed using the :py:attr:`Vehicle.commands ` attribute. + The current commands/mission for a vehicle are accessed using the :py:attr:`Vehicle.commands` attribute. Waypoints are not downloaded from vehicle until :py:func:`download()` is called. The download is asynchronous; use :py:func:`wait_ready()` to block your thread until the download is complete. The code to download the commands from a vehicle is shown below: @@ -2156,7 +2124,7 @@ def clear(self): ''' Clear the command list. - This command will be sent to the vehicleonly after you call :py:func:`upload() `. + This command will be sent to the vehicle only after you call :py:func:`upload() `. ''' # Add home point again. @@ -2258,9 +2226,58 @@ def connect(ip, baud=115200, heartbeat_timeout=30, source_system=255): + """ + Returns a :py:class:`Vehicle` object connected to the address specified by string parameter ``ip``. + Connection string parameters (``ip``) for different targets are listed in the :ref:`getting started guide `. + + The method is usually called with ``wait_ready=True`` to ensure that vehicle parameters and (most) attributes are + available when ``connect()`` returns. + + .. code:: python + + from dronekit import connect + + # Connect to the Vehicle using "connection string" (in this case an address on network) + vehicle = connect('127.0.0.1:14550', wait_ready=True) + + :param String ip: :ref:`Connection string ` for target address - e.g. 127.0.0.1:14550. + + :param Bool/Array wait_ready: If ``True`` wait until all default attributes have downloaded before + the method returns (default is ``None``). + The default attributes to wait on are: :py:attr:`parameters`, :py:attr:`gps_0`, + :py:attr:`armed`, :py:attr:`mode`, and :py:attr:`attitude`. + + You can also specify a named set of parameters to wait on (e.g. ``wait_ready=['system_status','mode']``). + + For more information see :py:func:`Vehicle.wait_ready `. + + :param status_printer: Method of signature ``def status_printer(txt)`` that prints + STATUS_TEXT messages from the Vehicle and other diagnostic information. + By default the status information is printed to the command prompt in which the script is running. + :param Vehicle vehicle_class: The class that will be instantiated by the ``connect()`` method. + This can be any sub-class of ``Vehicle`` (and defaults to ``Vehicle``). + :param int rate: Data stream refresh rate. The default is 4Hz (4 updates per second). + :param int baud: The baud rate for the connection. The default is 115200. + :param int heartbeat_timeout: Connection timeout value in seconds (default is 30s). + If a heartbeat is not detected within this time an exception will be raised. + :param int source_system: The MAVLink ID of the :py:class:`Vehicle` object returned by this method (by default 255). + + .. note:: + + The returned :py:class:`Vehicle` object acts as a ground control station from the + perspective of the connected "real" vehicle. It will process/receive messages from the real vehicle + if they are addressed to this ``source_system`` id. Messages sent to the real vehicle are + automatically updated to use the vehicle's ``target_system`` id. + + It is *good practice* to assign a unique id for every system on the MAVLink network. + It is possible to configure the autopilot to only respond to guided-mode commands from a specified GCS ID. + + + :returns: A connected vehicle of the type defined in ``vehicle_class`` (a superclass of :py:class:`Vehicle`). + """ handler = MAVConnection(ip, baud=baud, source_system=source_system) vehicle = vehicle_class(handler) - + if status_printer: @vehicle.on_message('STATUSTEXT') From 3dbb93c2759d9bfb798c86176b0e954377ffb113 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 19 Nov 2015 12:19:02 +1100 Subject: [PATCH 225/475] Fix link to forums rather than stack overflow --- docs/about/overview.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/about/overview.rst b/docs/about/overview.rst index 3d94e9fd4..05b814ffb 100644 --- a/docs/about/overview.rst +++ b/docs/about/overview.rst @@ -51,7 +51,7 @@ Technical support This documentation is a great place to get started with developing DroneKit Python APIs. -If you run into problems, the `best place to ask questions is Stack Overflow `_. +If you run into problems, the best place to ask questions is the `DroneKit-Python Forum `_. If your problem turns out to be a bug, then it should be `posted on Github `_. From 72a3c1c9037820f8a48a824dec0191d7273bfc59 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 19 Nov 2015 22:12:50 +1100 Subject: [PATCH 226/475] Fixes as a result of retesting examples. For example, velocity movement commands are signficantly different in AC3.3 --- docs/examples/guided-set-speed-yaw-demo.rst | 111 ++++++++----- docs/examples/mission_basic.rst | 5 +- docs/examples/simple_goto.rst | 8 +- docs/guide/auto_mode.rst | 2 +- docs/guide/copter/guided_mode.rst | 79 ++++++---- .../guided_set_speed_yaw.py | 147 +++++++++++------- examples/mission_basic/mission_basic.py | 4 +- examples/simple_goto/simple_goto.py | 4 +- examples/vehicle_state/vehicle_state.py | 1 - 9 files changed, 221 insertions(+), 140 deletions(-) diff --git a/docs/examples/guided-set-speed-yaw-demo.rst b/docs/examples/guided-set-speed-yaw-demo.rst index 787023136..b0f32ec58 100644 --- a/docs/examples/guided-set-speed-yaw-demo.rst +++ b/docs/examples/guided-set-speed-yaw-demo.rst @@ -176,12 +176,24 @@ The example is :ref:`documented in source code `. Ad The functions for controlling vehicle movement are: -* :ref:`Vehicle.commands.goto() ` is the standard DroneKit position controller method. It is called from :ref:`goto ` to fly a triangular path. -* :ref:`goto_position_target_global_int() ` is a position controller that uses the `SET_POSITION_TARGET_GLOBAL_INT `_ command. -* :ref:`goto_position_target_local_ned() ` is a position controller that uses `SET_POSITION_TARGET_LOCAL_NED `_ command (taking values in NED frame, relative to the home position). This is used to fly a square path. The script is put to sleep for a certain time in order to allow the vehicle to reach the specified position. -* :ref:`send_ned_velocity() ` is a velocity controller. It uses `SET_POSITION_TARGET_LOCAL_NED `_ to fly a square path using velocity vectors to define the speed in each direction. -* :ref:`send_global_velocity() ` is a velocity controller. It uses `SET_POSITION_TARGET_GLOBAL_INT `_ to fly a diamond-shaped path. The behaviour is essentially the same as for ``send_ned_velocity()`` because the velocity components in both commands are in the NED frame. -* :ref:`goto ` is a convenience function for specifying a target location in metres from the current location and reporting the result. +* :ref:`Vehicle.commands.goto() ` is the standard + DroneKit position controller method. It is called from :ref:`goto ` to fly a triangular path. +* :ref:`goto_position_target_global_int() ` + is a position controller that uses the + `SET_POSITION_TARGET_GLOBAL_INT `_ command. +* :ref:`goto_position_target_local_ned() ` + is a position controller that uses `SET_POSITION_TARGET_LOCAL_NED `_ + command (taking values in NED frame, relative to the home position). This is used to fly a square path. + The script is put to sleep for a certain time in order to allow the vehicle to reach the specified position. +* :ref:`send_ned_velocity() ` is a velocity controller. + It uses `SET_POSITION_TARGET_LOCAL_NED `_ + to fly a square path using velocity vectors to define the speed in each direction. +* :ref:`send_global_velocity() ` is a velocity controller. + It uses `SET_POSITION_TARGET_GLOBAL_INT `_ + to fly a diamond-shaped path. The behaviour is essentially the same as for ``send_ned_velocity()`` + because the velocity components in both commands are in the NED frame. +* :ref:`goto ` is a convenience function for specifying a target location + in metres from the current location and reporting the result. The functions sending immediate commands are: @@ -190,21 +202,25 @@ The functions sending immediate commands are: * :ref:`set_roi(location) ` * :ref:`set_speed(speed) ` -The example uses a number functions to convert global locations co-ordinates (decimal degrees) into local coordinates relative to the vehicle (in metres). These are :ref:`described in the guide `. +The example uses a number functions to convert global locations co-ordinates (decimal degrees) into local +coordinates relative to the vehicle (in metres). These are :ref:`described in the guide `. + .. _example_guided_mode_goto_convenience: goto() - convenience function ----------------------------- -This is a convenience function for setting position targets in metres North and East of the current location. It reports the distance to the target every two seconds and completes when the target is reached. +This is a convenience function for setting position targets in metres North and East of the current location. +It reports the distance to the target every two seconds and completes when the target is reached. -This takes a function argument of either :ref:`Vehicle.commands.goto() ` or :ref:`goto_position_target_global_int() ` +This takes a function argument of either :ref:`Vehicle.commands.goto() ` or +:ref:`goto_position_target_global_int() ` .. code-block:: python def goto(dNorth, dEast, gotoFunction=vehicle.commands.goto): - currentLocation=vehicle.location.global_frame + currentLocation=vehicle.location.global_relative_frame targetLocation=get_location_metres(currentLocation, dNorth, dEast) targetDistance=get_distance_metres(currentLocation, targetLocation) gotoFunction(targetLocation) @@ -225,8 +241,9 @@ send_ned_velocity() ------------------- The function ``send_ned_velocity()`` generates a ``SET_POSITION_TARGET_LOCAL_NED`` MAVLink message -which is used to directly specify the speed components of the vehicle. The distance travelled is controlled -by a delay before the next command is sent. +which is used to directly specify the speed components of the vehicle. + +The message is resent at 1Hz for a set duration. This is documented in :ref:`the guide here `. @@ -236,12 +253,17 @@ This is documented in :ref:`the guide here send_global_velocity() ---------------------- -The function ``send_global_velocity()`` generates a `SET_POSITION_TARGET_GLOBAL_INT `_ MAVLink message -which is used to directly specify the speed components of the vehicle. The function behaviour is otherwise exactly the same as when using :ref:`SET_POSITION_TARGET_LOCAL_NED ` +The function ``send_global_velocity()`` generates a +`SET_POSITION_TARGET_GLOBAL_INT `_ +MAVLink message which is used to directly specify the speed components of the vehicle in the NED +frame. + +The function behaviour is otherwise exactly the same as when using +:ref:`SET_POSITION_TARGET_LOCAL_NED `. .. code-block:: python - def send_global_velocity(velocity_x, velocity_y, velocity_z): + def send_global_velocity(velocity_x, velocity_y, velocity_z, duration): """ Move vehicle in direction based on specified velocity vectors. """ @@ -259,8 +281,18 @@ which is used to directly specify the speed components of the vehicle. The funct velocity_z, # Z velocity in NED frame in m/s 0, 0, 0, # afx, afy, afz acceleration (not supported yet, ignored in GCS_Mavlink) 0, 0) # yaw, yaw_rate (not supported yet, ignored in GCS_Mavlink) - # send command to vehicle - vehicle.send_mavlink(msg) + + # send command to vehicle on 1 Hz cycle + for x in range(0,duration): + vehicle.send_mavlink(msg) + time.sleep(1) + +.. note:: + + The message is re-sent every second for the specified duration. From Copter 3.3 the vehicle will stop + moving if a new message is not received in approximately 3 seconds. Prior to Copter 3.3 the message only + needs to be sent once, and the velocity remains active until the next movement message is received. + The above code works for both cases! @@ -269,9 +301,11 @@ which is used to directly specify the speed components of the vehicle. The funct goto_position_target_global_int() --------------------------------- -The function ``goto_position_target_global_int()`` generates a `SET_POSITION_TARGET_GLOBAL_INT `_ -MAVLink message which is used to directly specify the target location of the vehicle. When used with ``MAV_FRAME_GLOBAL_RELATIVE_ALT_INT`` as shown below, -this method is effectively the same as :ref:`Vehicle.commands.goto `. +The function ``goto_position_target_global_int()`` generates a +`SET_POSITION_TARGET_GLOBAL_INT `_ +MAVLink message which is used to directly specify the target location of the vehicle. +When used with ``MAV_FRAME_GLOBAL_RELATIVE_ALT_INT`` as shown below, +this method is effectively the same as :ref:`Vehicle.commands.goto `. .. code-block:: python @@ -292,6 +326,7 @@ this method is effectively the same as :ref:`Vehicle.commands.goto `_ MAVLink message -which is used to directly specify the target location in the North, East, Down frame. The ``type_mask`` enables the position parameters (the last three bits of of the mask are zero). +The function ``goto_position_target_local_ned()`` generates a +`SET_POSITION_TARGET_LOCAL_NED `_ +MAVLink message which is used to directly specify the target location in the North, East, Down frame. +The ``type_mask`` enables the position parameters (the last three bits of of the mask are zero). .. warning:: @@ -314,9 +351,11 @@ which is used to directly specify the target location in the North, East, Down f .. note:: - The `documentation `_ lists a number of possible frames of reference. - Up until Copter 3.2.1 the actual frame use is always relative to the home location (not the vehicle, as indicated by MAV_FRAME_BODY_NED). - + The `MAVLink protocol documentation `_ + lists a number of possible frames of reference. Up until Copter 3.2.1 the actual frame used is always + relative to the home location (as indicated by MAV_FRAME_LOCAL_NED). Starting from Copter 3.3 + you can specify `other frames `_, + for example to move the vehicle relative to its current position. .. code-block:: python @@ -324,13 +363,13 @@ which is used to directly specify the target location in the North, East, Down f """ Send SET_POSITION_TARGET_LOCAL_NED command to request the vehicle fly to a specified location in the North, East, Down frame. - """ + """ msg = vehicle.message_factory.set_position_target_local_ned_encode( 0, # time_boot_ms (not used) 0, 0, # target system, target component - mavutil.mavlink.MAV_FRAME_BODY_NED, # frame + mavutil.mavlink.MAV_FRAME_LOCAL_NED, # frame 0b0000111111111000, # type_mask (only positions enabled) - north, east, down, # x, y, z positions (or North, East, Down in the MAV_FRAME_BODY_NED frame + north, east, down, 0, 0, 0, # x, y, z velocity in m/s (not used) 0, 0, 0, # x, y, z acceleration (not supported yet, ignored in GCS_Mavlink) 0, 0) # yaw, yaw_rate (not supported yet, ignored in GCS_Mavlink) @@ -344,18 +383,10 @@ At time of writing, acceleration and yaw bits are ignored. Testbed settings ================ -This demo has been tested on Windows against SITL running both natively and in a virtual machine (as described in :ref:`get-started`). - -DroneKit environment (from PIP): - -* droneapi: 2.0.0rc2 -* pymavlink: 1.1.57 -* MAVProxy: 1.4.23 -* protobuf: 2.6.1 - -ArduPilot version: +This example has been tested on Windows against SITL running both natively and in a virtual machine (as described in :ref:`get-started`). -* 3.3.0. +* DroneKit version: 2.0.0rc12 +* ArduPilot version: 3.4.0. @@ -365,7 +396,7 @@ Source code =========== The full source code at documentation build-time is listed below -(`current version on github `_): +(`current version on Github `_): .. literalinclude:: ../../examples/guided_set_speed_yaw/guided_set_speed_yaw.py :language: python diff --git a/docs/examples/mission_basic.rst b/docs/examples/mission_basic.rst index 446d166d6..97a67d065 100644 --- a/docs/examples/mission_basic.rst +++ b/docs/examples/mission_basic.rst @@ -177,10 +177,7 @@ When the vehicle starts the 5th command (a dummy waypoint) the loop breaks and t Known issues ============ -This example has the following issues: - -* :py:func:`next ` does not appear to be writable, so the example does not skip steps as documented. - This is tracked as `#390 <#https://github.com/dronekit/dronekit-python/issues/390>`_. +This example has no known issues. .. _example_mission_basic_source_code: diff --git a/docs/examples/simple_goto.rst b/docs/examples/simple_goto.rst index 04f7d7b04..3e9211a2c 100644 --- a/docs/examples/simple_goto.rst +++ b/docs/examples/simple_goto.rst @@ -130,11 +130,12 @@ Flying to a point - Goto ------------------------ The vehicle is already in ``GUIDED`` mode, so to send it to a certain point we just need to -call :py:func:`Vehicle.commands.goto() ` with the target ``LocationGlobal``: +call :py:func:`Vehicle.commands.goto() ` with the target +:py:class:`dronekit.LocationGlobalRelative`: .. code-block:: python - point1 = LocationGlobal(-35.361354, 149.165218, 20, is_relative=True) + point1 = LocationGlobalRelative(-35.361354, 149.165218, 20) vehicle.commands.goto(point1) # sleep so we can see the change in map @@ -161,7 +162,8 @@ To return to the home position and land, we set the mode to ``RTL``: Source code =========== -The full source code at documentation build-time is listed below (`current version on github `_): +The full source code at documentation build-time is listed below +(`current version on Github `_): .. literalinclude:: ../../examples/simple_goto/simple_goto.py :language: python \ No newline at end of file diff --git a/docs/guide/auto_mode.rst b/docs/guide/auto_mode.rst index 745b689b8..6c8a29fb1 100644 --- a/docs/guide/auto_mode.rst +++ b/docs/guide/auto_mode.rst @@ -400,7 +400,7 @@ Get distance to waypoint lat=missionitem.x lon=missionitem.y alt=missionitem.z - targetWaypointLocation=LocationGlobal(lat,lon,alt,is_relative=True) + targetWaypointLocation=LocationGlobal(lat,lon,alt) distancetopoint = get_distance_metres(vehicle.location.global_frame, targetWaypointLocation) return distancetopoint diff --git a/docs/guide/copter/guided_mode.rst b/docs/guide/copter/guided_mode.rst index 79e71aa68..03e464fc0 100644 --- a/docs/guide/copter/guided_mode.rst +++ b/docs/guide/copter/guided_mode.rst @@ -38,9 +38,8 @@ Position control Controlling the vehicle by explicitly setting the target position is useful when the final position is known/fixed. The recommended method for position control is :py:func:`Vehicle.commands.goto() `. -This takes a :py:class:`LocationGlobal ` argument for the target position in the -global `WGS84 coordinate system `_, but with altitude -relative to the home location (home altitude = 0). +This takes a :py:class:`LocationGlobal ` or +:py:class:`LocationGlobalRelative ` argument. The method is used as shown below: @@ -49,8 +48,8 @@ The method is used as shown below: # Set mode to guided - this is optional as the goto method will change the mode if needed. vehicle.mode = VehicleMode("GUIDED") - # Set the target location in global frame - a_location = LocationGlobal(-34.364114, 149.166022, 30, is_relative=True) + # Set the target location in global-relative frame + a_location = LocationGlobalRelative(-34.364114, 149.166022, 30) vehicle.commands.goto(a_location) @@ -69,7 +68,7 @@ When moving the vehicle you can send a separate command to :ref:`control the spe a ``type_mask`` bitmask that enables the position parameters. The main difference between these commands is that the former allows you to specify the location relative to the "global" frames (like ``Vehicle.commands.goto()``), while the later lets you specify the location in NED co-ordinates relative - to the home location. For more information on these options see the example code: + to the home location or the vehicle itself. For more information on these options see the example code: :ref:`example_guided_mode_goto_position_target_global_int` and :ref:`example_guided_mode_goto_position_target_local_ned`. @@ -79,39 +78,61 @@ When moving the vehicle you can send a separate command to :ref:`control the spe Velocity control ---------------- -Controlling vehicle movement using velocity is much smoother than using position when there are likely to be many updates (for example when tracking moving objects). +Controlling vehicle movement using velocity is much smoother than using position when there are likely +to be many updates (for example when tracking moving objects). The function ``send_ned_velocity()`` below generates a ``SET_POSITION_TARGET_LOCAL_NED`` MAVLink message -which is used to directly specify the speed components of the vehicle. +which is used to directly specify the speed components of the vehicle in the ``MAV_FRAME_LOCAL_NED`` +frame (relative to home location). The message is re-sent every second for the specified duration. + +.. note:: + + From Copter 3.3 the vehicle will stop moving if a new message is not received in approximately 3 seconds. + Prior to Copter 3.3 the message only needs to be sent once, and the velocity remains active until the next + movement command is received. The example code works for both cases! + .. code-block:: python - def send_ned_velocity(velocity_x, velocity_y, velocity_z): + def send_ned_velocity(velocity_x, velocity_y, velocity_z, duration): """ Move vehicle in direction based on specified velocity vectors. """ msg = vehicle.message_factory.set_position_target_local_ned_encode( 0, # time_boot_ms (not used) 0, 0, # target system, target component - mavutil.mavlink.MAV_FRAME_BODY_NED, # frame + mavutil.mavlink.MAV_FRAME_LOCAL_NED, # frame 0b0000111111000111, # type_mask (only speeds enabled) 0, 0, 0, # x, y, z positions (not used) velocity_x, velocity_y, velocity_z, # x, y, z velocity in m/s 0, 0, 0, # x, y, z acceleration (not supported yet, ignored in GCS_Mavlink) - 0, 0) # yaw, yaw_rate (not supported yet, ignored in GCS_Mavlink) - # send command to vehicle - vehicle.send_mavlink(msg) - - + 0, 0) # yaw, yaw_rate (not supported yet, ignored in GCS_Mavlink) + + + # send command to vehicle on 1 Hz cycle + for x in range(0,duration): + vehicle.send_mavlink(msg) + time.sleep(1) + + The ``type_mask`` parameter is a bitmask that indicates which of the other parameters in the message are used/ignored by the vehicle (0 means that the dimension is enabled, 1 means ignored). In the example the value 0b0000111111000111 is used to enable the velocity components. -The speed components ``velocity_x`` and ``velocity_y`` are parallel to the North and East directions (not to the front and side of the vehicle). +In the ``MAV_FRAME_LOCAL_NED`` the speed components ``velocity_x`` and ``velocity_y`` are parallel to the North and East +directions (not to the front and side of the vehicle). The ``velocity_z`` component is perpendicular to the plane of ``velocity_x`` and ``velocity_y``, with a positive value **towards the ground**, following -the right-hand convention. For more information about the ``mavutil.mavlink.MAV_FRAME_BODY_NED`` frame of reference, see this wikipedia article +the right-hand convention. For more information about the ``MAV_FRAME_LOCAL_NED`` frame of reference, see this wikipedia article on `NED `_. +.. tip:: + + From Copter 3.3 you can `specify other frames `_, + for example ``MAV_FRAME_BODY_OFFSET_NED`` makes the velocity components relative to the current vehicle heading. + In Copter 3.2.1 (and earlier) the frame setting is ignored (``MAV_FRAME_LOCAL_NED`` is always used). + + + The code fragment below shows how to call this method: .. code-block:: python @@ -127,16 +148,15 @@ The code fragment below shows how to call this method: UP=-0.5 #NOTE: up is negative! #Fly south and up. - send_ned_velocity(SOUTH,0,UP) + send_ned_velocity(SOUTH,0,UP,DURATION) -The command can be interrupted by a later movement command. When moving the vehicle you can send separate commands to control the yaw (and other behaviour). +When moving the vehicle you can send separate commands to control the yaw (and other behaviour). .. tip:: You can also control the velocity using the `SET_POSITION_TARGET_GLOBAL_INT `_ - MAVLink command in almost exactly the same way (there is no real benefit in sending one command over the other). - For more information on this option see :ref:`example_guided_mode_send_global_velocity` in the example code. + MAVLink command, as described in :ref:`example_guided_mode_send_global_velocity`. @@ -350,9 +370,13 @@ The ROI (and yaw) is also reset when the mode, or the command used to control mo Command acknowledgements and response values -------------------------------------------- -ArduPilot typically sends a command acknowledgement indicating whether a command was received, and whether it was accepted or rejected. At time of writing there is no way to intercept this acknowledgement in the API (`#168 `_). +ArduPilot typically sends a command acknowledgement indicating whether a command was received, and whether +it was accepted or rejected. At time of writing there is no way to intercept this acknowledgement +in the API (`#168 `_). -Some MAVLink messages request information from the autopilot, and expect the result to be returned in another message. At time of writing you can send the request (provided the message is handled by the AutoPilot in GUIDED mode) but there is no way to intercept the response in DroneKit-Python (`#169 `_). +Some MAVLink messages request information from the autopilot, and expect the result to be returned +in another message. Provided the message is handled by the AutoPilot in GUIDED mode you can send the request +and process the response by creating a :ref:`message listener `. .. _guided_mode_copter_useful_conversion_functions: @@ -372,7 +396,7 @@ to the Earth's poles. def get_location_metres(original_location, dNorth, dEast): """ Returns a LocationGlobal object containing the latitude/longitude `dNorth` and `dEast` metres from the - specified `original_location`. The returned LocationGlobal has the same `alt and `is_relative` values + specified `original_location`. The returned LocationGlobal has the same `alt` value as `original_location`. The function is useful when you want to move the vehicle around specifying locations relative to @@ -391,14 +415,14 @@ to the Earth's poles. #New position in decimal degrees newlat = original_location.lat + (dLat * 180/math.pi) newlon = original_location.lon + (dLon * 180/math.pi) - return LocationGlobal(newlat, newlon,original_location.alt,original_location.is_relative) + return LocationGlobal(newlat, newlon,original_location.alt) .. code-block:: python def get_distance_metres(aLocation1, aLocation2): """ - Returns the ground distance in metres between two LocationGlobal objects. + Returns the ground distance in metres between two `LocationGlobal` or `LocationGlobalRelative` objects. This method is an approximation, and will not be accurate over large distances and close to the earth's poles. It comes from the ArduPilot test code: @@ -428,7 +452,8 @@ to the Earth's poles. .. tip:: - The `common.py `_ file in the ArduPilot test code may have other functions that you will find useful. + The `common.py `_ file + in the ArduPilot test code may have other functions that you will find useful. diff --git a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py index 44f64bb8b..4f1d8d355 100644 --- a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py +++ b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py @@ -7,7 +7,7 @@ """ from dronekit import connect, VehicleMode, LocationGlobal -from pymavlink import mavutil +from pymavlink import mavutil # Needed for command message definitions import time import math @@ -178,7 +178,7 @@ def set_speed(speed): def get_location_metres(original_location, dNorth, dEast): """ Returns a LocationGlobal object containing the latitude/longitude `dNorth` and `dEast` metres from the - specified `original_location`. The returned LocationGlobal has the same `alt and `is_relative` values + specified `original_location`. The returned LocationGlobal has the same `alt` value as `original_location`. The function is useful when you want to move the vehicle around specifying locations relative to @@ -197,7 +197,7 @@ def get_location_metres(original_location, dNorth, dEast): #New position in decimal degrees newlat = original_location.lat + (dLat * 180/math.pi) newlon = original_location.lon + (dLon * 180/math.pi) - return LocationGlobal(newlat, newlon,original_location.alt,original_location.is_relative) + return LocationGlobal(newlat, newlon,original_location.alt) def get_distance_metres(aLocation1, aLocation2): @@ -253,11 +253,10 @@ def goto_position_target_global_int(aLocation): See the above link for information on the type_mask (0=enable, 1=ignore). At time of writing, acceleration and yaw bits are ignored. """ - print 'goto_target_globalint_position' msg = vehicle.message_factory.set_position_target_global_int_encode( 0, # time_boot_ms (not used) 0, 0, # target system, target component - mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT_INT, # frame + mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT_INT, # frame 0b0000111111111000, # type_mask (only speeds enabled) aLocation.lat*1e7, # lat_int - X Position in WGS84 frame in 1e7 * meters aLocation.lon*1e7, # lon_int - Y Position in WGS84 frame in 1e7 * meters @@ -280,12 +279,9 @@ def goto_position_target_local_ned(north, east, down): It is important to remember that in this frame, positive altitudes are entered as negative "Down" values. So if down is "10", this will be 10 metres below the home altitude. - At time of writing the method ignores the frame value and the NED frame is relative to the - HOME Location. If you want to specify the frame in terms of the vehicle (i.e. really use - MAV_FRAME_BODY_NED) then you can translate values relative to the home position (or move - the home position if this is sensible in your context). - - For more information see: https://pixhawk.ethz.ch/mavlink/#SET_POSITION_TARGET_LOCAL_NED + Starting from AC3.3 the method respects the frame setting. Prior to that the frame was + ignored. For more information see: + http://dev.ardupilot.com/wiki/copter-commands-in-guided-mode/#set_position_target_local_ned See the above link for information on the type_mask (0=enable, 1=ignore). At time of writing, acceleration and yaw bits are ignored. @@ -294,7 +290,7 @@ def goto_position_target_local_ned(north, east, down): msg = vehicle.message_factory.set_position_target_local_ned_encode( 0, # time_boot_ms (not used) 0, 0, # target system, target component - mavutil.mavlink.MAV_FRAME_BODY_NED, # frame + mavutil.mavlink.MAV_FRAME_LOCAL_NED, # frame 0b0000111111111000, # type_mask (only positions enabled) north, east, down, # x, y, z positions (or North, East, Down in the MAV_FRAME_BODY_NED frame 0, 0, 0, # x, y, z velocity in m/s (not used) @@ -315,14 +311,16 @@ def goto(dNorth, dEast, gotoFunction=vehicle.commands.goto): The method reports the distance to target every two seconds. """ - currentLocation=vehicle.location.global_frame + currentLocation=vehicle.location.global_relative_frame targetLocation=get_location_metres(currentLocation, dNorth, dEast) targetDistance=get_distance_metres(currentLocation, targetLocation) gotoFunction(targetLocation) + + while vehicle.mode.name=="GUIDED": #Stop action if we are no longer in guided mode. - remainingDistance=get_distance_metres(vehicle.location.global_frame, targetLocation) + remainingDistance=get_distance_metres(vehicle.location.global_relative_frame, targetLocation) print "Distance to target: ", remainingDistance if remainingDistance<=targetDistance*0.01: #Just below target, in case of undershoot. print "Reached target" @@ -333,19 +331,28 @@ def goto(dNorth, dEast, gotoFunction=vehicle.commands.goto): """ Functions that move the vehicle by specifying the velocity components in each direction. -The two functions use different MAVLink commands, but effectively implement the same behaviour. +The two functions use different MAVLink commands. The main difference is +that depending on the frame used, the NED velocity can be relative to the vehicle +orientation. The methods include: * send_ned_velocity - Sets velocity components using SET_POSITION_TARGET_LOCAL_NED command * send_global_velocity - Sets velocity components using SET_POSITION_TARGET_GLOBAL_INT command """ -def send_ned_velocity(velocity_x, velocity_y, velocity_z): +def send_ned_velocity(velocity_x, velocity_y, velocity_z, duration): """ - Move vehicle in direction based on specified velocity vectors. + Move vehicle in direction based on specified velocity vectors and + for the specified duration. This uses the SET_POSITION_TARGET_LOCAL_NED command with a type mask enabling only - velocity components (https://pixhawk.ethz.ch/mavlink/#SET_POSITION_TARGET_LOCAL_NED). + velocity components + (http://dev.ardupilot.com/wiki/copter-commands-in-guided-mode/#set_position_target_local_ned). + + Note that from AC3.3 the message should be re-sent every second (after about 3 seconds + with no message the velocity will drop back to zero). In AC3.2.1 and earlier the specified + velocity persists until it is canceled. The code below should work on either version + (sending the message multiple times does not cause problems). See the above link for information on the type_mask (0=enable, 1=ignore). At time of writing, acceleration and yaw bits are ignored. @@ -353,23 +360,33 @@ def send_ned_velocity(velocity_x, velocity_y, velocity_z): msg = vehicle.message_factory.set_position_target_local_ned_encode( 0, # time_boot_ms (not used) 0, 0, # target system, target component - mavutil.mavlink.MAV_FRAME_BODY_NED, # frame + mavutil.mavlink.MAV_FRAME_LOCAL_NED, # frame 0b0000111111000111, # type_mask (only speeds enabled) 0, 0, 0, # x, y, z positions (not used) velocity_x, velocity_y, velocity_z, # x, y, z velocity in m/s 0, 0, 0, # x, y, z acceleration (not supported yet, ignored in GCS_Mavlink) 0, 0) # yaw, yaw_rate (not supported yet, ignored in GCS_Mavlink) - # send command to vehicle - vehicle.send_mavlink(msg) + # send command to vehicle on 1 Hz cycle + for x in range(0,duration): + vehicle.send_mavlink(msg) + time.sleep(1) + + -def send_global_velocity(velocity_x, velocity_y, velocity_z): +def send_global_velocity(velocity_x, velocity_y, velocity_z, duration): """ Move vehicle in direction based on specified velocity vectors. This uses the SET_POSITION_TARGET_GLOBAL_INT command with type mask enabling only - velocity components (https://pixhawk.ethz.ch/mavlink/#SET_POSITION_TARGET_GLOBAL_INT). + velocity components + (http://dev.ardupilot.com/wiki/copter-commands-in-guided-mode/#set_position_target_global_int). + + Note that from AC3.3 the message should be re-sent every second (after about 3 seconds + with no message the velocity will drop back to zero). In AC3.2.1 and earlier the specified + velocity persists until it is canceled. The code below should work on either version + (sending the message multiple times does not cause problems). See the above link for information on the type_mask (0=enable, 1=ignore). At time of writing, acceleration and yaw bits are ignored. @@ -388,9 +405,11 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z): velocity_z, # Z velocity in NED frame in m/s 0, 0, 0, # afx, afy, afz acceleration (not supported yet, ignored in GCS_Mavlink) 0, 0) # yaw, yaw_rate (not supported yet, ignored in GCS_Mavlink) - # send command to vehicle - vehicle.send_mavlink(msg) + # send command to vehicle on 1 Hz cycle + for x in range(0,duration): + vehicle.send_mavlink(msg) + time.sleep(1) """ @@ -401,6 +420,8 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z): the distance-to-target. """ print("TRIANGLE path using standard Vehicle.commands.goto()") +print("Set speed to 5m/s.") +set_speed(5) print("Position North 80 West 50") goto(80, -50) @@ -413,7 +434,6 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z): - """ Fly a triangular path using the SET_POSITION_TARGET_GLOBAL_INT command and specifying a target position (rather than controlling movement using velocity vectors). The command is @@ -499,7 +519,8 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z): The code also sets the yaw (MAV_CMD_CONDITION_YAW) using the `set_yaw()` method in each segment so that the front of the vehicle points in the direction of travel -""" +""" + #Set up velocity vector to map to each direction. # vx > 0 => fly North @@ -522,33 +543,37 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z): # Square path using velocity print("SQUARE path using SET_POSITION_TARGET_LOCAL_NED and velocity parameters") -print("Velocity South & up") -send_ned_velocity(SOUTH,0,UP) + print("Yaw 180 absolute (South)") condition_yaw(180) -time.sleep(DURATION) -send_ned_velocity(0,0,0) -print("Velocity West & down") -send_ned_velocity(0,WEST,DOWN) +print("Velocity South & up") +send_ned_velocity(SOUTH,0,UP,DURATION) +send_ned_velocity(0,0,0,1) + + print("Yaw 270 absolute (West)") condition_yaw(270) -time.sleep(DURATION) -send_ned_velocity(0,0,0) -print("Velocity North") -send_ned_velocity(NORTH,0,0) +print("Velocity West & down") +send_ned_velocity(0,WEST,DOWN,DURATION) +send_ned_velocity(0,0,0,1) + + print("Yaw 0 absolute (North)") condition_yaw(0) -time.sleep(DURATION) -send_ned_velocity(0,0,0) -print("Velocity East") +print("Velocity North") +send_ned_velocity(NORTH,0,0,DURATION) +send_ned_velocity(0,0,0,1) + + +print("Yaw 90 absolute (East)") condition_yaw(90) -send_ned_velocity(0,EAST,0) -time.sleep(DURATION) -send_ned_velocity(0,0,0) +print("Velocity East") +send_ned_velocity(0,EAST,0,DURATION) +send_ned_velocity(0,0,0,1) """ @@ -565,19 +590,21 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z): print("DIAMOND path using SET_POSITION_TARGET_GLOBAL_INT and velocity parameters") # vx, vy are parallel to North and East (independent of the vehicle orientation) -print("Velocity North, East and up") -send_global_velocity(SOUTH,WEST,UP) + print("Yaw 225 absolute") condition_yaw(225) -time.sleep(DURATION) -send_global_velocity(0,0,0) -print("Velocity South, East and down") -send_global_velocity(NORTH,WEST,DOWN) +print("Velocity South, West and Up") +send_global_velocity(SOUTH,WEST,UP,DURATION) +send_global_velocity(0,0,0,1) + + print("Yaw 90 relative (to previous yaw heading)") condition_yaw(90,relative=True) -time.sleep(DURATION) -send_global_velocity(0,0,0) + +print("Velocity North, West and Down") +send_global_velocity(NORTH,WEST,DOWN,DURATION) +send_global_velocity(0,0,0,1) print("Set new home location to current location") vehicle.home_location=vehicle.location.global_frame @@ -588,19 +615,21 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z): cmds.wait_ready() print " Home Location: %s" % vehicle.home_location -print("Velocity South and West") -send_global_velocity(NORTH,EAST,0) + print("Yaw 90 relative (to previous yaw heading)") condition_yaw(90,relative=True) -time.sleep(DURATION) -send_global_velocity(0,0,0) -print("Velocity North and West") -send_global_velocity(SOUTH,EAST,0) +print("Velocity North and East") +send_global_velocity(NORTH,EAST,0,DURATION) +send_global_velocity(0,0,0,1) + + print("Yaw 90 relative (to previous yaw heading)") condition_yaw(90,relative=True) -time.sleep(DURATION) -send_global_velocity(0,0,0) + +print("Velocity South and East") +send_global_velocity(SOUTH,EAST,0,DURATION) +send_global_velocity(0,0,0,1) """ diff --git a/examples/mission_basic/mission_basic.py b/examples/mission_basic/mission_basic.py index d34db9748..f7e247ac7 100644 --- a/examples/mission_basic/mission_basic.py +++ b/examples/mission_basic/mission_basic.py @@ -26,7 +26,7 @@ def get_location_metres(original_location, dNorth, dEast): """ Returns a LocationGlobal object containing the latitude/longitude `dNorth` and `dEast` metres from the - specified `original_location`. The returned Location has the same `alt and `is_relative` values + specified `original_location`. The returned Location has the same `alt` value as `original_location`. The function is useful when you want to move the vehicle around specifying locations relative to @@ -43,7 +43,7 @@ def get_location_metres(original_location, dNorth, dEast): #New position in decimal degrees newlat = original_location.lat + (dLat * 180/math.pi) newlon = original_location.lon + (dLon * 180/math.pi) - return LocationGlobal(newlat, newlon,original_location.alt,original_location.is_relative) + return LocationGlobal(newlat, newlon,original_location.alt) def get_distance_metres(aLocation1, aLocation2): diff --git a/examples/simple_goto/simple_goto.py b/examples/simple_goto/simple_goto.py index db4feb537..60f911fcd 100644 --- a/examples/simple_goto/simple_goto.py +++ b/examples/simple_goto/simple_goto.py @@ -6,9 +6,7 @@ Full documentation is provided at http://python.dronekit.io/examples/simple_goto.html """ -import time -from dronekit import connect, VehicleMode, LocationGlobal, LocationGlobalRelative -from pymavlink import mavutil +from dronekit import connect, VehicleMode, LocationGlobalRelative import time diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 5bbfcc76f..04aab4fd8 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -7,7 +7,6 @@ Full documentation is provided at http://python.dronekit.io/examples/vehicle_state.html """ from dronekit import connect, VehicleMode -from pymavlink import mavutil import time #Set up option parsing to get connection string From 7101fecc0c10e69e11f672b78082fadfa94774dd Mon Sep 17 00:00:00 2001 From: Ahmed Agbabiaka Date: Thu, 19 Nov 2015 13:43:10 -0500 Subject: [PATCH 227/475] Update vehicle_state.py vehicle.home_location requires a float, not an integer. changed my_location_alt.alt value from 222 to 222.0 --- examples/vehicle_state/vehicle_state.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 04aab4fd8..50bca5330 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -65,7 +65,7 @@ # Home location must be within 50km of EKF home location (or setting will fail silently) # In this case, just set value to current location with an easily recognisable altitude (222) my_location_alt=vehicle.location.global_frame -my_location_alt.alt=222 +my_location_alt.alt=222.0 vehicle.home_location=my_location_alt print " New Home Location (from attribute - altitude should be 222): %s" % vehicle.home_location From 4ae648b166ca5e26107e6371117d0d2ab17e3670 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 19 Nov 2015 10:49:39 -0500 Subject: [PATCH 228/475] Fixes vehicle.commands.goto with LocationGlobal. --- dronekit/__init__.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index d1fa0d0bb..fd987d256 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -2110,15 +2110,24 @@ def goto(self, location): ''' if isinstance(location, LocationGlobalRelative): frame = mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT + alt = location.alt elif isinstance(location, LocationGlobal): - frame = mavutil.mavlink.MAV_FRAME_GLOBAL + # This should be the proper code: + # frame = mavutil.mavlink.MAV_FRAME_GLOBAL + # However, APM discards information about the relative frame + # and treats any alt value as relative. So we compensate here. + frame = mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT + if not self._vehicle.home_location: + self.download() + self.wait_ready() + alt = location.alt - self._vehicle.home_location.alt else: raise APIException('Expecting location to be LocationGlobal or LocationGlobalRelative.') self._vehicle._master.mav.mission_item_send(0, 0, 0, frame, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 2, 0, 0, 0, 0, 0, location.lat, location.lon, - location.alt) + alt) def clear(self): ''' From 43c8364bd78484dda6676e2e02b9f0ac21221feb Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 19 Nov 2015 19:35:21 -0500 Subject: [PATCH 229/475] Makes airspeed/groundspeed settable. --- dronekit/__init__.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index fd987d256..da4a2c2ad 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1484,6 +1484,21 @@ def groundspeed(self): """ return self._groundspeed + @groundspeed.setter + def groundspeed(self, speed): + speed_type = 1 # ground speed + msg = vehicle.message_factory.command_long_encode( + 0, 0, # target system, target component + mavutil.mavlink.MAV_CMD_DO_CHANGE_SPEED, #command + 0, #confirmation + speed_type, #param 1 + speed, # speed in metres/second + -1, 0, 0, 0, 0 #param 3 - 7 + ) + + # send command to vehicle + vehicle.send_mavlink(msg) + @property def airspeed(self): """ @@ -1491,6 +1506,21 @@ def airspeed(self): """ return self._airspeed + @groundspeed.setter + def airspeed(self, speed): + speed_type = 0 # air speed + msg = vehicle.message_factory.command_long_encode( + 0, 0, # target system, target component + mavutil.mavlink.MAV_CMD_DO_CHANGE_SPEED, #command + 0, #confirmation + speed_type, #param 1 + speed, # speed in metres/second + -1, 0, 0, 0, 0 #param 3 - 7 + ) + + # send command to vehicle + vehicle.send_mavlink(msg) + @property def mount_status(self): """ From 50cde45802592a5b8e80befe90157645103873a1 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 19 Nov 2015 19:38:38 -0500 Subject: [PATCH 230/475] Adds speed params to goto. --- dronekit/__init__.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index da4a2c2ad..71e505841 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -2121,7 +2121,7 @@ def takeoff(self, alt=None): self._vehicle._master.mav.command_long_send(0, 0, mavutil.mavlink.MAV_CMD_NAV_TAKEOFF, 0, 0, 0, 0, 0, 0, 0, altitude) - def goto(self, location): + def goto(self, location, airspeed=None, groundspeed=None): ''' Go to a specified global location (:py:class:`LocationGlobal` or :py:class:`LocationGlobalRelative`). @@ -2159,6 +2159,11 @@ def goto(self, location): 0, 0, 0, location.lat, location.lon, alt) + if airspeed != None: + self._vehicle.airspeed = airspeed + if groundspeed != None: + self._vehicle.groundspeed = groundspeed + def clear(self): ''' Clear the command list. From 48b80ba5f54144b8251be0572665f82fea4038d0 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 19 Nov 2015 19:39:10 -0500 Subject: [PATCH 231/475] Fixes examples. --- dronekit/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 71e505841..f72fa8940 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1487,7 +1487,7 @@ def groundspeed(self): @groundspeed.setter def groundspeed(self, speed): speed_type = 1 # ground speed - msg = vehicle.message_factory.command_long_encode( + msg = self.message_factory.command_long_encode( 0, 0, # target system, target component mavutil.mavlink.MAV_CMD_DO_CHANGE_SPEED, #command 0, #confirmation @@ -1497,7 +1497,7 @@ def groundspeed(self, speed): ) # send command to vehicle - vehicle.send_mavlink(msg) + self.send_mavlink(msg) @property def airspeed(self): @@ -1509,7 +1509,7 @@ def airspeed(self): @groundspeed.setter def airspeed(self, speed): speed_type = 0 # air speed - msg = vehicle.message_factory.command_long_encode( + msg = self.message_factory.command_long_encode( 0, 0, # target system, target component mavutil.mavlink.MAV_CMD_DO_CHANGE_SPEED, #command 0, #confirmation @@ -1519,7 +1519,7 @@ def airspeed(self, speed): ) # send command to vehicle - vehicle.send_mavlink(msg) + self.send_mavlink(msg) @property def mount_status(self): From 292327f53de2dc091c65091b04054e3ad7ac5479 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 19 Nov 2015 19:46:13 -0500 Subject: [PATCH 232/475] Renames to simple_goto and simple_takeoff --- dronekit/__init__.py | 110 +++++++++--------- dronekit/test/sitl/test_goto.py | 10 +- dronekit/test/sitl/test_locations.py | 4 +- examples/drone_delivery/drone_delivery.py | 6 +- examples/follow_me/follow_me.py | 8 +- .../guided_set_speed_yaw.py | 14 +-- examples/mission_basic/mission_basic.py | 4 +- examples/simple_goto/simple_goto.py | 10 +- 8 files changed, 83 insertions(+), 83 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index f72fa8940..a0d04c6cb 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -18,8 +18,8 @@ Asynchronous notification on vehicle attribute changes is available by registering listeners/observers. Vehicle movement is primarily controlled using the :py:attr:`Vehicle.armed` attribute and -:py:func:`Vehicle.commands.takeoff() ` and -:py:attr:`Vehicle.commands.goto() ` in GUIDED mode. +:py:func:`Vehicle.simple_takeoff() ` and +:py:attr:`Vehicle.simple_goto() ` in GUIDED mode. Control over speed, direction, altitude, camera trigger and any other aspect of the vehicle is supported using custom MAVLink messages (:py:func:`Vehicle.send_mavlink`, :py:func:`Vehicle.message_factory`). @@ -780,8 +780,8 @@ class Vehicle(HasObservers): Parameters can be iterated and are also individually observable. Vehicle movement is primarily controlled using the :py:attr:`armed` attribute and - :py:func:`Vehicle.commands.takeoff() ` and - :py:func:`Vehicle.commands.goto() ` in GUIDED mode. + :py:func:`Vehicle.simple_takeoff() ` and + :py:func:`Vehicle.simple_goto() ` in GUIDED mode. It is also possible to work with vehicle "missions" using the :py:attr:`commands` attribute, and run them in AUTO mode. @@ -1650,6 +1650,57 @@ def parameters(self): """ return self._parameters + def simple_takeoff(self, alt=None): + if alt is not None: + altitude = float(alt) + if math.isnan(alt) or math.isinf(alt): + raise ValueError("Altitude was NaN or Infinity. Please provide a real number") + self._master.mav.command_long_send(0, 0, mavutil.mavlink.MAV_CMD_NAV_TAKEOFF, + 0, 0, 0, 0, 0, 0, 0, altitude) + + def simple_goto(self, location, airspeed=None, groundspeed=None): + ''' + Go to a specified global location (:py:class:`LocationGlobal` or :py:class:`LocationGlobalRelative`). + + The method will change the :py:class:`VehicleMode` to ``GUIDED`` if necessary. + + .. code:: python + + # Set mode to guided - this is optional as the goto method will change the mode if needed. + vehicle.mode = VehicleMode("GUIDED") + + # Set the LocationGlobal to head towards + a_location = LocationGlobal(-34.364114, 149.166022, 30) + vehicle.simple_goto(a_location) + + :param LocationGlobal location: The target location. + ''' + if isinstance(location, LocationGlobalRelative): + frame = mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT + alt = location.alt + elif isinstance(location, LocationGlobal): + # This should be the proper code: + # frame = mavutil.mavlink.MAV_FRAME_GLOBAL + # However, APM discards information about the relative frame + # and treats any alt value as relative. So we compensate here. + frame = mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT + if not self.home_location: + self.commands.download() + self.commands.wait_ready() + alt = location.alt - self.home_location.alt + else: + raise APIException('Expecting location to be LocationGlobal or LocationGlobalRelative.') + + self._master.mav.mission_item_send(0, 0, 0, frame, + mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 2, 0, 0, + 0, 0, 0, location.lat, location.lon, + alt) + + if airspeed != None: + self.airspeed = airspeed + if groundspeed != None: + self.groundspeed = groundspeed + def send_mavlink(self, message): """ This method is used to send raw MAVLink "custom messages" to the vehicle. @@ -2113,57 +2164,6 @@ def wait_ready(self, **kwargs): """ return self._vehicle.wait_ready('commands', **kwargs) - def takeoff(self, alt=None): - if alt is not None: - altitude = float(alt) - if math.isnan(alt) or math.isinf(alt): - raise ValueError("Altitude was NaN or Infinity. Please provide a real number") - self._vehicle._master.mav.command_long_send(0, 0, mavutil.mavlink.MAV_CMD_NAV_TAKEOFF, - 0, 0, 0, 0, 0, 0, 0, altitude) - - def goto(self, location, airspeed=None, groundspeed=None): - ''' - Go to a specified global location (:py:class:`LocationGlobal` or :py:class:`LocationGlobalRelative`). - - The method will change the :py:class:`VehicleMode` to ``GUIDED`` if necessary. - - .. code:: python - - # Set mode to guided - this is optional as the goto method will change the mode if needed. - vehicle.mode = VehicleMode("GUIDED") - - # Set the LocationGlobal to head towards - a_location = LocationGlobal(-34.364114, 149.166022, 30) - vehicle.commands.goto(a_location) - - :param LocationGlobal location: The target location. - ''' - if isinstance(location, LocationGlobalRelative): - frame = mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT - alt = location.alt - elif isinstance(location, LocationGlobal): - # This should be the proper code: - # frame = mavutil.mavlink.MAV_FRAME_GLOBAL - # However, APM discards information about the relative frame - # and treats any alt value as relative. So we compensate here. - frame = mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT - if not self._vehicle.home_location: - self.download() - self.wait_ready() - alt = location.alt - self._vehicle.home_location.alt - else: - raise APIException('Expecting location to be LocationGlobal or LocationGlobalRelative.') - - self._vehicle._master.mav.mission_item_send(0, 0, 0, frame, - mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 2, 0, 0, - 0, 0, 0, location.lat, location.lon, - alt) - - if airspeed != None: - self._vehicle.airspeed = airspeed - if groundspeed != None: - self._vehicle.groundspeed = groundspeed - def clear(self): ''' Clear the command list. diff --git a/dronekit/test/sitl/test_goto.py b/dronekit/test/sitl/test_goto.py index e40f5f746..2269bc31e 100644 --- a/dronekit/test/sitl/test_goto.py +++ b/dronekit/test/sitl/test_goto.py @@ -2,7 +2,7 @@ simple_goto.py: GUIDED mode "simple goto" example (Copter Only) The example demonstrates how to arm and takeoff in Copter and how to navigate to -points using Vehicle.commands.goto. +points using Vehicle.simple_goto. Full documentation is provided at http://python.dronekit.io/examples/simple_goto.html """ @@ -54,11 +54,11 @@ def arm_and_takeoff(aTargetAltitude): assert_equals(vehicle.armed, True) # Take off to target altitude - vehicle.commands.takeoff(aTargetAltitude) + vehicle.simple_takeoff(aTargetAltitude) # Wait until the vehicle reaches a safe height before # processing the goto (otherwise the command after - # Vehicle.commands.takeoff will execute immediately). + # Vehicle.simple_takeoff will execute immediately). while True: # print " Altitude: ", vehicle.location.alt # Test for altitude just below target, in case of undershoot. @@ -73,14 +73,14 @@ def arm_and_takeoff(aTargetAltitude): # print "Going to first point..." point1 = LocationGlobalRelative(-35.361354, 149.165218, 20) - vehicle.commands.goto(point1) + vehicle.simple_goto(point1) # sleep so we can see the change in map time.sleep(3) # print "Going to second point..." point2 = LocationGlobalRelative(-35.363244, 149.168801, 20) - vehicle.commands.goto(point2) + vehicle.simple_goto(point2) # sleep so we can see the change in map time.sleep(3) diff --git a/dronekit/test/sitl/test_locations.py b/dronekit/test/sitl/test_locations.py index 648499428..a7a52fbdb 100644 --- a/dronekit/test/sitl/test_locations.py +++ b/dronekit/test/sitl/test_locations.py @@ -45,11 +45,11 @@ def arm_and_takeoff(aTargetAltitude): assert_equals(vehicle.armed, True) # Take off to target altitude - vehicle.commands.takeoff(aTargetAltitude) + vehicle.simple_takeoff(aTargetAltitude) # Wait until the vehicle reaches a safe height before # processing the goto (otherwise the command after - # Vehicle.commands.takeoff will execute immediately). + # Vehicle.simple_takeoff will execute immediately). while True: # print " Altitude: ", vehicle.location.alt # Test for altitude just below target, in case of undershoot. diff --git a/examples/drone_delivery/drone_delivery.py b/examples/drone_delivery/drone_delivery.py index b754ed30a..0e4374e65 100644 --- a/examples/drone_delivery/drone_delivery.py +++ b/examples/drone_delivery/drone_delivery.py @@ -72,7 +72,7 @@ def launch(self): def takeoff(self): self._log("Taking off") - self.commands.takeoff(30.0) + self.simple_takeoff(30.0) self.vehicle.flush() def arm(self, value=True): @@ -110,14 +110,14 @@ def goto(self, location, relative=None): self._log("Goto: {0}, {1}".format(location, self.altitude)) if relative: - self.commands.goto( + self.simple_goto( LocationGlobalRelative( float(location[0]), float(location[1]), float(self.altitude) ) ) else: - self.commands.goto( + self.simple_goto( LocationGlobal( float(location[0]), float(location[1]), float(self.altitude) diff --git a/examples/follow_me/follow_me.py b/examples/follow_me/follow_me.py index 661213596..1173866b2 100644 --- a/examples/follow_me/follow_me.py +++ b/examples/follow_me/follow_me.py @@ -2,7 +2,7 @@ followme - Tracks GPS position of your computer (Linux only). This example uses the python gps package to read positions from a GPS attached to your -laptop and sends a new vehicle.commands.goto command every two seconds to move the +laptop and sends a new vehicle.simple_goto command every two seconds to move the vehicle to the current point. When you want to stop follow-me, either change vehicle modes or type Ctrl+C to exit the script. @@ -52,10 +52,10 @@ def arm_and_takeoff(aTargetAltitude): time.sleep(1) print "Taking off!" - vehicle.commands.takeoff(aTargetAltitude) # Take off to target altitude + vehicle.simple_takeoff(aTargetAltitude) # Take off to target altitude # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command - # after Vehicle.commands.takeoff will execute immediately). + # after Vehicle.simple_takeoff will execute immediately). while True: print " Altitude: ", vehicle.location.global_relative_frame.alt if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: #Trigger just below target alt. @@ -88,7 +88,7 @@ def arm_and_takeoff(aTargetAltitude): print "Going to: %s" % dest # A better implementation would only send new waypoints if the position had changed significantly - vehicle.commands.goto(dest) + vehicle.simple_goto(dest) # Send a new target every two seconds # For a complete implementation of follow me you'd want adjust this delay diff --git a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py index 4f1d8d355..663c3bf7d 100644 --- a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py +++ b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py @@ -47,10 +47,10 @@ def arm_and_takeoff(aTargetAltitude): time.sleep(1) print "Taking off!" - vehicle.commands.takeoff(aTargetAltitude) # Take off to target altitude + vehicle.simple_takeoff(aTargetAltitude) # Take off to target altitude # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command - # after Vehicle.commands.takeoff will execute immediately). + # after Vehicle.simple_takeoff will execute immediately). while True: print " Altitude: ", vehicle.location.global_relative_frame.alt if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: #Trigger just below target alt. @@ -238,7 +238,7 @@ def get_bearing(aLocation1, aLocation2): MAV_FRAME_GLOBAL_RELATIVE_ALT_INT frame * goto_position_target_local_ned - Sets position using SET_POSITION_TARGET_LOCAL_NED command in MAV_FRAME_BODY_NED frame -* goto - A convenience function that can use Vehicle.commands.goto (default) or +* goto - A convenience function that can use Vehicle.simple_goto (default) or goto_position_target_global_int to travel to a specific position in metres North and East from the current location. This method reports distance to the destination. @@ -301,13 +301,13 @@ def goto_position_target_local_ned(north, east, down): -def goto(dNorth, dEast, gotoFunction=vehicle.commands.goto): +def goto(dNorth, dEast, gotoFunction=vehicle.simple_goto): """ Moves the vehicle to a position dNorth metres North and dEast metres East of the current position. The method takes a function pointer argument with a single `dronekit.lib.LocationGlobal` parameter for the target position. This allows it to be called with different position-setting commands. - By default it uses the standard method: dronekit.lib.Vehicle.commands.goto(). + By default it uses the standard method: dronekit.lib.Vehicle.simple_goto(). The method reports the distance to target every two seconds. """ @@ -413,13 +413,13 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z, duration): """ -Fly a triangular path using the standard Vehicle.commands.goto() method. +Fly a triangular path using the standard Vehicle.simple_goto() method. The method is called indirectly via a custom "goto" that allows the target position to be specified as a distance in metres (North/East) from the current position, and which reports the distance-to-target. """ -print("TRIANGLE path using standard Vehicle.commands.goto()") +print("TRIANGLE path using standard Vehicle.simple_goto()") print("Set speed to 5m/s.") set_speed(5) print("Position North 80 West 50") diff --git a/examples/mission_basic/mission_basic.py b/examples/mission_basic/mission_basic.py index f7e247ac7..ae9e548f3 100644 --- a/examples/mission_basic/mission_basic.py +++ b/examples/mission_basic/mission_basic.py @@ -145,10 +145,10 @@ def arm_and_takeoff(aTargetAltitude): time.sleep(1) print "Taking off!" - vehicle.commands.takeoff(aTargetAltitude) # Take off to target altitude + vehicle.simple_takeoff(aTargetAltitude) # Take off to target altitude # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command - # after Vehicle.commands.takeoff will execute immediately). + # after Vehicle.simple_takeoff will execute immediately). while True: print " Altitude: ", vehicle.location.global_relative_frame.alt if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: #Trigger just below target alt. diff --git a/examples/simple_goto/simple_goto.py b/examples/simple_goto/simple_goto.py index 60f911fcd..f3b0217c4 100644 --- a/examples/simple_goto/simple_goto.py +++ b/examples/simple_goto/simple_goto.py @@ -1,7 +1,7 @@ """ simple_goto.py: GUIDED mode "simple goto" example (Copter Only) -Demonstrates how to arm and takeoff in Copter and how to navigate to points using Vehicle.commands.goto. +Demonstrates how to arm and takeoff in Copter and how to navigate to points using Vehicle.simple_goto. Full documentation is provided at http://python.dronekit.io/examples/simple_goto.html """ @@ -45,10 +45,10 @@ def arm_and_takeoff(aTargetAltitude): time.sleep(1) print "Taking off!" - vehicle.commands.takeoff(aTargetAltitude) # Take off to target altitude + vehicle.simple_takeoff(aTargetAltitude) # Take off to target altitude # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command - # after Vehicle.commands.takeoff will execute immediately). + # after Vehicle.simple_takeoff will execute immediately). while True: print " Altitude: ", vehicle.location.global_relative_frame.alt if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: #Trigger just below target alt. @@ -61,14 +61,14 @@ def arm_and_takeoff(aTargetAltitude): print "Going to first point..." point1 = LocationGlobalRelative(-35.361354, 149.165218, 20) -vehicle.commands.goto(point1) +vehicle.simple_goto(point1) # sleep so we can see the change in map time.sleep(30) print "Going to second point..." point2 = LocationGlobalRelative(-35.363244, 149.168801, 20) -vehicle.commands.goto(point2) +vehicle.simple_goto(point2) # sleep so we can see the change in map time.sleep(30) From 2ff3bae2f1ed9628b2c7878deeb84c2c0a49e1df Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 20 Nov 2015 21:18:02 +1100 Subject: [PATCH 233/475] Fixes to lots of examples and docs for new settable speed, simple_takeoff and simple_goto --- docs/examples/follow_me.rst | 4 +- docs/examples/guided-set-speed-yaw-demo.rst | 10 ++-- docs/examples/simple_goto.rst | 11 ++-- docs/examples/vehicle_state.rst | 4 +- docs/guide/copter/guided_mode.rst | 29 +++++++--- docs/guide/migrating.rst | 21 +++++++- docs/guide/taking_off.rst | 8 +-- docs/guide/vehicle_state_and_parameters.rst | 18 ++++--- dronekit/__init__.py | 59 +++++++++++++++++---- examples/drone_delivery/drone_delivery.py | 4 +- examples/simple_goto/simple_goto.py | 8 +-- examples/vehicle_state/vehicle_state.py | 4 +- 12 files changed, 129 insertions(+), 51 deletions(-) diff --git a/docs/examples/follow_me.rst b/docs/examples/follow_me.rst index d01a5e077..03a9f544a 100644 --- a/docs/examples/follow_me.rst +++ b/docs/examples/follow_me.rst @@ -108,7 +108,7 @@ Most of the example should be fairly familiar as it uses the same code as other :ref:`taking off `, and closing the vehicle object. The example-specific code is shown below. All this does is attempt to get a gps socket and read the location in a two second loop. If it is successful it -reports the value and uses :py:func:`Vehicle.commands.goto ` to move to the new position. The loop exits when +reports the value and uses :py:func:`Vehicle.simple_goto ` to move to the new position. The loop exits when the mode is changed. .. code-block:: python @@ -141,7 +141,7 @@ the mode is changed. print "Going to: %s" % dest # A better implementation would only send new waypoints if the position had changed significantly - vehicle.commands.goto(dest) + vehicle.simple_goto(dest) # Send a new target every two seconds # For a complete implementation of follow me you'd want adjust this delay diff --git a/docs/examples/guided-set-speed-yaw-demo.rst b/docs/examples/guided-set-speed-yaw-demo.rst index b0f32ec58..54a7bcb9e 100644 --- a/docs/examples/guided-set-speed-yaw-demo.rst +++ b/docs/examples/guided-set-speed-yaw-demo.rst @@ -83,7 +83,7 @@ On the command prompt you should see (something like): Altitude: 4.82999992371 Reached target altitude - TRIANGLE path using standard Vehicle.commands.goto() + TRIANGLE path using standard Vehicle.simple_goto() Position North 80 West 50 Distance to target: 100.792762965 Distance to target: 100.25918006 @@ -176,7 +176,7 @@ The example is :ref:`documented in source code `. Ad The functions for controlling vehicle movement are: -* :ref:`Vehicle.commands.goto() ` is the standard +* :ref:`Vehicle.simple_goto() ` is the standard DroneKit position controller method. It is called from :ref:`goto ` to fly a triangular path. * :ref:`goto_position_target_global_int() ` is a position controller that uses the @@ -214,12 +214,12 @@ goto() - convenience function This is a convenience function for setting position targets in metres North and East of the current location. It reports the distance to the target every two seconds and completes when the target is reached. -This takes a function argument of either :ref:`Vehicle.commands.goto() ` or +This takes a function argument of either :ref:`Vehicle.simple_goto() ` or :ref:`goto_position_target_global_int() ` .. code-block:: python - def goto(dNorth, dEast, gotoFunction=vehicle.commands.goto): + def goto(dNorth, dEast, gotoFunction=vehicle.simple_goto): currentLocation=vehicle.location.global_relative_frame targetLocation=get_location_metres(currentLocation, dNorth, dEast) targetDistance=get_distance_metres(currentLocation, targetLocation) @@ -305,7 +305,7 @@ The function ``goto_position_target_global_int()`` generates a `SET_POSITION_TARGET_GLOBAL_INT `_ MAVLink message which is used to directly specify the target location of the vehicle. When used with ``MAV_FRAME_GLOBAL_RELATIVE_ALT_INT`` as shown below, -this method is effectively the same as :ref:`Vehicle.commands.goto `. +this method is effectively the same as :ref:`Vehicle.simple_goto `. .. code-block:: python diff --git a/docs/examples/simple_goto.rst b/docs/examples/simple_goto.rst index 3e9211a2c..33c9235b8 100644 --- a/docs/examples/simple_goto.rst +++ b/docs/examples/simple_goto.rst @@ -5,8 +5,8 @@ Example: Simple Go To (Copter) ============================== This example demonstrates how to arm and launch a Copter in GUIDED mode, travel towards a number of target points, and then return -to the home location. It uses :py:func:`Vehicle.commands.takeoff() `, -:py:func:`Vehicle.commands.goto() ` and :py:attr:`Vehicle.mode `. +to the home location. It uses :py:func:`Vehicle.simple_takeoff() `, +:py:func:`Vehicle.simple_goto() ` and :py:attr:`Vehicle.mode `. The target locations are centred around the home location when the :ref:`Simulated Vehicle ` is booted; you can edit the latitude and longitude to use more appropriate positions for your own vehicle. @@ -93,6 +93,7 @@ On the command prompt you should see (something like): Altitude: 18.7299995422 Altitude: 19.2700004578 Reached target altitude + Set default/target airspeed to 3 Going to first point... Going to second point... Returning to Launch @@ -122,7 +123,7 @@ Takeoff To launch *Copter* you need to first check that the vehicle :py:func:`Vehicle.is_armable `. Then set the mode to ``GUIDED``, arm the vehicle, and call -:py:func:`Vehicle.commands.takeoff() `. The takeoff code in this example +:py:func:`Vehicle.simple_takeoff() `. The takeoff code in this example is explained in the guide topic :ref:`taking-off`. @@ -130,13 +131,13 @@ Flying to a point - Goto ------------------------ The vehicle is already in ``GUIDED`` mode, so to send it to a certain point we just need to -call :py:func:`Vehicle.commands.goto() ` with the target +call :py:func:`Vehicle.simple_goto() ` with the target :py:class:`dronekit.LocationGlobalRelative`: .. code-block:: python point1 = LocationGlobalRelative(-35.361354, 149.165218, 20) - vehicle.commands.goto(point1) + vehicle.simple_goto(point1) # sleep so we can see the change in map time.sleep(30) diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index 80606e3bd..6e2a673a0 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -64,8 +64,6 @@ On the command prompt you should see (something like): Attitude: Attitude:pitch=0.00294387154281,yaw=-0.11805768311,roll=0.00139428151306 Velocity: [-0.03, 0.02, 0.0] GPS: GPSInfo:fix=3,num_sat=10 - Groundspeed: 0.0 - Airspeed: 0.0 Mount status: [None, None, None] Battery: Battery:voltage=12.587,current=0.0,level=100 EKF OK?: False @@ -76,6 +74,8 @@ On the command prompt you should see (something like): Heading: 353 Is Armable?: False System status: STANDBY + Groundspeed: 0.0 + Airspeed: 0.0 Mode: STABILIZE Armed: False Waiting for home location ... diff --git a/docs/guide/copter/guided_mode.rst b/docs/guide/copter/guided_mode.rst index 03e464fc0..abab885f4 100644 --- a/docs/guide/copter/guided_mode.rst +++ b/docs/guide/copter/guided_mode.rst @@ -37,7 +37,7 @@ Position control Controlling the vehicle by explicitly setting the target position is useful when the final position is known/fixed. -The recommended method for position control is :py:func:`Vehicle.commands.goto() `. +The recommended method for position control is :py:func:`Vehicle.simple_goto() `. This takes a :py:class:`LocationGlobal ` or :py:class:`LocationGlobalRelative ` argument. @@ -50,10 +50,10 @@ The method is used as shown below: # Set the target location in global-relative frame a_location = LocationGlobalRelative(-34.364114, 149.166022, 30) - vehicle.commands.goto(a_location) + vehicle.simple_goto(a_location) -``Vehicle.commands.goto()`` can be interrupted by a later command, and does not provide any functionality +``Vehicle.simple_goto()`` can be interrupted by a later command, and does not provide any functionality to indicate when the vehicle has reached its destination. Developers can use either a time delay or :ref:`measure proximity to the target ` to give the vehicle an opportunity to reach its destination. The :ref:`example-guided-mode-setting-speed-yaw` shows both approaches. @@ -67,7 +67,7 @@ When moving the vehicle you can send a separate command to :ref:`control the spe `SET_POSITION_TARGET_LOCAL_NED `_, specifying a ``type_mask`` bitmask that enables the position parameters. The main difference between these commands is that the former allows you to specify the location relative to the "global" frames (like - ``Vehicle.commands.goto()``), while the later lets you specify the location in NED co-ordinates relative + ``Vehicle.simple_goto()``), while the later lets you specify the location in NED co-ordinates relative to the home location or the vehicle itself. For more information on these options see the example code: :ref:`example_guided_mode_goto_position_target_global_int` and :ref:`example_guided_mode_goto_position_target_local_ned`. @@ -255,9 +255,24 @@ Supported commands `Copter Commands in Guided Mode `_ lists all the commands that *can* be sent to Copter in GUIDED mode (in fact most of the commands can be sent in any mode!) -DroneKit-Python provides a friendly Python API that abstracts many of the commands. Where possible you should use the API rather than send messages directly. For example it is better to use :py:func:`Vehicle.commands.takeoff() ` than to explicitly send the ``MAV_CMD_NAV_TAKEOFF`` command. - -Some of the MAV_CMD commands that you might want to send include: :ref:`MAV_CMD_CONDITION_YAW `, :ref:`MAV_CMD_DO_CHANGE_SPEED `, :ref:`MAV_CMD_DO_SET_ROI `, ``MAV_CMD_DO_SET_SERVO``, ``MAV_CMD_DO_REPEAT_SERVO``, ``MAV_CMD_DO_SET_RELAY``, ``MAV_CMD_DO_REPEAT_RELAY``, ``MAV_CMD_DO_FENCE_ENABLE``, ``MAV_CMD_DO_PARACHUTE``, ``MAV_CMD_DO_GRIPPER``, ``MAV_CMD_MISSION_START``. These would be sent in a ``COMMAND_LONG`` message :ref:`as discussed above `. +DroneKit-Python provides a friendly Python API that abstracts many of the commands. +Where possible you should use the API rather than send messages directly. +For example it is better to use :py:func:`Vehicle.simple_takeoff() ` +than to explicitly send the ``MAV_CMD_NAV_TAKEOFF`` command. + +Some of the MAV_CMD commands that you might want to send include: +:ref:`MAV_CMD_CONDITION_YAW `, +:ref:`MAV_CMD_DO_CHANGE_SPEED `, +:ref:`MAV_CMD_DO_SET_ROI `, +``MAV_CMD_DO_SET_SERVO``, +``MAV_CMD_DO_REPEAT_SERVO``, +``MAV_CMD_DO_SET_RELAY``, +``MAV_CMD_DO_REPEAT_RELAY``, +``MAV_CMD_DO_FENCE_ENABLE``, +``MAV_CMD_DO_PARACHUTE``, +``MAV_CMD_DO_GRIPPER``, +``MAV_CMD_MISSION_START``. +These would be sent in a ``COMMAND_LONG`` message :ref:`as discussed above `. diff --git a/docs/guide/migrating.rst b/docs/guide/migrating.rst index c7403a691..2bfa537b9 100644 --- a/docs/guide/migrating.rst +++ b/docs/guide/migrating.rst @@ -5,7 +5,7 @@ Migrating to DKPY 2.0 ===================== DroneKit-Python 2.0 has undergone a significant *architectural* evolution when compared to version 1.x (the library changed from a MAVProxy extension -to a standalone Python module). The API itself remains largely compatible, with the most important difference being that you +to a standalone Python module). The API itself remains similar, with the most important difference being that you now need to specify the vehicle target address inside the script. The sections below outline the main migration areas. @@ -188,7 +188,24 @@ For more information see: :py:attr:`Vehicle.location :py:attr:`Vehicle.location.global_frame `, :py:attr:`Vehicle.location.global_relative_frame `, :py:attr:`Vehicle.location.local_frame `, and :ref:`vehicle-information`. - + + +Takeoff and movement commands +----------------------------- + +DroneKit-Python v1.x provided guided mode takeoff and movement methods ``Vehicle.commands.takeoff()`` +and ``Vehicle.commands.goto()``. + +DKPY2.0 instead provides :py:func:`Vehicle.simple_takeoff ` and +:py:func:`Vehicle.simple_goto `. These are the same as the old methods +except that ``simple_goto`` allows you to optionally set the default target groundspeed and airspeed. + + +:py:attr:`Vehicle.airspeed ` and +:py:attr:`Vehicle.groundspeed ` are now settable values. Call these to +set the default target speed used when moving with :py:func:`Vehicle.simple_goto ` +(or other position-based movement commands). + .. _migrating_dkpy2_0_home_location: diff --git a/docs/guide/taking_off.rst b/docs/guide/taking_off.rst index ee856db1a..9c5db2fe5 100644 --- a/docs/guide/taking_off.rst +++ b/docs/guide/taking_off.rst @@ -6,7 +6,7 @@ Taking Off This article explains how to get your *Copter* to take off. At high level, the steps are: check that the vehicle is able to arm (can pass pre-arm checks), set the mode to ``GUIDED``, arm the vehicle, -and then call :py:func:`Vehicle.commands.takeoff() `. +and then call :py:func:`Vehicle.simple_takeoff() `. .. todo:: @@ -53,7 +53,7 @@ The code below shows a function to arm a Copter, take off, and fly to a specifie print "Taking off!" # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command - # after Vehicle.commands.takeoff will execute immediately). + # after Vehicle.simple_takeoff will execute immediately). while True: print " Altitude: ", vehicle.location.global_relative_frame.alt if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. @@ -100,7 +100,7 @@ vehicle has booted, EKF is ready, and it has a GPS lock. These checks are encaps Once the vehicle is ready we set the mode to ``GUIDED`` and arm it. We then wait until arming is confirmed -before sending the :py:func:`takeoff ` command. +before sending the :py:func:`takeoff ` command. .. code-block:: python @@ -114,7 +114,7 @@ before sending the :py:func:`takeoff ` command time.sleep(1) print "Taking off!" - vehicle.commands.takeoff(aTargetAltitude) # Take off to target altitude + vehicle.simple_takeoff(aTargetAltitude) # Take off to target altitude The ``takeoff`` command is asynchronous and can be interrupted if another command arrives before it reaches the target altitude. This could have potentially serious consequences if the vehicle is commanded to move diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index d8dbbde55..b6c935f23 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -26,8 +26,6 @@ Vehicle state information is exposed through vehicle *attributes*. DroneKit-Pyth :py:attr:`Vehicle.location.local_frame `, :py:attr:`Vehicle.attitude `, :py:attr:`Vehicle.velocity `, -:py:attr:`Vehicle.airspeed `, -:py:attr:`Vehicle.groundspeed `, :py:attr:`Vehicle.gps_0 `, :py:attr:`Vehicle.mount_status `, :py:attr:`Vehicle.battery `, @@ -38,6 +36,8 @@ Vehicle state information is exposed through vehicle *attributes*. DroneKit-Pyth :py:func:`Vehicle.system_status `, :py:func:`Vehicle.heading `, :py:func:`Vehicle.is_armable `, +:py:attr:`Vehicle.airspeed `, +:py:attr:`Vehicle.groundspeed `, :py:attr:`Vehicle.armed `, :py:attr:`Vehicle.mode `. @@ -46,6 +46,8 @@ Attributes are initially created with ``None`` values for their members. In most All of the attributes can be :ref:`read `, but only the :py:attr:`Vehicle.home_location `, +:py:attr:`Vehicle.airspeed `, +:py:attr:`Vehicle.groundspeed `, :py:attr:`Vehicle.mode ` and :py:attr:`Vehicle.armed ` status can be :ref:`written `. @@ -112,7 +114,8 @@ regularly updated from MAVLink messages sent by the vehicle). Setting attributes ------------------ -Only the :py:attr:`Vehicle.mode ` and :py:attr:`Vehicle.armed ` +Only the :py:attr:`Vehicle.mode ` :py:attr:`Vehicle.armed ` +, :py:attr:`Vehicle.airspeed ` and :py:attr:`Vehicle.groundspeed `, attributes can be written (``Vehicle.home_location`` is a special case, as :ref:`discussed below `). The attributes are set by assigning a value: @@ -121,12 +124,15 @@ The attributes are set by assigning a value: #disarm the vehicle vehicle.armed = False - + + #set the default groundspeed to be used in movement commands + vehicle.groundspeed = 3.2 .. warning:: Changing a value is **not guaranteed to succeed**. - For example, vehicle arming can fail if the vehicle doesn't pass pre-arming checks. + For example, vehicle arming can fail if the vehicle doesn't pass pre-arming checks, + and it is possible that the message will not even arrive at the vehicle. While the autopilot does send information about the success (or failure) of the request, this is `not currently handled by DroneKit `_. @@ -142,7 +148,7 @@ to confirm they have changed before proceeding. while not vehicle.mode.name=='GUIDED' and not vehicle.armed and not api.exit: print " Getting ready to take off ..." time.sleep(1) - + .. _vehicle_state_observe_attributes: diff --git a/dronekit/__init__.py b/dronekit/__init__.py index a0d04c6cb..65f879f4a 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -18,9 +18,9 @@ Asynchronous notification on vehicle attribute changes is available by registering listeners/observers. Vehicle movement is primarily controlled using the :py:attr:`Vehicle.armed` attribute and -:py:func:`Vehicle.simple_takeoff() ` and -:py:attr:`Vehicle.simple_goto() ` in GUIDED mode. -Control over speed, direction, altitude, camera trigger and any other aspect of the vehicle is supported using custom MAVLink messages +:py:func:`Vehicle.simple_takeoff` and :py:attr:`Vehicle.simple_goto` in GUIDED mode. +Control over speed, direction, altitude, camera trigger and any other aspect of the vehicle is supported +using custom MAVLink messages (:py:func:`Vehicle.send_mavlink`, :py:func:`Vehicle.message_factory`). It is also possible to work with vehicle "missions" using the :py:attr:`Vehicle.commands` attribute, and run them in AUTO mode. @@ -780,8 +780,7 @@ class Vehicle(HasObservers): Parameters can be iterated and are also individually observable. Vehicle movement is primarily controlled using the :py:attr:`armed` attribute and - :py:func:`Vehicle.simple_takeoff() ` and - :py:func:`Vehicle.simple_goto() ` in GUIDED mode. + :py:func:`simple_takeoff` and :py:func:`simple_goto` in GUIDED mode. It is also possible to work with vehicle "missions" using the :py:attr:`commands` attribute, and run them in AUTO mode. @@ -1480,7 +1479,11 @@ def heading(self): @property def groundspeed(self): """ - Groundspeed in metres/second (``double``). + Current groundspeed in metres/second (``double``). + + This attribute is settable. The set value is the default target groundspeed + when moving the vehicle using :py:func:`simple_goto` (or other position-based + movement commands). """ return self._groundspeed @@ -1499,10 +1502,15 @@ def groundspeed(self, speed): # send command to vehicle self.send_mavlink(msg) + @property def airspeed(self): """ Current airspeed in metres/second (``double``). + + This attribute is settable. The set value is the default target airspeed + when moving the vehicle using :py:func:`simple_goto` (or other position-based + movement commands). """ return self._airspeed @@ -1636,8 +1644,7 @@ def commands(self): """ Gets the editable waypoints/current mission for this vehicle (:py:class:`CommandSequence`). - This can be used to get, create, and modify a mission. It can also be used for direct control of vehicle position - (outside missions) using the :py:func:`goto ` method. + This can be used to get, create, and modify a mission. :returns: A :py:class:`CommandSequence` containing the waypoints for this vehicle. """ @@ -1650,7 +1657,28 @@ def parameters(self): """ return self._parameters + def simple_takeoff(self, alt=None): + """ + Take off and fly the vehicle to the specified altitude (in metres) and then wait for another command. + + .. note:: + + This function should only be used on Copter vehicles. + + + The vehicle must be in GUIDED mode and armed before this is called. + + There is no mechanism for notification when the correct altitude is reached, + and if another command arrives before that point (e.g. :py:func:`simple_goto`) it will be run instead. + + .. warning:: + + Apps should code to ensure that the vehicle will reach a safe altitude before + other commands are executed. A good example is provided in the guide topic :doc:`guide/taking_off`. + + :param alt: Target height, in metres. + """ if alt is not None: altitude = float(alt) if math.isnan(alt) or math.isinf(alt): @@ -1661,19 +1689,28 @@ def simple_takeoff(self, alt=None): def simple_goto(self, location, airspeed=None, groundspeed=None): ''' Go to a specified global location (:py:class:`LocationGlobal` or :py:class:`LocationGlobalRelative`). + + There is no mechanism for notification when the target location is reached, and if another command arrives + before that point that will be executed immediately. + + You can optionally set the desired airspeed or groundspeed (this is identical to setting + :py:attr:`airspeed` or :py:attr:`groundspeed`). The vehicle will determine what speed to + use if the values are not set or if they are both set. The method will change the :py:class:`VehicleMode` to ``GUIDED`` if necessary. .. code:: python - # Set mode to guided - this is optional as the goto method will change the mode if needed. + # Set mode to guided - this is optional as the simple_goto method will change the mode if needed. vehicle.mode = VehicleMode("GUIDED") # Set the LocationGlobal to head towards a_location = LocationGlobal(-34.364114, 149.166022, 30) vehicle.simple_goto(a_location) - :param LocationGlobal location: The target location. + :param location: The target location (:py:class:`LocationGlobal` or :py:class:`LocationGlobalRelative`). + :param airspeed: Target airspeed in m/s (optional). + :param groundspeed: Target groundspeed in m/s (optional). ''' if isinstance(location, LocationGlobalRelative): frame = mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT @@ -2130,7 +2167,7 @@ class CommandSequence(object): The vehicle must be in ``GUIDED`` mode and armed before this is called. There is no mechanism for notification when the correct altitude is reached, and if another command arrives - before that point (e.g. :py:func:`goto`) it will be run instead. + before that point (e.g. :py:func:`simple_goto`) it will be run instead. .. warning:: diff --git a/examples/drone_delivery/drone_delivery.py b/examples/drone_delivery/drone_delivery.py index 0e4374e65..6f38e11be 100644 --- a/examples/drone_delivery/drone_delivery.py +++ b/examples/drone_delivery/drone_delivery.py @@ -72,8 +72,8 @@ def launch(self): def takeoff(self): self._log("Taking off") - self.simple_takeoff(30.0) - self.vehicle.flush() + self.vehicle.simple_takeoff(30.0) + def arm(self, value=True): if value: diff --git a/examples/simple_goto/simple_goto.py b/examples/simple_goto/simple_goto.py index f3b0217c4..511d32800 100644 --- a/examples/simple_goto/simple_goto.py +++ b/examples/simple_goto/simple_goto.py @@ -56,8 +56,10 @@ def arm_and_takeoff(aTargetAltitude): break time.sleep(1) -arm_and_takeoff(20) +arm_and_takeoff(10) +print "Set default/target airspeed to 3" +vehicle.airspeed=3 print "Going to first point..." point1 = LocationGlobalRelative(-35.361354, 149.165218, 20) @@ -66,9 +68,9 @@ def arm_and_takeoff(aTargetAltitude): # sleep so we can see the change in map time.sleep(30) -print "Going to second point..." +print "Going to second point (groundspeed set to 10 m/s) ..." point2 = LocationGlobalRelative(-35.363244, 149.168801, 20) -vehicle.simple_goto(point2) +vehicle.simple_goto(point2, groundspeed=10) # sleep so we can see the change in map time.sleep(30) diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 04aab4fd8..1e973e8c5 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -31,8 +31,6 @@ print " Attitude: %s" % vehicle.attitude print " Velocity: %s" % vehicle.velocity print " GPS: %s" % vehicle.gps_0 -print " Groundspeed: %s" % vehicle.groundspeed -print " Airspeed: %s" % vehicle.airspeed print " Mount status: %s" % vehicle.mount_status print " Battery: %s" % vehicle.battery print " EKF OK?: %s" % vehicle.ekf_ok @@ -43,6 +41,8 @@ print " Heading: %s" % vehicle.heading print " Is Armable?: %s" % vehicle.is_armable print " System status: %s" % vehicle.system_status.state +print " Groundspeed: %s" % vehicle.groundspeed # settable +print " Airspeed: %s" % vehicle.airspeed # settable print " Mode: %s" % vehicle.mode.name # settable print " Armed: %s" % vehicle.armed # settable From ad1d6e7794834ffa974ed60ae23ea44d779425cf Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 20 Nov 2015 12:24:38 +1100 Subject: [PATCH 234/475] Fixes to mission_basic.py example and related docs --- docs/examples/mission_basic.rst | 5 +++-- docs/guide/auto_mode.rst | 11 +---------- examples/mission_basic/mission_basic.py | 10 +++++++--- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/docs/examples/mission_basic.rst b/docs/examples/mission_basic.rst index 97a67d065..746c97f50 100644 --- a/docs/examples/mission_basic.rst +++ b/docs/examples/mission_basic.rst @@ -151,7 +151,7 @@ gets the distance to the next waypoint and :py:func:`Vehicle.commands.next ` gets the value of the next command. -We also show how to move to a specified command using +We also show how to jump to a specified command using :py:func:`Vehicle.commands.next ` (note how we skip the third command below): .. code:: python @@ -185,7 +185,8 @@ This example has no known issues. Source code =========== -The full source code at documentation build-time is listed below (`current version on github `_): +The full source code at documentation build-time is listed below +(`current version on Github `_): .. literalinclude:: ../../examples/mission_basic/mission_basic.py :language: python diff --git a/docs/guide/auto_mode.rst b/docs/guide/auto_mode.rst index 6c8a29fb1..4fe9e168b 100644 --- a/docs/guide/auto_mode.rst +++ b/docs/guide/auto_mode.rst @@ -400,7 +400,7 @@ Get distance to waypoint lat=missionitem.x lon=missionitem.y alt=missionitem.z - targetWaypointLocation=LocationGlobal(lat,lon,alt) + targetWaypointLocation=LocationGlobalRelative(lat,lon,alt) distancetopoint = get_distance_metres(vehicle.location.global_frame, targetWaypointLocation) return distancetopoint @@ -423,12 +423,3 @@ Useful Links * `MAVLink mission command messages `_ (all vehicle types - wiki). - -.. _auto_mode_mission_known_issues: - -Known Issues -============ - -AUTO Mode/mission control has the following known issues (at time of writing): - -* `#390 Vehicle.commands.next is not writeable <#https://github.com/dronekit/dronekit-python/issues/390>`_. \ No newline at end of file diff --git a/examples/mission_basic/mission_basic.py b/examples/mission_basic/mission_basic.py index ae9e548f3..e811ff859 100644 --- a/examples/mission_basic/mission_basic.py +++ b/examples/mission_basic/mission_basic.py @@ -4,7 +4,7 @@ Full documentation is provided at http://python.dronekit.io/examples/mission_basic.html """ -from dronekit import connect, VehicleMode, LocationGlobal, Command +from dronekit import connect, VehicleMode, LocationGlobalRelative, LocationGlobal, Command import time import math from pymavlink import mavutil @@ -156,8 +156,8 @@ def arm_and_takeoff(aTargetAltitude): break time.sleep(1) - -print 'Create a new mission' + +print 'Create a new mission (for current location)' adds_square_mission(vehicle.location.global_frame,50) @@ -165,6 +165,9 @@ def arm_and_takeoff(aTargetAltitude): arm_and_takeoff(10) print "Starting mission" +# Reset mission set to first (0) waypoint +vehicle.commands.next=0 + # Set mode to AUTO to start mission vehicle.mode = VehicleMode("AUTO") @@ -173,6 +176,7 @@ def arm_and_takeoff(aTargetAltitude): # Demonstrates getting and setting the command number # Uses distance_to_current_waypoint(), a convenience function for finding the # distance to the next waypoint. + while True: nextwaypoint=vehicle.commands.next print 'Distance to waypoint (%s): %s' % (nextwaypoint, distance_to_current_waypoint()) From a323c18ee4eadc6b550ec41bc12c03cd7fc4fae8 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 20 Nov 2015 12:30:07 +1100 Subject: [PATCH 235/475] Modify example to use wait_ready when downloading commands --- examples/mission_import_export/mission_import_export.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/mission_import_export/mission_import_export.py b/examples/mission_import_export/mission_import_export.py index c55bc0ad6..8669ce6c8 100644 --- a/examples/mission_import_export/mission_import_export.py +++ b/examples/mission_import_export/mission_import_export.py @@ -87,7 +87,7 @@ def download_mission(): missionlist=[] cmds = vehicle.commands cmds.download() - cmds.wait_valid() + cmds.wait_ready() for cmd in cmds: missionlist.append(cmd) return missionlist From 21c9bcd077dcf63c8482ceb89f330e8ecbf20581 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 20 Nov 2015 12:40:10 +1100 Subject: [PATCH 236/475] Minor fix to create attribute docs to explain when cache should be called --- docs/examples/create_attribute.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/examples/create_attribute.rst b/docs/examples/create_attribute.rst index 45bed93ca..b44480180 100644 --- a/docs/examples/create_attribute.rst +++ b/docs/examples/create_attribute.rst @@ -202,8 +202,8 @@ the attribute and then notifies all observers. should be called every time there is an update from the vehicle. You can set a third parameter (``cache=True``) so that it only invokes the listeners when the value *changes*. - This is normally used for vehicle state information like ``Vehicle.mode``, where the value is updated - regularly from the vehicle client code is only interested in attribute changes. + This is normally used for attributes like the vehicle mode, where the information is updated + regularly from the vehicle, but client code is only interested when the attribute changes. You should not set ``cache=True`` for attributes that represent sensor information or other "live" information, including the RAW_IMU attribute demonstrated here. Clients can then implement their own caching strategy if needed. From 61922591d590490fd486e6cb3f3271e9677b4b43 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 20 Nov 2015 13:41:02 +1100 Subject: [PATCH 237/475] Fixes to follow_me example docs due to changed LocationGlobalRelative --- docs/examples/follow_me.rst | 2 +- examples/follow_me/follow_me.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/examples/follow_me.rst b/docs/examples/follow_me.rst index 03a9f544a..4f7e44d81 100644 --- a/docs/examples/follow_me.rst +++ b/docs/examples/follow_me.rst @@ -137,7 +137,7 @@ the mode is changed. # Once we have a valid location (see gpsd documentation) we can start moving our vehicle around if (gpsd.valid & gps.LATLON_SET) != 0: altitude = 30 # in meters - dest = LocationGlobal(gpsd.fix.latitude, gpsd.fix.longitude, altitude, is_relative=True) + dest = LocationGlobalRelative(gpsd.fix.latitude, gpsd.fix.longitude, altitude) print "Going to: %s" % dest # A better implementation would only send new waypoints if the position had changed significantly diff --git a/examples/follow_me/follow_me.py b/examples/follow_me/follow_me.py index 1173866b2..581c5c0c4 100644 --- a/examples/follow_me/follow_me.py +++ b/examples/follow_me/follow_me.py @@ -10,7 +10,7 @@ Example documentation: http://python.dronekit.io/examples/follow_me.html """ -from dronekit import connect, VehicleMode, LocationGlobal +from dronekit import connect, VehicleMode, LocationGlobalRelative import gps import socket import time From 3a3e91c8e5704b2affdc0ea23c952fe0725fe322 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 20 Nov 2015 14:09:31 +1100 Subject: [PATCH 238/475] Fix a few typos in the channel_overrides example docs --- docs/examples/channel_overrides.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/examples/channel_overrides.rst b/docs/examples/channel_overrides.rst index b571d14c7..fda53187f 100644 --- a/docs/examples/channel_overrides.rst +++ b/docs/examples/channel_overrides.rst @@ -9,14 +9,14 @@ This example shows how to get channel information and to get/set channel-overrid .. warning:: - Channel overrides (a.k.a "RC overrides") are highly discommended (they are primarily implemented + Channel overrides (a.k.a. "RC overrides") are highly dis-commended (they are primarily intended for simulating user input and when implementing certain types of joystick control). Instead use the appropriate MAVLink commands like DO_SET_SERVO/DO_SET_RELAY, or more generally set the desired position or direction/speed. If you have no choice but to use a channel-override please explain why in a - `github issue `_ and we will attempt to find a + `Github issue `_ and we will attempt to find a better alternative. @@ -123,8 +123,8 @@ from the UAV, based on the RC inputs from the transmitter. These can be read eit print " Ch1: %s" % vehicle.channels['1'] print " Ch2: %s" % vehicle.channels['2'] -You can override the values sent to the vehicle by the autopilot using :py:attr:`Vehicle.channels.overrides ` -(although this is not recommended)! The overrides can be written individually using an indexing syntax or as a set using a dictionary syntax. +You can override the values sent to the vehicle by the autopilot using :py:attr:`Vehicle.channels.overrides `. +The overrides can be written individually using an indexing syntax or as a set using a dictionary syntax. .. code:: python From ceacc12914d441b38c6480aceb76859f6538dfa9 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 20 Nov 2015 14:49:47 +1100 Subject: [PATCH 239/475] Fix error due to incorrect access of location in callback in drone_delivery --- docs/examples/drone_delivery.rst | 42 +++++++++-------------- examples/drone_delivery/drone_delivery.py | 6 ++-- 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/docs/examples/drone_delivery.rst b/docs/examples/drone_delivery.rst index aeec2fb43..ae2caef11 100644 --- a/docs/examples/drone_delivery.rst +++ b/docs/examples/drone_delivery.rst @@ -63,28 +63,17 @@ On the command prompt you should see (something like): .. code-block:: bash - \dronekit-python\examples\drone_delivery>drone_delivery.py - local path: E:\deleteme\dronekit-python\examples\drone_delivery Connecting to vehicle on: 127.0.0.1:14550 - >>> ☺APM:Copter V3.4-dev (e0810c2e) - >>> ☺Frame: QUAD - connected ... + >>> Frame: QUAD + [DEBUG]: Connected to vehicle. [DEBUG]: DroneDelivery Start - [DEBUG]: Waiting for GPS Lock - [DEBUG]: DroneDelivery Armed Callback - [DEBUG]: GPS: GPSInfo:fix=3,num_sat=10 + [DEBUG]: Waiting for ability to arm... [DEBUG]: Running initial boot sequence - [DEBUG]: Arming + [DEBUG]: Changing to mode: GUIDED + [DEBUG]: Waiting for arming... [DEBUG]: Taking off - [DEBUG]: Mode: GUIDED - INFO:cherrypy.error:[21/Oct/2015:16:33:15] ENGINE Bus STARTING - INFO:cherrypy.error:[21/Oct/2015:16:33:15] ENGINE Started monitor thread 'Autoreloader'. - INFO:cherrypy.error:[21/Oct/2015:16:33:15] ENGINE Started monitor thread '_TimeoutMonitor'. - INFO:cherrypy.error:[21/Oct/2015:16:33:15] ENGINE Serving on http://0.0.0.0:8080 - INFO:cherrypy.error:[21/Oct/2015:16:33:15] ENGINE Bus STARTED - >>> ☺ARMING MOTORS - >>> ☺Initialising APM... - ... + http://localhost:8080/ + [DEBUG]: Goto: [u'-35.4', u'149.2'], 29.98 Screenshots @@ -110,21 +99,24 @@ For instance, `drone_delivery.py `. + Starting CherryPy from a DroneKit application diff --git a/examples/drone_delivery/drone_delivery.py b/examples/drone_delivery/drone_delivery.py index 6f38e11be..83ba0d28f 100644 --- a/examples/drone_delivery/drone_delivery.py +++ b/examples/drone_delivery/drone_delivery.py @@ -10,7 +10,7 @@ import simplejson import time from pymavlink import mavutil -from dronekit import connect, VehicleMode, LocationGlobal +from dronekit import connect, VehicleMode, LocationGlobal, LocationGlobalRelative import cherrypy from cherrypy.process import wspbus, plugins from jinja2 import Environment, FileSystemLoader @@ -130,9 +130,9 @@ def get_location(self): def location_callback(self, vehicle, name, location): if location.global_relative_frame.alt is not None: - self.altitude = location.alt + self.altitude = location.global_relative_frame.alt - self.current_location = location + self.current_location = location.global_relative_frame def _log(self, message): print "[DEBUG]: {0}".format(message) From 922981907b7180cd395fe448f877364a612a0a53 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 20 Nov 2015 14:56:09 +1100 Subject: [PATCH 240/475] improve description of how example works --- docs/examples/drone_delivery.rst | 36 +++++++++++++++++++------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/docs/examples/drone_delivery.rst b/docs/examples/drone_delivery.rst index ae2caef11..2500f8375 100644 --- a/docs/examples/drone_delivery.rst +++ b/docs/examples/drone_delivery.rst @@ -56,24 +56,30 @@ In summary, after cloning the repository: The ``--connect`` parameter above connects to SITL on udp port 127.0.0.1:14550. This is the default value for the parameter, and may be omitted. -#. After a short while you should be able to reach your new webserver at http://localhost:8080. + On the command prompt you should see (something like): + .. code-block:: bash -On the command prompt you should see (something like): - -.. code-block:: bash + Connecting to vehicle on: 127.0.0.1:14550 + >>> Frame: QUAD + [DEBUG]: Connected to vehicle. + [DEBUG]: DroneDelivery Start + [DEBUG]: Waiting for ability to arm... + [DEBUG]: Running initial boot sequence + [DEBUG]: Changing to mode: GUIDED + [DEBUG]: Waiting for arming... + [DEBUG]: Taking off + http://localhost:8080/ + +#. After a short while you should be able to reach your new webserver at http://localhost:8080. + The command prompt will show something like + + .. code-block:: bash - Connecting to vehicle on: 127.0.0.1:14550 - >>> Frame: QUAD - [DEBUG]: Connected to vehicle. - [DEBUG]: DroneDelivery Start - [DEBUG]: Waiting for ability to arm... - [DEBUG]: Running initial boot sequence - [DEBUG]: Changing to mode: GUIDED - [DEBUG]: Waiting for arming... - [DEBUG]: Taking off - http://localhost:8080/ - [DEBUG]: Goto: [u'-35.4', u'149.2'], 29.98 + [DEBUG]: Goto: [u'-35.4', u'149.2'], 29.98 + + On the web server you can use the **Command** button to set a target location and + the **Track** button to view the moving vehicle (see the screenshots below). Screenshots From f58deddd377c36747a109dcf2d503896e08e6b03 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 23 Nov 2015 12:42:52 +1100 Subject: [PATCH 241/475] Remove CommandSequence.takeoff docs. Update simple_goto.py example and associated docs --- docs/examples/simple_goto.rst | 59 ++++++++++-------- .../simple_goto_example_copter_path.png | Bin 193312 -> 31566 bytes docs/guide/taking_off.rst | 18 ++++-- dronekit/__init__.py | 19 ------ examples/simple_goto/simple_goto.py | 9 +-- 5 files changed, 52 insertions(+), 53 deletions(-) diff --git a/docs/examples/simple_goto.rst b/docs/examples/simple_goto.rst index 33c9235b8..576f78c0b 100644 --- a/docs/examples/simple_goto.rst +++ b/docs/examples/simple_goto.rst @@ -20,7 +20,7 @@ you can edit the latitude and longitude to use more appropriate positions for yo .. figure:: simple_goto_example_copter_path.png - :width: 50 % + :width: 75 % :alt: Setting destination using position and changing speed and ROI Simple Goto Example: Flight path @@ -67,35 +67,27 @@ On the command prompt you should see (something like): .. code-block:: bash Connecting to vehicle on: 127.0.0.1:14550 - >>> APM:Copter V3.4-dev (e0810c2e) + >>> APM:Copter V3.4-dev (d52279af) >>> Frame: QUAD Basic pre-arm checks - Waiting for vehicle to initialise... - Waiting for vehicle to initialise... - Waiting for vehicle to initialise... - Waiting for vehicle to initialise... - Waiting for vehicle to initialise... Arming motors Waiting for arming... - Waiting for arming... - Waiting for arming... >>> ARMING MOTORS - >>> GROUND START - Waiting for arming... - Waiting for arming... >>> Initialising APM... Taking off! Altitude: 0.0 - Altitude: 0.00999999977648 - Altitude: 0.25 - Altitude: 0.5 - ... - Altitude: 18.7299995422 - Altitude: 19.2700004578 + Altitude: 0.0 + Altitude: 0.1 + Altitude: 1.25 + Altitude: 3.08 + Altitude: 5.14 + Altitude: 7.28 + Altitude: 9.2 + Altitude: 9.71 Reached target altitude Set default/target airspeed to 3 - Going to first point... - Going to second point... + Going towards first point for 30 seconds ... + Going towards second point for 30 seconds (groundspeed set to 10 m/s) ... Returning to Launch Close vehicle object @@ -136,16 +128,32 @@ call :py:func:`Vehicle.simple_goto() ` with the ta .. code-block:: python + # set the default travel speed + vehicle.airspeed=3 + point1 = LocationGlobalRelative(-35.361354, 149.165218, 20) vehicle.simple_goto(point1) # sleep so we can see the change in map time.sleep(30) -Without some sort of "wait" the next command would be executed immediately. In this example we just -sleep for 30 seconds, set a new destination and then sleep another 30 seconds (the vehicle doesn't reach -its target destination in either 30 second wait). The script doesn't report anything during these sleep periods, -but you can observe the vehicle's movement on a ground station map. +.. tip:: + + Without some sort of "wait" the next command would be executed immediately. In this example we just + sleep for 30 seconds before executing the next command. + +When moving towards the first point we set the airspeed using the :py:attr:`Vehicle.airspeed ` +attribute. For the second point the example specifies the target groundspeed when calling +:py:func:`Vehicle.simple_goto() ` + +.. code-block:: python + + vehicle.simple_goto(point2, groundspeed=10) + +.. tip:: + + The script doesn't report anything during the sleep periods, + but you can observe the vehicle's movement on a ground station map. @@ -153,7 +161,8 @@ but you can observe the vehicle's movement on a ground station map. RTL - Return to launch ------------------------ -To return to the home position and land, we set the mode to ``RTL``: +To return to the home position and land, we set the mode to ``RTL``. +The vehicle travels at the previously set default speed: .. code-block:: python diff --git a/docs/examples/simple_goto_example_copter_path.png b/docs/examples/simple_goto_example_copter_path.png index d5d3b28ded3a318ed4194c09fe48b29cdcf9025d..6c6f1f93d03fd1fb0ce77495fa8daa4ee1f2efa3 100644 GIT binary patch literal 31566 zcmZ6yby!qg)ILl~N=kS4NT;HNq;$t1Asx~K3@9BEB3(*@)X+Ht(hW-YNFzBk3dZk@ z&-=dDcYS|w37&Ii@3YpuV&C_gI9+Yk`-Jp_7#JA$)zy^sF)*+~FfcIV@UejZ@w}zL z2mZnI(N|T(fK4*)1ApK+DrhNSVAQ`O`elO){7vAgX6A!|LE(%3!9+T+1YlqUZK*3O z7zS7!e;}}Y;F$AwL}bg&e?I$h%F(3uAF;*}Z3k|6qx!CzXsY_7VwnkNke00|_aN=o zeSH46c&wRk3wYnY#d{kYzUs}JiB-gk^%gH+AYm{|E}Qe$o4Hp84_^66t%2v(UKu?J z?#gcoIIL-{94qVkjkrR*!nJ&~aKbd{*JO3HPDG$+dK#B5-&EiPxTxw zP6~03kppo%IadU}?w10?a2%V=B!4~m`sw_4{;2uqn>iBV4hPs|d#Ne`n5e)TTfC5R z4&rEC6QzKgvH1mQA8FE-^jkJS6l{&|x#Dz{xzKKXLvN3qj z>LeoICDB54VUOJOckn(uw$coxguD_!9Dw&Do*}ssB1}z`DAy)uiDoV_lOeweUqLhF zEh6iMQz50NlfHZtyQiQ6*W$nH_NZyccwt)GQe$Tw=dwcOPV#cn(CHVy@M?oHqbbOv zl|EImaTY!<&32tx%yNuSmYLim-~zbu+awo{wQc1 zcj|eo*cBE^ZA|7pLO_Kj6m93?fED;OUc7z|!4_){M9T+wN#A{JvW?HCpLFOq^n%yd zeB{qzTvb&xmbl?{aZgQ@9(y>pm?)o4(9?-sb*4go|z--8>@pQt_%VNOLgF zdxWM^9R9;iY?KB|bywsN!GAZA9lEILsOlDKYBb{i9k30V#(%fLfvO~wkyZ$bB{>Ie zFftvxTgH81MOAjMh^T&(3tZ4SO@uJLX(>?BPG$~AXiCRrBLpUopLYst{kuvw1rMbx ziCOp8AiE|ThW{Yqe|d(OFrxC?3LB znte*bj{J622HEG(mL|B*ML{jY6CDt^$L zOoS#rKCt&}`Of%&g?b3C49_-rW=j(#`@^jVj-=}yJI-Wfe5w=|IT+`Ig~EdAs>t%# zqTe%zL7_9=NZjup8@(bIdyfbJ%Q#>4sS~isBtfZhHbZ_O4S+2>HbadIdwPu$EEN99 zHnM_Z7Yy~|M7{OW9)|A@W+MIa%yFevgJR`LBUot_18Lr8+YMb3Fmf2;)P9ivLclM5 z3aZPa{3iDf;p#CA2f_yz=NxpOOMhxl#s)bcU;^S8mU(|WUcoYnh&=>X@8ImS4Z|ZZ z06e_kzsM6tiC!%?JuDTcw0ipW4o-~5;R>IEbZ9gML1LdzZ-RiGn5YUHkm$tauVE2i zs0ZMYq4>T^Y0(rFUIE&tuhWq`^P>G|n@}ntO9L`JG3)iKoOs_8=20RZo_rWx|1G+| zeDw0(;9Ai zz1*!l01XLkHxRl!*2g%&W6bm#oZ{RX7u={Es&CK*AZCEz0(LXW@%6qQ-~q*slB}IP z0A^-vC=F@(d*Qn5#x7KVEyH|@c3N6}wRr)obIMF8m?<2dHUXcB;Mcl->I`1}1rYz!LvmNS}5i z8TyV7U_zXdT?v`q=DW|{>Kg8efesk(^aS9oA+q0pKw2LZ{sEDmUPC!Hkqp^~ zux0+_hh97UWAME_HPVd&crL4Sq=s`e8)Lb+Qk7*Kg-?*lJ6|!F zR{m3@1lKlL0KiKi`UPT?;tE*s-gRP&rwwxhp8{mbk3Ba?T=o*<_Yi_iGG3(LciL)u zoh~24p#-J4rt(~ZO|X9LPqMZD%TP%oqq^+e;ONde)8s{Mo$vejk=?oo*QiZ!FBh>$ zni`3}eH$UM0%I{x+Vpe$1Tv)GY0r5Mq#dxK9nL{kGm18=FZ;CvWf09@1&1>b5Fw;` z2v?oXZLs2V9F3X-ffl<1zdR^cter2;UVo2CqWt@RHv6dHiz>>CKBd57PlgC3c@-G# zf)U<3qPv$M0C8kg=P)WD_fj~V!(?J8re?_T^~igHgozjLQxa1!%iqg|a}MiUBr*3J zgl{64z@Et-yPUud1Mu|_hl_##108~5VlG=Gu4Oxgg00-+DJ~!{Y6f7OdyoPKu8qVC0LZ2d=%dOIU!Y|1l zpeR6W0NyB(xFiSxZMSlc09A7Yk*D#qScwrhcOS<8CzH{JA>t$U4=a?D*ig&LZy^I} z&bu1;N=nG%Fd&^@#yKP6-MNN70sTt|^7@2Q!2>GS_J~47`2h+mADRi62gVMp)Uucq zXp&b;e*08Ml{HeC6}1fSd`rp*U@JCGFPcIof;FTvsAx==9oXq*G-3rC2pcNw`&lV8{P^N0HDgHLt8WpkA9Dpufm*^@(5AOIj0*{2n?tr1KCctlX=$!W6_Zd)| zdstD|;s4C?^!GRbY3fs0MlDAQx>$Xsvbz*3M&rd6FbELc4N)Mz33f~BVR)H>G-~-* za4LkrMkEz7ux~I&4n_zlN@0L=o=1ovh!9&~>)P5}RyP1>Ucx{+j{>cs(#)TIkF`M% z0Yx4kz!`tp8H^7o&}DZY5U%w7=jdz~9f8iKap>*tK9xqvenl6sp5rvu+eqL-l0Ql# z8(HblNeVz7`y50Hq}VF_*)PwP;@rZdN_P%p|D_JaC&V*fh?%?r*sQ)LDAEB!qNq^0 zMOaHi45-CGiOxOXLQ(YEa-%frnI1DKM6n`E@8G+kh%qIl00JqpPgU7K&i-0@2afc> zfTB%GI|%13sSv}rA?Iy=3tXEjWdI8G_ef79Zr2qE9U4YJCLLDm0M>~V23EjZ-ukb4 zQ~{Rm>B*h;Hs?g?Ylsz6Zi5+sQf5N_{SQ!j{xfKQ4p0)TvtB!3{M++vs#4qAZ2g=G znY37-S+pUWg#h92j@5oo(xLM8m9h0u--T=O9j`)tSiRMH6=rlNco!LP0yxyglWx0RJX6WNDg%qSz*2b&W=aEig3i$$s|Zr%Si zEs^WNX6ykY8hV4Z9Np)B{Wp^wD0+Gzm>i`~Fdh+d=FsG&`$DiF#7SnrJII)l^{dxR zbHxltB1?f%hh<&&+QA2EvTLYh5NH|3AY-;|{f#{d(!57TkOHrI*b&S`zR|RPu67^+ zQiPiP?oo^@k2&?`-XiI~t9#$$u}aL1cZV|*VA7GP&NsndGNXv(YEl5KcQn8hO6nzt ze{T_oVR|bC@vo)>^&3C52Qjw(yy9VAeH)kvD|{WXE@;wNPkZF0{s0Gx|39$vIJ33b zpKL`R11pRMfffhr946Lwj5cX&!m4hz>GLng3*_jVJ4(cT+;4$G=0&~?mo&)1bkqph z*zP|z_aqwt-~u>#)8&PDQ{w&o?4D(Ep5{^UcKB`4I|#0{&^CBW5!h*D|MBwEwms|X zaqFC%KKICT*!3!yGH5}tJPLpi&DNC|G>DgckIe&h50}JWg3tV8PDHqMCfN{t*(a8j zmfRcSSN8Y?{9lF*|Bf_zQ#TAZm!A7-Nb#Piu)|j@YmK1H*NI0Y5mKwK(I|u?^S=wH z^&PK0pDjuAVCdxA&2Tyql2iG}k<(Cr^uKV~Im8cKD4_iU=RNyQW~D8*iqukf4eVsN zFbLniOR2N5^S{4Pkguc^hlBS@L(?VwUzHVSZGvD1F68>QFqZ!0Yv#~+B9;Us+a<*< zXUvS5P3Ycx$o;q9k;CFFVL_QX>Y`(OFeeWWt%e=XWFn?KC_zwKU0- zdgJ;q2Ed(hZp%U^-o3l>h$x_)@P+^tu^bo4bwy7O7)VUo>;T`9#N+ep$%^Q*(f&;# z4ym@BL|p3Y7g@4y%}=CF8Bs1@)+9ep)KgSqJf+KSp=Lq_K;{RDQVpbZs);4a=P(4}t z@#FT{6Z8HL-SS}(=#;3uo#Px%f(D1Qkh#a1MtKyFb|HlUnK6x6KzoUa65Xnt+C*b% zV#C@C0d3zj1In;UW}3r)-64As6gZyX_J={zf7C=gYyVu8X+54f{T%2Uf@3fdRoc$i zWf1pkZ%XYT69OO4gSxqR%g-!s(s*0H@QaW>=%NdtGTzhtJC?mN@jf_s_K{R%CVX>d zXqnq1AhXA9_UPn-FpP~+Fb&d7G?)g^7t%s)Pp2eCJ!u>AmvWIt7Wo+TomKtSB-H(I zGGZ*_NjebQ4jEt(s%d9*n=6#C0nTL+oXiaB0WXcfCBqE2Upi#2FK>MPZY?RPp8T^2 zSG}h9Z<-8Fv0ND%Z++;HgzavFa|4Fq8covDh!+9pA?h*)qCl|;xmx86k_}&9*K%&Z z5DElH1%g&q)VZgLr$;$X9}&{1XrPC6|0Hs}eqVyG6dC-w?kRF^Yaib-mpc@=_k|4x z3hOQ8S>G6N=TwiTN4(va)0;~nn~DgN_Lh^!H!|n)qlmn*HO3bkMuVbO3Ipn5>xWZZ6>P^i)>{ zJvtZ^V|d!jr0K6U{8fZUlM$tuy-Sub`4#AJS!`xsJJbf=Oqa%AX1Cz&89J_;pOPI* z#PCzbwGF&a69 zTk&K@akDd&e2n{BX8-TK>$pKy(@%xU=0H=o4-TCv0$N*N^ZsG!;#q#XefLx# z5(C@yq$01?DejI=7)7jCOJJvhJGhRl$bbrsqneo@M&6Z~3Q5Eb%#4Ar7XjygQs9Yo z9~8ecs5&Yl^+bF9&kWO6Fqz<_+#E0MF4zm1Wc7U$OfEV(3?J;JMdC_+HslYfpjmxJ z4V-15z<%!)A_QiZyqiSpX~}D<6iz!f_=KfwonQ+0kQJ=2t{ERQ_52Sim1Elp_CyjO z?xQ;Unw{&g8r}_mjbZdhh;&xrgbDVVNl`Q`9x#xw)A>$XH9Z zmwRw6=|KLUt6l&N>Z4WM2VAS#_S;%*-a^AtHTA4CqjKKs&z!G6Rb|qRdb_b_+9ftH zeil8gvcwzqV=TTt`S$sjK0&MTATQEr)1Pcyt?MB{?m|hLe+%P|`85R)d?f!6k8Q(= z@@5eX*#ZZ^%8H2Hy-l81>z^1#6L|NweQt1XZ}y0o_av64XgBl6;O(i>&to*53ohXn z6vy8*JfPd*?eVg$@%Gs@dC+hhAS5uU|LO!I7x|21k;aN?aUm9&K1G2ewy2!WMczIU z)oi)Nj2k|cH7&R{W+>t6ds^1C`ZMDnRR)kD8r?2+0|!(D0XwjiYAk;q6Jzhcou4x^ z?eF+Cx9#zGn-gDn(K=;x%Gnc;P{0g(aYiyW#&X^U??XemVCg-z-3@{AukE2WMfMZG zUff^F;oR3OJ6a3Je%U@+(4*vM?}S;4!IkHWi4b549hd>HJ*h5B9i_p+>3L?eY|k*GHmUqhN5|iKx5x?h#h;tci*8q14kn$xCB*-L`5@lgUrnRBq4_GJ`G_?U zcXK@_Z5l`|up|xr6wjd)_hKowj~QZ(zWw6iQ!@n#1U zWjZk5;6l6@6-Q0vO(6EkQVV3`x2_jRMO`Oj;ZUWU_^i{kySAEf%sZl5LYi2#ul9(F z`X$#_9sx|=FnlwD7F&gK^xhSV>iAMYl_IEy-$kOXF+#=Rs}DHe&Yubx7czbxy&Gux zlwe}mCs0{WU1yLsrY9(8U1fdzmsd)J*Udl4ug{>!BVk=$PrH|S3uT?0QkA75d>cOF zosFh!XgC5hapOgiXCMv1Kgn1I?ex^vG=fjXo_C*{8=ILG!LW6E&AS;Ca0PigiMIXg zLSN|NeeU(wC(59u=~a?3d}}lvox#v#O60sjH8x5ywrh-1bawOUzD_ckwUJAg8VYal zs(!|H0eU@Pz6f59FZH3F(+#&5Tu*Plr%RbQEaj``VdQ$FV`^dYG~;sgcLDcG|M&II zR%2#gXoC}-jM&(*S+N!e?T0C@tptQ-TXD#&^i|z~G}csA(TcM@yS$NtY+~JcqwJc-SdF%HgPTcV>B9i~#;=r5 z#zXy;wNY?|gZgxI({P^Em9e0|LoVK|(84YL1?I9UK{7JFlp9K9I>=17ILdD{@a{2c z6Ypxr{eI%FW^AD6i2fnrs8Lo$X~ZAb&b9nuT(A*e zF4L8A$P~Us3+-gkSO(jIUP~x$V7AdZV(fqy(jS;9)OccRTyzQY;ZOGCh0;Ws##8tc zV;l<`G)$b0BF1j3%;Xly4;=^1Y00exep-LcL2&#UHBU`K$jQ;y8h^O{W_7g`f`{iD?t{i#}>?$w_a@w2C45JpP1h?5nS)qjny(`YDsUvHD;O9%{S^sF0H(0 zaID%^sSDNQQO4)%4PVR~sNhx5aw8%tN|qrV<5iF_9%^Xc24@k2`punbsO^jB=Qm%Z z)lHne9Zj(mYB#C&YLRP()Du#D#gcp}*K0g#XAOTEQl$y~D}4=W>1|ON8Y$;+3iP0e z80bll8@N^>P$Es6u2w-;raV=?36(H}0Op>^A;yXMy%ifOs|`KDy4z|TqEGK|TMC1P zy$u#4=WKSW`C1Z2t4UV!+{di+VvOu$9k1#`Uu=l=7o5_)j>0YEYR4(SVJO1cIil5# zZRYI}rM7;GL0-hDF&O?!Ad>%8l8K>;i~;w2!`jH5;@xAhre{sPbnc}p+W@(}+% zt59M=|G_l!Nm6HgO1p zUhwC(=A<4rFD}V?lN!{75GXBd%Ji4ZK#>wbd%r$DwB8#ge>h-2_NlMZOrVOPb=KzC z+N|@1D^Ui8n`@18MM9_Pv*o)O^-LR`&c*rfYD|dbGD4eoXOLIP6o;{(xM6pp+H!QO ztTmV|E6CR0uZF~3#f!&HyX^(Hn6e$>%;So4q2eQ|DlAJMVMxDoCRIr#UJ!b=6ki>l zQ2o>}LkiC_f^l?^E9lOmolW57aIS!+?u^US2}=_zg9*WCjYP+r#U$cHe-!^zN;cI+ z>glnLwwt-+etcQ0jE^({j-5QvO-oY_!Aq=^tc6jEO{=vUGW%GN3fri!A3-cm++e}F zB-eTALl+0Ap0PufX?|k^qcF$3;r5s~ONEV8h#m;42aEHb|00+vr$XU)gTs`dl;PDa zxuP)9fb@AjDmNfdmEfMOT3Ix9AmE((?;BQj2inZ$aq=?uryx2RP`=M4y1ucYwduoeU216 z3H-yFr@gL8dd!ljUJr18>U&gqDG*`dP{-mH<*pUFhY*O6Zj*F>wY%tRVo=O+`(;T~ zFyO`dtie8|%!g0p%EBGkD3|@Pp%#6e(0}@(1kN^?`J|FF(+BR4Ego*NsFvir!JlPx z4I14s;_bJvLk<|5CYyg}(iN>2$$F3tsb|e>l%}d3kBv1Js!<0=c{AaR@(y7^2S6`T zMch>pDxpWOjI-y4YRBRF?e<;jE$P$n#kUm?ypNqw?U@2llRrJ?KTWP3v_ez)CW6?W zAbJw>1p9k_z8ZG|ysNPzmj@0t>m+h@xrF)dSSO-T`oW{d8&3BftTF6<|uf#$fR0BnI_;?nLJ*q*gTV||; zn%9QQ{1SjHPW7` z#`uH(U*Ubx*@N^}QA~Ek`wN~GfQD-QOoq6m5o;%HPc1>pH3s~;9BnVwmS~qTDXnwT zaR!b?2V)#;tY{yab7cC+`C*F}UBXryQjyJ|n`_Xf-aU==CuvV#w~dPJ0rgX|bL^UH zg}i{gJ!A>~sc+e&B|F!2W<<69E|}F%=9^XLD1gwG9q$cH1tX1S8;LPa0T2JPqSPDUm{)*7{ zxtL?0t}#Y{mwUDdA_)a()!x%oakffOHz&`&Fhipgl0RB%+s0KaMMmPNF`+ zL~yLj5K80P?#yj=r-2$hE{<%*j+)805J? z-fr1$&}wrmtZ7!wttB~zZJuyR4yyrLM;1)=L=AQTo_CLvK=$ zeW>D;t5H+{$L*mh7rMre9g}mN8~>oP*f0?vpsr&RP$h6pbcf;WIyelNSGkdIS#^$A zAN8rx_%^j}44<8(6(~bv8c7YRf;Kd)A>4;+Az=os#6(G5UXnMEDW3S-hrW-@nw-{~ zoYZSlfFXcExf`FxbT1|egJ`{V{pop zr3PY+5~T(~r93yvc~$|O=Xs-#z3U!pjIE8D^qOyl+HQ!MQV)%Ei)sWjKWMSIr!X>T zUq=BetBTzO$6K!k$o8g>LUJ;+M&H<}OxJ=*qJT4^=Wd*O*E4{&_*b$wm2Mz`ZJN=R zuuRAmmb@LWCg+&BLw!KY-C4(I4spAvb#z8*iSDGN-u%Yvbj`HS%Yr7<^tic5d+?>D zmI?U~JX7G~+z-Q|$yJ`!+$z!CjPF1zK39_F9m9zwxRn5H1hEaE1rARvr6802CxU&k z4NT2_V7_hdDTFI!fHsM^LjJOWu>1rqCyS8vGr8SiHq^R_(~@ZuN-KE6mo>CwfpC;NYt; zTLl)r#*z#CDCm@aC+GcqdW|64ZbpDIJ|vsGMpHxVJ{NmlcK{OiKqq}ViGBlyKWY?x z3MwQ=N0P~e5kT-dV!@Z2I#*O)y=~{pxr;bR1^AzZ`#OAtW7q!r;=uEWD7Mb3>->L@ zV~rYJI$z_>-ar7pXDuf@U|}o_>>Bu(^I$MFf^Ou73m~oZQuW_j=eU|dJk6UfyX`E3 zIX0Fr34BW_7{vlizRmKVe6ecRXgBDs?uN%4j7p=5>cAH-r@~8&)!(;1#DW9N0?>Im zbLfLZ-0Bj_c}Ax9{+I9!S2_cc-ju^EpZy;HgE3a552dLETqJU<%T9N!qv|vcQy?S8 zgHMr9;G<}gbWOjF3$BSx2IB^rc#eC%q4~^z{E7VJi^YGd2YB$l=lwmNgWHFwT3C?* zc*#_NrAByn$tthdEr02QLVCkhPTUHf-%@s{4sn zN+~Bm8sKG{rN96Ycu%AflFq07BQkIZ9;#pU3)An3*w+&}|n# zBX!7mbQZPRKLzl9LF=V6>?(jlWbzUnq%1tG8NfV8H~gSb`4n~?`4S-Si6|CD0DgbI z?08LrjpJt*=Lu>--IUQX+cdb+seu}Wm1hb>R)rC}-912JSLnEZgEvyc1x$AcLbESG zFWqw35KoIC&7@rCjOVOeH=>Oh-5mnunL8QO7l%v60ninyM~=d zLd5tDk}syS-QU)Y2^PiXaX)C2@L$?L7u7Ch>kIm-+EUTR`|{*O!SpM`zDS$-QfASJxfTr~$qn+m!<6Rm@frz!y%?P2`cqFl&(u}RRj z)*_9x#1%4oRicNE`YQjkgLOmKJ9ke&_pSrp+q2M0DWLr`i-(ZzNv5!XVEkLO(<%#< zgB~%3xz6BxLIwZ*y|@BYqn*zp92@hxC%5aINA>qVLchxuJ zzzz@yyf+XDD2*CY!ce2pKsrzP;=eB7`EU7Adw4Wy&gHH^A zA&AFqPbfTuSOM6)7EM#LLvx#l+aFLwft2g()q7Z5Z)D@)9@24-bc`Lx^!^BoD3402IYL7updJK%o{g03X<$07PP|tj*hfwm3S{4Hkm%?*oR+`r3UcBVy>&xPp_?ykp1>^@*bb^NT zV&c!DdiBY)=b5raBXC<=fH%ti_qd;j5HR{tgfQss?}npCRWzP7?slW)`qp9^Wcx)T z88w=gG`TCHxq2}yT6D*luKau4*7oBa90|-I=KRLY=sW^a*Cv{5W~lx4)8XA&j21Y= zI>HWbOXC@h0Hz26vZF&4nE92)!K~ER3=q-v!zU*8!27+MaCLEpMpth@1(_nR@vl24 zRF91aM8xBQ%O=<5M_0|G8{Xs!3;Yp|G=W+>ZUWqI5EduOrR!o1AX@>WBqlkr%C(8q z=D22@$_!qkMQ>&-my$x|kRl+w=|T*0nrEzhK5?>3xhq#zF->)Qy%66BAx43?HqI@Kkh95gEb$BJio`BV*XVZf9bjSEZfSV&!4v*@|D`*dJ~gq`bI`00c~*kJ_LOnA8DJ-k=fLels4)v%<- ziB{UYLjH`{39X7yO4esjyYZtoNmT*OA`M>UGXFhmcd|A0UybJTzFCUGIG-e%oId;6 z!ySzn>kG*OmLNgEKUY$F5D_9DFy@Fr6t3US?Ho$YZ9iZ<6UuF2?tZT$N+`c6I%$JAr@(DdPd+{O3ZE*U@F^cJtlo2aNhx`n}qO!A!*`j`unO zOn@#er;`YW;K+AS5Yn{)mYS_9VJn{Q-oH=g3J#PGP3;GFKF7N6ohqc6NG@W zau@6AYQMcEBCFFfNwh-C*rD}H&19s9V=r8(6>rj1HE{CUI>SgKGyTVwZc+S{F{s?U zr@=m*m8r6$Sd$dNlefpOU1r>#7=wQM@pUlkn}+&sv;p4X0tP@zC>_|4Ak*rK(kOF( zlsL}geR*Dvbbto<;@7fP80l}DQ&Y~wn% z-~3t!bX-8ivVP|-e8$MceFj@SjK|eZhV_O#0FW}uhIsaqDs0BUG1@`A#cI8pTmH@6 zkFg~iGyFgw{{vQv3rwD$Te|G&w(*oIVN_cu2?6KdB2GRtTPs|HO2t={l9>Zu1(`&z z5hEpoQdfL@LxEuvK<~|Q3l>J(=f&RqC~s$ObEi13XJ2?Mqqeh(&F`|Df&y^_(X~H5 z$roT$q%=R9=%`@2N@l#_dA%s_`?;!XnDi@EDe-b~qD`=6_4Z-9PI5lWIN16F4ukjo zf0G9{eEnaUwf&YkA#-SOlrKh1`uE1ZC!hb13xW zj=--^KS6N4s8+vLDP6f}Kbw^1&4_9@B{F481rgSK_yROz3bKZNgMz7nffMi#LaKml zsSs$1xoKGE5ugDmnI67!0t6_U$>ZU#S*L$sgB4i?S8~VApjW&S3pAC(`gx*I>-qdA>+5zI;s2~V(SsNn>6z^ zYXUur3hMd&#>X{%7&uT?!vw zr9harNYSP0YwENcfj?ljQyb8Q2a4Gt+PTxUdjz2^Azn{n)7?ba!0oVZbV5C!VpomZ zasvoF(pjVZwv2@=+FNeSsDpI#fe?+hW{qv|Ar-1peB_`}*R=ikPBTVrEQ0czs>Gr3 zIQ%Eww71TWDz_d`c)(3>wjKT-ZD!X;%K_`wN@qPmdJa?J^m7$Pg7~{G9bwYQD6llD zVV3_B4eNGPv{{nTyNK*)pgfO~0Yh)D~n|#75X+PBHe#yNHjb%~Q zoKfNzDTHA1sAaCptE`%Hou5290vmq@#E+H+P}TQlRVw+LlRL+E`NvL==e_G-Wo|dH znp_`_6r!P_%qIxM0Uw!(L{=3l#H~#Ha1#tvSuak@82-p*ArmL;!Ker`Q8BCf)va}p zE5hl*N-f_IoP&e6v3db!D?f{BlzV%sCrWXOe@@d@&X_L zr)EdmThs@%mgAP6)v{K6{o0C7ft{oPZ(j1up%O1dBB;9>IDvXS0(5;& zLnfO*weH9pNarp%@PIf#iZ|fm8hk(Ri{a%4*zp8)y|H%U;${SCZEX8J{=CEJ?yY3? z3%YdiK!w57_%XZzV-mBDSN+qgCMGCit85t#(ZFEO{;Eb3dARiuNBr2mAtO@D7k?Li z4@rWh4?B5iD^Vz{H?$g&y>Iip@ZC4eWsrc_nF86c8{_VPd?Lg`jJ@IT!X1IHJw65W zd+Q}&P-y-Mqn`mMq~}bu+JY9(;6X+rw%puT&d;vB>MwKo_nlB-7P!xMz@fM(Xlq08 z8{MyiS{9_9@&;3x5O==^5EK7t_+tt9zEVeb4Dzwhfs@wG$GH&#A8M`GQK)p8?bF~L zrQ91Gp{37-u$CX)e;!lq;I=Q(xh@F4GkxSUzxf%ocN1mdD*#=^2=(!#F^oqwq@We zc8L2KW3^Nk+c!sC+zW5hR^bR}ZX^Zw1Ck+0TuY8?;X=q+r9E&sCfEfaH+g)EeWeh_ zu$e*SBQHj{pMCWM8Ttt4Y z+R6u3lh64(cqAp|J+YsTtlKHJ)nHDlpih4Ny>p9+$}*R^w-}h=50X`UC)r_8#W_$Z zm#2rNtNMQNs7-0EZJpQ?`P*V75}?uP<{Hbps}qF!!VOR#2q--6@4z@^dm~3Z8XDxP zwXg5>QCr5n=wa+BG~`>K7j5%zvSUVJ`G=n#*rOW~W(ve>hws-jH1eBi4*2ZUd-ov=8JC4E9fiMRD75w{>)2Xer!v6;59#0*qm2Cv1x4w0^fBdWaMXzLo)TS26oC)lC0%?v&;7QpK+mz6KO43%8q6}gze66wEV$xUq z^P8lQ4=%3qh&Olh_ZyWQaVCNUWNFUMLeo0*948qw7%mwlV<<4e`c=TdT8C2e9q1v$ z*jRUi1eWo*_EEC$&1T3Q?Avn5;>5E z#LZ*<5ObHhKJPsYSE{3>K(I;sLhTNtNab%gH`5=&f(IG2pOO`P`H;`_psk086tfz} z`|*jC?{Zq49<*e=8Dam-anDArb*rD8x24QmXX#I(eIg(99n8b+%QH)&`*x}Jn$%zL zgCPo|uJuOPsiX;y7C-h#9J09unPgfZ^zqOwP96jf&)Hax<@wvWc%FdMJxH#Oj0)Kq zrRGEt=1q_D{Tpfg1}_KdGDx*vn&ROT+xb@Sl;cmz75c?1vw>({<{Lq4hEn^G;C_X& zGZDLY66AHjZ7&atFuI|%*(do44oC#@9uSO;O4t#7$VlJJxkuB!`W;qE zFh2?VT*(qa&5s}I_I@so_L#!U{AYV8SH9#sJ3CiuS$yV~_SE>1BDJN#Y@z?S3Bk4B zEAvW?=xuYhd6Xi+umbbdei|1$hOVIkkcSq&L|45-(+!qO;a`B+(LiaWiC}D(m;XVh zSp1OA!w>R>UQ1Qdk|$1`2|VK5D|+hr{J55KucHW1Xo^Ud^d_^fW+xefH|fXtE@?FD z2QvC6c{?6S{su7*z2lP~oPoz(>)95LF=b4z&IX0_lUjB=CY)Uz?rG(w3iHEUtX+N! z#OQ42q0(eiTRpTtP)YJ}o;lNIl3Pev-)(f?d|^I(w3OHA* z^oh?jGv)&qj0stJA&Bg~kx_9Q;9YZ9!t~OZ?1|jMYgl;<#nKG_`XBGds>*+51Oo|6 z?&D{qR$k+3r>E9nKpb%P!yx(r4NU2m&IT~@US@|2*snKV2&MzuK8tt=#UNZ&W(o&+ znBN6?Y&Udgubkg7?ilir%w3h2p6skoB%l1@|CSIR^J1aeoLM?#x_4Hu{w}(@h9Trf zKdh0drg_d@ouHob8 z#Wk63@t()o+b!_-!XfGg$kLi+K&FuCCO8*4Cs3NL6_rJkhuaurR+RvBwDkrVVhJ41 zmQT_@UmUZCUv~S98dj!RaP>7mbsEY;9)A^%%)GnU0%AoefG$u5TCQa#cAZ#KKzA6S z)FKo+ywr5{RJ(^9RoA+!Yn2gY`r==wKkwD-$Cw9vS_7i!HD-Zks$TFxF545IR_L_D0}a_T+EmaVT(Y?3`d@bP*+?zPP4)E^N>d93BpGfK<&PFZ+CS8RLf5JOZ!-ue@z%cJ!kIZg_=I!3ALYlx6NYa`>RRZ@Fu{uFDXH5!-kD0<1>|s zxb04uW97NN;@+G1kvXc zWV8E8UUrYqw*;in+UQ!4leeQ|--ulzE?jIcD(X2wFh|+x)Q^KgnHcJi$IODh+qx4u zMq?4!<;w0*Og(RxHG!IPgwzCeW3_$<#`GL=P7pm2+i$EPwrMVtolUnOTht0c+&!CF z8Inw>iVv(8mnF4L{e3Wz$F1|2R5i1lBg;#l92mvl2lp3vkZ$b!Noa3&d5Hqye;W@6 zUswI@j$ZkQ@||FG)M+(Lqv;1(NpqZjz;*t@0n?H_HJqq#+U1y|+dteJC(LQS+*u4! zGG6Fv`>aK8k@^gLmxFYVi`#B*fKfw|4hNVg4C>E!`=R+w+%SK@Qc zoAdH~tFGXaU`;CyC$;Aj*=<1!ZJ&hRDVP3{VMkM-FB11o(~R#F4|0L;Ldc@oqCb;E z2-%?PO*1aMc=-+&xI&BSck1b=pdAhosXA8WmB0o%kehSmgQ<1Wn5`$8KC-soUgu+ud+nZ zp!uEc4%hI@PyS9uk>#7+@Ly6CCdq)X28hi*z3UkH8*YF-9H?z?M36BdC{gNlU931e*KClN?eg80CQGbkwJM9U)#AR_b zXV2i~omN!{)KSUQXyvwL#(wYkkpzC?(-o-Z`KBF5nHIy7S393*oj;v~&ZXDJsA_!_ z_p&sM6Ze)XcRq?5FGY=iyAAMND&U$^ihnow@t}Gu=Sp0+x}(bM zPRJ@hptTvntYMd`_TwO0p!@X#@$*5EI@Qglh3}`I2z0t{y5S^bmA%}2C<^ZRCzlHczh6_AMw2O5x%hu=Ad#blGY zE-{FV(`ek*I)cnxJbnLcxm9jwjfPFT&P4!Cwh&TI80K@T<-*P%_Iia&4bNp}Y6O8R8w}ro=vm)?DAvD!5nr&=;D3j;&?x zIP^5V+jl`FuoTZ4;)rLzX>1pcdSKGDj45CC z-g^=-JU#`n55UWy@**4e%C11Z!vxbJ0+kC^ES|>_^{qZM@u5j~*s>_nwjWQs(=it~ z|J>fX)+P#Q8G6Kq{M4y~wiHv@cvwwdQ}L0%Kl~QU&q!||!`ii37}@ZC>|AxI8p`AU z8~)zej=Jm#(|Zmr7fcG*kGwJ+m*MtF_7YBY6@@{LySoGLH`r`Yzx|McB-y>b6_jLAZ}4&q9I z(AA-auwm+dCT?KuEvGNz5H){s;00G|OpJ6?BCmRGGmGCczpY`;GL#W*4p$jy~n-~MQRQ^b!;qt(99j*iP*TMirJ`HIfrwtl_ zE4_HL-J$wQS()gw_d*UcN>rZS^VsL_>%WcI^0$jQ4pfw>$2>hJKPM&mJ_Jmyu78?} z*DQtBk4QXZa+~mYVuc5>lJ+64Z|+DBoP2nxUnva*os`19lX z=F8Fv^{gaenS7CiO=o&-Wz=XTvAjFjpJkp^v^uGuJd`=-oZ)(vh}KZHFb#oCS#im6i<*R z@9gpGMez;syDH{1Kk4mDI=Hj0?!#Pl4yVCwzD5W8^MlGk41$`hE%EE>kTJtYZuW@PTdT-Rk=u#ysmv#6JpIKFn6OEc=O zmJ&VdYFgbKXaVH=on_8nWWWo_X!gP2#c#T!KC3+*2??SJKJE7Ve0Me;o4x42pTZa* z&1B@+D-cqgyUe>g zC8tnT=Yb6E3*V-*?%QU8jkT{k92;xReznG}ZU@p{+v63*2iGC7TNa3F9a`=c2{vrw zi$8sqb9IhiY8oGHq(4?z^O_V!tQ@M8*=IPIQeO{XMUM8q5b&13b?AIw0f_hu+#4}j z*MC4(9~gV@ZmVi7Z?-4&kqytPRwb%bTSZyq1CBMH&|Qo=;lK+Eb7_Q@UvEbKi~uLM zyq+5`a3;@vk+3H9a;xV|i|1Sye}?guyR_j8vlk{UwKfJnr(Rx5KS`64G%T&r{3!2d zJ6u%nwet>C!JIQg3u-OfT@UL#t0%{QPxJE8J=88^HUv?eQpJIBUt~p?)0Dk*VK2%Q~k#6M@2?Pl1;L* z_fE2sT_FyRnZ4(+6*3FSCPK*G8OP3^+56a=bL`Fe-M&4~^ZNaL&iS0rz25hGT<`13 zVb>i`5gm5f*EYFE?f{>xxqL1H5nA{&@$rtS7JbI7RuY|%I5`4Zr&U|yHGdj+VD2N? zFDr46w zZdUg-RJaIGX4EMqjKQ@XhTtX!bk4IT!guxD+Ta6M9lyv7KDqo^{b_JMeQ`Yxy_5Nd z_&|ECk<@_C7}Cce*T?(xnOE)Ivd@q@!=b}*6E>_??NpjOaVWoxB3JpXy|DeV?e)$x zeoU5^c0SL4Tg|Tq?G@%I#`JZ+7!v0f9w4}n|0RYtpmDK@zb_}OT8yAc_|_MiL2%`8 zn2R{uh&@}YloBa}@ORk8R&GvHB+WyS8~38P;DvZcii8YhGl!;>adn_svAdPEk7zA$ zgr0ICnduUr-;2y4tg@>mrgO{g%BTslhD2rbf5HaG2CZb@9|$WiV;l4bxEA%dF%o`= zf|B(r6TH-js$SB&1C>>@{v765sy-~c6lQuaZH|82cQt_t^-e;FsgkKhY{#e^#SJ2I z$t!A)S4eUSCDJCS9Z7qAipuZy$P}@<^!KL;&Cu-->VW&)DWXBz zmm_=GBpp;@s??&61=reMN1^I&=3U3J1`w?h>hdXk?Yo|AU&~}h7onz4NL}zY_>QF8 z3tq=@@tnMV0!iCD`}V$C`b;aC$-6u-%}5$}*0(gzM`=k}*z8Z6CH1}?`C-tBd>!!K z`)G}eM4nvH)n6mt-hq?NNk%?ezDi1HsVk^)HtSD1vC~LB6giJxWm+4cl^Ap*M|>yc zGcoS$-2EO0$$yb0up&peBJ&98Es(99InwPn?PJihjj zR(S$KOIPoG-VFC6{mMBz!zo7TRhyYAj>W{o<>FPaVkooIFjPh(dhy_Qy!_9Y`uc?? zU5ZMnX{+1L1hT8E9NY@i(Gs@#!dJE1=*3cQNDz!1tehtAwTEZl}KSw~4?%8Io zmoN2h6*gwS$RU^iY!9Kn@UFr2<*9|}#NBRaax_Stt#~=D4cz~Ji8wvY$T1qT4bE|M zqYXM^>&A_KV4TIc4DKe_b9lvN*J(5{p1Qtn$>veW=bTCE9=>}q!lRAl;%JI+7#cMZ zBxo%p%VPWecZJny*?tb0S;RW-J;U##UP&a>z4f1$L=jW3t68o4GE8~Hb6yrvQY7-@ z>&l_F-uSw7HMLnr%JzEGU!I^G(K)q5N8duSU~P8fHD+6<6?JXm-D9h?d5DgnV<-8o zXP6%G@UN3s5A_vF<9M{3c2_j&rar?yLhRpzbbxwk(`C0}g25j9Bl4l*doi4X6i(KG ze$snIvcuRaXt#q#eetU`3_6KUsJ@rSNhZd4f6Y;cWP``$=UAtbi{>`|klG|dl)crj z=iVi_hUry*o9gwa+T|8K)qg-HYI{EY)iM)gqzlA&_GRUdKJj<# zBGQ)+RdT6>i#vM_8sJaTz2_qQFL#oM$6gUWOW<>C`5bRn>^CAt81(6=8I9TKHtRe- zJ9%ppl+Y1!UC#WARCJR1av+`_tcZ?Og#}#0iKtWc# z=^h_T7m ztx!ef2zx8Pr$^}kX8vdyc}wn0Tq)d{ts8ICs{65t#YVtEkQVo47>Xp9Rbe4svk&FOB$e|!RfvS-<3OedG(3K1 z$#~-pNe2)8p}X7{{9fCgFFdMZ{Xz{gVFbDY$k-b6BMvmImmooc({Kv3`bg{r$amD6 zezD7RBOpjVK7==Vo3`}Xf39~tbe{7v({3t}xASo5#Ul)4lpxofDny`#8MdcV(GY@F ztz*L!kdZg94cYm!ILc@AQv@MrIKK48eS9bjKf#lDqotZCk`elNe7hYOUWs$S5F))I z%g)WO9qJ^betd_h-$Vz68DEDdM2m3qX%d`SnP8i3lyK-P5-)CCo!X`8$ySAm8%Z0# zF*1_!b<;6Pd_Fu9=M(CFZ###-^_b}WM{byV&=SbYs8!G)>aC||MEP@qKZkd^ zGlOKlbf1Z)?H0I1TQ*-b{pGhRGj)fJM{p9qNpI%mei=^~QSAA&a`F4j_UDSDVbxbd zDY-Ndhn1)fXT317sLJwKKa@DeZnu7OHF@QZkrfh&B{Egzn+?*3#whv@_LMr z(9ml4&@#~~|5qah3?=e~arH^gXU5o6{p|6b?WU)pFvstuc@@)@-C|FTdb*RgwQ8hV z2m$8f$@?wuESHarv;2NIBCcpx$wniM5d$(#JxMd=ZU3|U-?q~gmL{7?F|l3j@x|Ju z9AaWl3VPhYURBx8HjP;OBh2(dsH{%17+HD~j`b~i^WVq~nQW?W8RS|(oomZkFmMra zDzC`Gpk+4KGp$-roPyil-JfxBxNKg6gnS;qOHdhdELnv^5Lgds2u9gBP$NT)FSI~SMGELtaB|Tb-+av3a z663L+N!Wjh$*%-4`d1R347+bBO=Uvxq&Mqso$Rj_%ZK1ie6B&yEQ1)MlN9cGK<3#= z&--3KQBA8JDbakoVG$oUd4xS=`jsmH0;!>2r~<~lsf)gjPfPOpMT0j#Bg*%5zEa)q z8tr>kUa2e8a5$6^Z=gd&TIoL6;!$pP7aLo}yzT@6S7$jP5-@Rc*Y50Yb(gJIxj#Cy zKtX)(Xk?Gs`-}GP_l~c3TWb`!JCIZyeM5EVvzFEB%pE2gmZXR(8VgY!bzSHq5@F$| z#)r$MGA+(@Aw}*E$H$G&&d%u?POhwPV`2uu#7QNE4;y{|uIn1gT7S;}DUPV*F_dci z6IrD1Gv3-VCt15$B#!W*cTqM(Iv*&}sd+QFtOWGfs1A)dF24F#r2;k~h4kp9a&yQ; zp43J#^Ogu1c7xHxwiTA$+zM${8ijmIU*CI$9OEU}N;14)dNOIPptcPU6?Wj}BC`NB zdlyt2$o{?u|KHhDMPZ)Q;klzyFO*&k`;5;yTveNXV^+~QU1yNWlvn%a%KpcLtQR*C z1NCSH^=!;3N?a(QrR>+P3g+hhls$x(b1Fd(dEG>`G_@w5``ebQ;vfY7a;(8KvdbRf zrE6G!zgME5xy||2_W--gYr>)c3%`*@zg9o(3eRy9?naUQSy)Gd#Kxx$JpF{k-I1BY z1(3TiB%K@3+h6H+6jcTm9|J zp~+#+?>Wihoa)94;VmE~xQ(Isk$>*X%)YU5+YiCYOoFt|cMYsx9#>S7?bGJ5FR_W= zMtpi)B(2=;LFQQKZB9lICykK7IUU`EqRAES#9+A+0=;m(Cak)Z{J~%WUFDb%sa%vtLU~(~DZ7M`xT3+cBHP5N)d!g2UO$cWz@} zu0;Bs&Jv>c=;#N1(GIgaC)YiA=~clim!YE3#E@gMjmqVZAuUqQ!jf@OV*DWQ3RQ^= zG?cwpcD8$+=OYIy9X)X`Ra385EA9@+Kg17mWN?!p{&uk)?GxF)L(@=uSQt}T+ME^QHL87lGZ+fUd)v}%J zQ+rTe%<>)TGyk8ZyrzV0nuG=7slE#-cE$k=G=X(?qE@Gz+U7I$`V>9$EQ$H1VX9Oc|%A@cb;>BtXYXm(-8~UxxU;yMmJo=qa_S?B^dN;(Z$U& zGSPJ5GiUCX2>G~}XZ3cd*52Djf?p_dRE70Kte3icUZX&sVOz`7t>s)(J*SSJe_wNg z5&?xfAFuXiiQ|5=+H~5a#LZ*J3*U#?^-Mgh=R5n3qn=8$H^PrMM;ZP7G`ZlC&R#Un zWmk=l%AgNQq{Vt)Tj$*YNXUou^9N7s67FqxOJQVZr8tz@V$z(Ti&m{=ssCqMIlmSD~+ZjmTe&la(5GBvE69J^qlrjjS@(G zHEC~Q-}&QI=`X_)Sm=rI_VQHny0n(Q{OA?5Bb32hTxSpypb*?DeC-wVy=_`SU?0TT zCb;Q<(zkFeH6p+jwM4f+s(`F_yzT8J& z`_=A@@KSi1?%RXE{q3)jJQYiimt7gu6k|r%Kqls=^&n?p7bL(j4N&vxyg5Glb{e1fLKiK(1U95!d$uG`c zGZ0{9dpmEFYahU1bC#9AzNaPI)e?^qts0XwEl;iKeo&|H=g*1ASlt`L`bEs#Ud+Q( z(5v|yCmG4c<@u(wZV!(?HISR1Dj*`Q=&uttHIB?eLiv>%3-BewP#C z-1tRius!1*&P+t6dr=HJ6GpNW9N~Iz?Gk!7B z>KE2`Ceb~Oi#~+3RYwxA`20;bZ=kx&qwT>uLuKM{u}!fs7)CkFD+-2vR==VTbfmZs*>CysG)+!4xc&h-pYjZZj^3`e-qC!m4jxaEcKL7!B@ zl|8J_Qs4CC(az~eX6172bnjO?Go*2zuJj%FI@%siBqu~RB3z*3?YG*6#qF+)2l%zN z7`SQ1J;NR=Vb}MS6d%BB0ry8Z!<+j|Y`>LBE$eHhed5V*rAB%LW`I2uy)B*$ig1sQ zngEk0`LHKwQ<-g!l-%F94xfjbmcR|KXZn)Ig@x&2s{COq%3SgDPD!cMd*lU^=BmT! znLTR_FV{n*2}U+!TA_iy{&}58DWFh_O}GvHp2Fii20s{kB@6?unQiHTi~a|a${Zf? zXB_X(KkvPP476$x=xJVD4u13M|85!Jxpfk+RFzm|&&3*zEJzcnL|;N!?em@NjTXxi zq7sW`3*)30`f~lY&uw3f^J75MF`&8cF8CUhP-xTUziN5eP|G+wLpa8AcZROuy-!94 zEb@<<;r_qK?AA#qTnU*rNvCv1wzLqj4a3$afaPl6q<0${LgYtZM6j?@mz*{y;<&iE zmR6+*>raUq&5xeap{gnTV1g=3VHSCi{a#eXA!jth&DYRCBOtUCr=a(+SI}BS8z!Jn zFV~t|8cwDt46BmFU^NpAN?k9RX2K&C96>7Sm%41m;28C^%K}e5pCV92)pexaPt|k% z3Iv_UV=^=>5hdPSbwYv~IrfU*g}EK{yF1s1j6yHuV=9^T^H|}OWM^$59S!vx?M2g= zwL#b}D)-hEw^s~zN0DB7I}z=~Q+OT}C46j$qOqW1y|CojR%*>VEIyD-kdB4*O{L?a ztP~2Lpw31A+tBuEuc&#SJZwg`+&v UIk2yUM|W=Rf8CKsnp_-!`_vOwd!|9}SAe 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

f|>TP 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 N1vypOB56ba{|Ayx)9wHO literal 193312 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℘s+ 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

H~5)+pWF3 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

Ng+VN=|?Yjuc6Qr++=JFLCy2J3U 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

yQsw&Hy7PNuD`(c- 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 Xbl-o7byG)x3p||cPTStI#$W$GZjT2R diff --git a/docs/guide/taking_off.rst b/docs/guide/taking_off.rst index 9c5db2fe5..8763706b7 100644 --- a/docs/guide/taking_off.rst +++ b/docs/guide/taking_off.rst @@ -16,10 +16,16 @@ and then call :py:func:`Vehicle.simple_takeoff() `_ waypoint - in your mission (you can run a mission by switching to ``AUTO`` mode after you're in the air). + Copter is usually started in ``GUIDED`` mode. + * For Copter 3.2.1 and earlier you cannot take off in ``AUTO`` mode (if you need to run a mission you take off + in ``GUIDED`` mode and then switch to ``AUTO`` mode once you're in the air). + * Starting from Copter 3.3 you can takeoff in ``AUTO`` mode (provided the mission has a + `MAV_CMD_NAV_TAKEOFF `_ command) + but the mission will not start until you explicitly send the + `MAV_CMD_MISSION_START `_ + message. + By contrast, Plane apps take off using the ``MAV_CMD_NAV_TAKEOFF`` command in a mission. Plane should first arm and then change to ``AUTO`` mode to start the mission. @@ -56,7 +62,8 @@ The code below shows a function to arm a Copter, take off, and fly to a specifie # after Vehicle.simple_takeoff will execute immediately). while True: print " Altitude: ", vehicle.location.global_relative_frame.alt - if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. + #Break and return from function just below target altitude. + if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: print "Reached target altitude" break time.sleep(1) @@ -128,7 +135,8 @@ concerned about reaching a particular height, a simpler implementation might jus while True: print " Altitude: ", vehicle.location.global_relative_frame.alt - if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: #Just below target, in case of undershoot. + #Break and return from function just below target altitude. + if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: print "Reached target altitude" break time.sleep(1) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 65f879f4a..fbd6867db 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -2158,25 +2158,6 @@ class CommandSequence(object): cmds.add(cmd) cmds.upload() - .. py:function:: takeoff(altitude) - - .. note:: This function should only be used on Copter vehicles. - - Take off and fly the vehicle to the specified altitude (in metres) and then wait for another command. - - The vehicle must be in ``GUIDED`` mode and armed before this is called. - - There is no mechanism for notification when the correct altitude is reached, and if another command arrives - before that point (e.g. :py:func:`simple_goto`) it will be run instead. - - .. warning:: - - Apps should code to ensure that the vehicle will reach a safe altitude before other commands are executed. - A good example is provided in the guide topic :ref:`taking-off`. - - :param altitude: Target height, in metres. - - .. todo:: This is a hack. The actual function should be defined here. See https://github.com/dronekit/dronekit-python/issues/64 """ def __init__(self, vehicle): diff --git a/examples/simple_goto/simple_goto.py b/examples/simple_goto/simple_goto.py index 511d32800..4f67f5373 100644 --- a/examples/simple_goto/simple_goto.py +++ b/examples/simple_goto/simple_goto.py @@ -50,8 +50,9 @@ def arm_and_takeoff(aTargetAltitude): # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.simple_takeoff will execute immediately). while True: - print " Altitude: ", vehicle.location.global_relative_frame.alt - if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: #Trigger just below target alt. + print " Altitude: ", vehicle.location.global_relative_frame.alt + #Break and return from function just below target altitude. + if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: print "Reached target altitude" break time.sleep(1) @@ -61,14 +62,14 @@ def arm_and_takeoff(aTargetAltitude): print "Set default/target airspeed to 3" vehicle.airspeed=3 -print "Going to first point..." +print "Going towards first point for 30 seconds ..." point1 = LocationGlobalRelative(-35.361354, 149.165218, 20) vehicle.simple_goto(point1) # sleep so we can see the change in map time.sleep(30) -print "Going to second point (groundspeed set to 10 m/s) ..." +print "Going towards second point for 30 seconds (groundspeed set to 10 m/s) ..." point2 = LocationGlobalRelative(-35.363244, 149.168801, 20) vehicle.simple_goto(point2, groundspeed=10) From 373a08b200db9c7863b70300035424548ab5a785 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 23 Nov 2015 16:24:46 +1100 Subject: [PATCH 242/475] update guided mode instructions for setting speed in positional mode --- docs/examples/guided-set-speed-yaw-demo.rst | 1 - docs/guide/copter/guided_mode.rst | 70 +++++++++---------- .../guided_set_speed_yaw.py | 61 ++++++---------- 3 files changed, 54 insertions(+), 78 deletions(-) diff --git a/docs/examples/guided-set-speed-yaw-demo.rst b/docs/examples/guided-set-speed-yaw-demo.rst index 54a7bcb9e..fd6db8a31 100644 --- a/docs/examples/guided-set-speed-yaw-demo.rst +++ b/docs/examples/guided-set-speed-yaw-demo.rst @@ -200,7 +200,6 @@ The functions sending immediate commands are: * :ref:`condition_yaw() ` * :ref:`set_roi(location) ` -* :ref:`set_speed(speed) ` The example uses a number functions to convert global locations co-ordinates (decimal degrees) into local coordinates relative to the vehicle (in metres). These are :ref:`described in the guide `. diff --git a/docs/guide/copter/guided_mode.rst b/docs/guide/copter/guided_mode.rst index abab885f4..b96ba3171 100644 --- a/docs/guide/copter/guided_mode.rst +++ b/docs/guide/copter/guided_mode.rst @@ -58,7 +58,27 @@ to indicate when the vehicle has reached its destination. Developers can use eit :ref:`measure proximity to the target ` to give the vehicle an opportunity to reach its destination. The :ref:`example-guided-mode-setting-speed-yaw` shows both approaches. -When moving the vehicle you can send a separate command to :ref:`control the speed ` (and other vehicle behaviour). +You can optionally set the target movement speed using the function's ``airspeed`` or ``groundspeed`` parameters +(this is equivalent to setting :py:attr:`Vehicle.airspeed ` +or :py:attr:`Vehicle.groundspeed `). The speed setting will then be used +for all positional movement commands until it is set to another value. + +.. code-block:: python + + # Set airspeed using attribute + vehicle.airspeed = 5 #m/s + + # Set groundspeed using attribute + vehicle.groundspeed = 7.5 #m/s + + # Set groundspeed using `simple_goto()` parameter + vehicle.simple_goto(a_location, groundspeed=10) + +.. note:: + + ``Vehicle.simple_goto()`` will use the last speed value set. If both speed values are set at the + same time the resulting behaviour will be vehicle dependent. + .. tip:: @@ -256,13 +276,14 @@ Supported commands `Copter Commands in Guided Mode `_ lists all the commands that *can* be sent to Copter in GUIDED mode (in fact most of the commands can be sent in any mode!) DroneKit-Python provides a friendly Python API that abstracts many of the commands. -Where possible you should use the API rather than send messages directly. -For example it is better to use :py:func:`Vehicle.simple_takeoff() ` -than to explicitly send the ``MAV_CMD_NAV_TAKEOFF`` command. +Where possible you should use the API rather than send messages directly> For example, use: + +* :py:func:`Vehicle.simple_takeoff() ` instead of the ``MAV_CMD_NAV_TAKEOFF`` command. +* :py:func:`Vehicle.simple_goto() `, :py:attr:`Vehicle.airspeed `, + or :py:attr:`Vehicle.groundspeed ` rather than ``MAV_CMD_DO_CHANGE_SPEED``. Some of the MAV_CMD commands that you might want to send include: :ref:`MAV_CMD_CONDITION_YAW `, -:ref:`MAV_CMD_DO_CHANGE_SPEED `, :ref:`MAV_CMD_DO_SET_ROI `, ``MAV_CMD_DO_SET_SERVO``, ``MAV_CMD_DO_REPEAT_SERVO``, @@ -317,36 +338,6 @@ The command allows you to specify that whether the heading is an absolute angle -.. _guided_mode_copter_set_speed: - -Setting the speed ------------------ - -Send `MAV_CMD_DO_CHANGE_SPEED `_ to change the current speed (metres/second) when travelling to a point. - -.. code-block:: python - - def set_speed(speed): - msg = vehicle.message_factory.command_long_encode( - 0, 0, # target system, target component - mavutil.mavlink.MAV_CMD_DO_CHANGE_SPEED, #command - 0, #confirmation - 0, #param 1 - speed, # speed in metres/second - 0, 0, 0, 0, 0 #param 3 - 7 - ) - - # send command to vehicle - vehicle.send_mavlink(msg) - - -The command is useful when setting the vehicle position directly. It is not needed when controlling movement using velocity vectors. - -.. note:: - - In AC3.2.1 Copter will accelerate to the target speed across the journey and then decelerate as it reaches the target. In AC3.3 the speed changes immediately. - - .. _guided_mode_copter_set_roi: @@ -430,7 +421,14 @@ to the Earth's poles. #New position in decimal degrees newlat = original_location.lat + (dLat * 180/math.pi) newlon = original_location.lon + (dLon * 180/math.pi) - return LocationGlobal(newlat, newlon,original_location.alt) + if type(original_location) is LocationGlobal: + targetlocation=LocationGlobal(newlat, newlon,original_location.alt) + elif type(original_location) is LocationGlobalRelative: + targetlocation=LocationGlobalRelative(newlat, newlon,original_location.alt) + else: + raise Exception("Invalid Location object passed") + + return targetlocation; .. code-block:: python diff --git a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py index 663c3bf7d..30bddb2e9 100644 --- a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py +++ b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py @@ -1,3 +1,4 @@ + """ guided_set_speed_yaw.py: (Copter Only) @@ -6,7 +7,7 @@ Example documentation: http://python.dronekit.io/examples/guided-set-speed-yaw-demo.html """ -from dronekit import connect, VehicleMode, LocationGlobal +from dronekit import connect, VehicleMode, LocationGlobal, LocationGlobalRelative from pymavlink import mavutil # Needed for command message definitions import time import math @@ -132,34 +133,6 @@ def set_roi(location): vehicle.send_mavlink(msg) -def set_speed(speed): - """ - Send MAV_CMD_DO_CHANGE_SPEED to change the current speed when travelling to a point. - - In AC3.2.1 Copter will accelerate to this speed near the centre of its journey and then - decelerate as it reaches the target. In AC3.3 the speed changes immediately. - - This method is only useful when controlling the vehicle using position/goto commands. - It is not needed when controlling vehicle movement using velocity components. - - For more information see: - http://copter.ardupilot.com/common-mavlink-mission-command-messages-mav_cmd/#mav_cmd_do_change_speed - """ - # create the MAV_CMD_DO_CHANGE_SPEED command - msg = vehicle.message_factory.command_long_encode( - 0, 0, # target system, target component - mavutil.mavlink.MAV_CMD_DO_CHANGE_SPEED, #command - 0, #confirmation - 0, #param 1 - speed, # speed - 0, 0, 0, 0, 0 #param 3 - 7 - ) - - # send command to vehicle - vehicle.send_mavlink(msg) - - - """ Functions to make it easy to convert between the different frames-of-reference. In particular these @@ -197,7 +170,14 @@ def get_location_metres(original_location, dNorth, dEast): #New position in decimal degrees newlat = original_location.lat + (dLat * 180/math.pi) newlon = original_location.lon + (dLon * 180/math.pi) - return LocationGlobal(newlat, newlon,original_location.alt) + if type(original_location) is LocationGlobal: + targetlocation=LocationGlobal(newlat, newlon,original_location.alt) + elif type(original_location) is LocationGlobalRelative: + targetlocation=LocationGlobalRelative(newlat, newlon,original_location.alt) + else: + raise Exception("Invalid Location object passed") + + return targetlocation; def get_distance_metres(aLocation1, aLocation2): @@ -315,9 +295,6 @@ def goto(dNorth, dEast, gotoFunction=vehicle.simple_goto): targetLocation=get_location_metres(currentLocation, dNorth, dEast) targetDistance=get_distance_metres(currentLocation, targetLocation) gotoFunction(targetLocation) - - - while vehicle.mode.name=="GUIDED": #Stop action if we are no longer in guided mode. remainingDistance=get_distance_metres(vehicle.location.global_relative_frame, targetLocation) @@ -420,8 +397,10 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z, duration): the distance-to-target. """ print("TRIANGLE path using standard Vehicle.simple_goto()") -print("Set speed to 5m/s.") -set_speed(5) + +print("Set groundspeed to 5m/s.") +vehicle.groundspeed=5 + print("Position North 80 West 50") goto(80, -50) @@ -450,17 +429,17 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z, duration): print("TRIANGLE path using standard SET_POSITION_TARGET_GLOBAL_INT message and with varying speed.") print("Position South 100 West 130") -print("Set speed to 5m/s.") -set_speed(5) +print("Set groundspeed to 5m/s.") +vehicle.groundspeed=5 goto(-100, -130, goto_position_target_global_int) -print("Set speed to 15m/s (max).") -set_speed(15) +print("Set groundspeed to 15m/s (max).") +vehicle.groundspeed=15 print("Position South 0 East 200") goto(0, 260, goto_position_target_global_int) -print("Set speed to 10m/s (max).") -set_speed(10) +print("Set airspeed to 10m/s (max).") +vehicle.airspeed=10 print("Position North 100 West 130") goto(100, -130, goto_position_target_global_int) From 70d7a865e4410f3ef6d28766a421566655ae061b Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 23 Nov 2015 18:35:45 -0500 Subject: [PATCH 243/475] Defaults vehicle_class to None, not Vehicle. --- dronekit/__init__.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index fbd6867db..785a4c6f7 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -2283,7 +2283,7 @@ def connect(ip, _initialize=True, wait_ready=None, status_printer=errprinter, - vehicle_class=Vehicle, + vehicle_class=None, rate=4, baud=115200, heartbeat_timeout=30, @@ -2337,6 +2337,10 @@ def connect(ip, :returns: A connected vehicle of the type defined in ``vehicle_class`` (a superclass of :py:class:`Vehicle`). """ + + if not vehicle_class: + vehicle_class = Vehicle + handler = MAVConnection(ip, baud=baud, source_system=source_system) vehicle = vehicle_class(handler) From 27ddf9003237548f51279f212d0f2cc19e688c15 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 24 Nov 2015 00:10:15 -0500 Subject: [PATCH 244/475] 2.0.0 --- CHANGELOG.md | 40 ++++++++++ docs/about/github_latest_release.txt | 89 +++++++++++++++------- scripts/get_release_notes.py | 110 --------------------------- scripts/update-docs.sh | 21 +---- scripts/update-releasenotes.sh | 37 +++++++++ setup.py | 4 +- 6 files changed, 141 insertions(+), 160 deletions(-) create mode 100644 CHANGELOG.md delete mode 100755 scripts/get_release_notes.py create mode 100755 scripts/update-releasenotes.sh diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..a618ea26f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,40 @@ +# Changelog + +## Version 2.0.0 (2015-11-23) + +### New Features: + +* Renamed library and package from DroneAPI to DroneKit on pip +* DroneKit Python is now a standalone library and no longer requires use of MAVProxy +* Connect multiple vehicles in one script by creating separate vehicle instances +* Removed NumPy, ProtoBuf as dependencies +* Add MAVLink message listeners using `add_message_listener` methods +* Added `on_attribute` and `on_message` function decorator shorthands +* Added `mount_status`, `system_status`, `ekf_ok`, `is_armable`, `heading` +* Made settable `groundspeed`, `airspeed` +* Moved `dronekit.lib` entries to root package `dronekit` +* Added `parameters.set` and `parameters.get` for fine-tuned parameter access +* `parameters` now observable and iterable (#442) +* Added `last_heartbeat` attribute, updated every event loop with time since last heartbeat (#451) +* Await attributes through `wait_ready` method and `connect` method parameter +* Adds subclassable Vehicle class, used by `vehicle_class` parameter in `connect` + +### Updated Features: + +* local_connect renamed to connect(), accepting a connection path, link configuration, and timeout settings +* Removed `.set_mavrx_callback`. Use `vehicle.on_message('*', obj)` methods +* Renamed `add_attribute_observer` methods to `add_attribute_listener`, etc. (#420) +* Renamed `wait_init` and `wait_valid` to `wait_ready` +* Split `home_location` is a separate attribute from `commands` waypoint array +* Moved RC channels into `.channels` object (#427) +* Split location information into `local_frame`, `global_frame`, and `global_relative_frame` (and removed `is_relative`) (#445) +* Renamed `flush` to `commands.upload`, as it only impacts waypoints (#276) +* `commands.goto` and `commands.takeoff` renamed to `simple_goto` and `simple_takeoff` + +### Bug Fixes: + +* `armed` and `mode` attributes updated constantly (#60, #446) +* Parameter setting times out (#12) +* `battery` access can throw exception (#298) +* Vehicle.location reports incorrect is_relative value for Copter (#130) +* Excess arming message when already armed diff --git a/docs/about/github_latest_release.txt b/docs/about/github_latest_release.txt index 90a1b229f..8c4697121 100644 --- a/docs/about/github_latest_release.txt +++ b/docs/about/github_latest_release.txt @@ -1,30 +1,63 @@ .. This document was auto-generated by the get_release_notes.py script using latest-release information from github -Release 1.5.0 (August 12, 2015) -=============================== - - -**Features:** - -* Added methods to unset `mavlink_callback`. (#115, #240) -* Publishing scripts now live in `scripts/` (#259) - -**Documentation:** - -* Documented clearing of `mavlink_callback`. (#245) - -Source Code ------------ - - -Source code is available `here `_. - -* View `**commits** included in this release `_ -* View `**bugs** closed by this release `_ -* View `**pull requests** merged into this release `_ - -Notes ------ - - -Thanks to @hamishwillee, @mrpollo, @tcr3dr \ No newline at end of file +Changelog +========= + +Version 2.0.0 (2015-11-23) +-------------------------- + +New Features: +~~~~~~~~~~~~~ + +- Renamed library and package from DroneAPI to DroneKit on pip +- DroneKit Python is now a standalone library and no longer requires + use of MAVProxy +- Connect multiple vehicles in one script by creating separate vehicle + instances +- Removed NumPy, ProtoBuf as dependencies +- Add MAVLink message listeners using ``add_message_listener`` methods +- Added ``on_attribute`` and ``on_message`` function decorator + shorthands +- Added ``mount_status``, ``system_status``, ``ekf_ok``, + ``is_armable``, ``heading`` +- Made settable ``groundspeed``, ``airspeed`` +- Moved ``dronekit.lib`` entries to root package ``dronekit`` +- Added ``parameters.set`` and ``parameters.get`` for fine-tuned + parameter access +- ``parameters`` now observable and iterable (`#442 `_) +- Added ``last_heartbeat`` attribute, updated every event loop with + time since last heartbeat (`#451 `_) +- Await attributes through ``wait_ready`` method and ``connect`` method + parameter +- Adds subclassable Vehicle class, used by ``vehicle_class`` parameter + in ``connect`` + +Updated Features: +~~~~~~~~~~~~~~~~~ + +- local\_connect renamed to connect(), accepting a connection path, + link configuration, and timeout settings +- Removed ``.set_mavrx_callback``. Use ``vehicle.on_message('*', obj)`` + methods +- Renamed ``add_attribute_observer`` methods to + ``add_attribute_listener``, etc. (`#420 `_) +- Renamed ``wait_init`` and ``wait_valid`` to ``wait_ready`` +- Split ``home_location`` is a separate attribute from ``commands`` + waypoint array +- Moved RC channels into ``.channels`` object (`#427 `_) +- Split location information into ``local_frame``, ``global_frame``, + and ``global_relative_frame`` (and removed ``is_relative``) (`#445 `_) +- Renamed ``flush`` to ``commands.upload``, as it only impacts + waypoints (`#276 `_) +- ``commands.goto`` and ``commands.takeoff`` renamed to ``simple_goto`` + and ``simple_takeoff`` + +Bug Fixes: +~~~~~~~~~~ + +- ``armed`` and ``mode`` attributes updated constantly (`#60 `_, `#446 `_) +- Parameter setting times out (`#12 `_) +- ``battery`` access can throw exception (`#298 `_) +- Vehicle.location reports incorrect is\_relative value for Copter + (`#130 `_) +- Excess arming message when already armed diff --git a/scripts/get_release_notes.py b/scripts/get_release_notes.py deleted file mode 100755 index acdf524f8..000000000 --- a/scripts/get_release_notes.py +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env python - -""" -This script gets the latest release notes from a specfied github repo, converts it from markdown to -reStructured Text format, and writes it to a text file. - -The text file can be auto-imported by Sphinx into the official release notes. - ----- - -The script uses the "Requests" module to make the API requests: http://docs.python-requests.org/en/latest/ - -Github API doc for getting latest release: https://developer.github.com/v3/repos/releases/#get-the-latest-release - GET /repos/:owner/:repo/releases/latest - -Where our release is: https://github.com/dronekit/dronekit-python/releases/tag/1.1.1 -""" - -import os -import requests # for making API requests -import re # regular expressions to convert markup to reStructuredText -from optparse import OptionParser # for command line options - - -def convert_markup_to_rst(text): - """ - Convert mardown to rst format. Currently converts only (up to level 5) headings and links to rst format. - """ - - def fixheadings(matchobj): - """ - Convert mardown headings to rst headings. - """ - #print 'matched' - #print matchobj.group(0) - #print matchobj.group(1) - #print matchobj.group(2) - #print 'endmatched' - heading_level=len(matchobj.group(1)) - heading_text=matchobj.group(2).strip() - heading_length= len(heading_text) - #print heading_level - #print heading_text - #print heading_length - - heading_char='=' - if heading_level == 1 : - heading_char = '=' - if heading_level == 2 : - heading_char = '-' - if heading_level == 3 : - heading_char = '~' - if heading_level == 4 : - heading_char = '+' - if heading_level == 5 : - heading_char = '*' - heading_underline=heading_char*heading_length - return heading_text+'\n'+heading_underline+'\n' - - - def fixlinks(matchobj): - """ - Convert mardown links to rst links. - """ - #print 'matched' - #print matchobj.group(0) - #print matchobj.group(1) - #print matchobj.group(2) - #print 'endmatched' - link_url=matchobj.group(2) - link_text=matchobj.group(1) - return '`%s <%s>`_' % (link_text,link_url) - - text=re.sub(r'^(\#+)\s+(.*)', fixheadings, text, flags=re.MULTILINE) - text=re.sub(r'\[(.*?)\]\((.*?)\)', fixlinks, text, flags=re.MULTILINE) - - return text - - -curpath = os.path.realpath(os.path.dirname(__file__)) - -#parser options -parser = OptionParser(version="%prog 0.0.1", usage="Usage: %prog [options] version") -parser.add_option("-o", "--gitowner", dest="owner", default="diydrones", help="Owner of github repository") -parser.add_option("-r", "--repo", dest="repo", default="dronekit-python", help="Repo name") -parser.add_option("-f" , "--file", dest="file", default=os.path.join(curpath, "../docs/about/github_latest_release.txt"), help="File path put output file") - -(options, args) = parser.parse_args() - -latest_release_url='https://api.github.com/repos/'+options.owner+'/'+options.repo+'/releases/latest' - -print 'Fetching release notes: %s' % latest_release_url - -r = requests.get(latest_release_url) -bodytext_markdown=r.json()[u'body'] -#print bodytext_markdown -print ' Converting markdown to reStructured text' -bodytext_rst = convert_markup_to_rst(bodytext_markdown) - -#Prefix with some documentation -bodytext_rst = ".. This document was auto-generated by the get_release_notes.py script using latest-release information from github \n\n" + bodytext_rst - -#print "RST" -#print bodytext_rst -release_notes_file=open(options.file,'w') -release_notes_file.write(bodytext_rst) -release_notes_file.close() - -print ' Complete' - diff --git a/scripts/update-docs.sh b/scripts/update-docs.sh index a651404d6..50459adad 100755 --- a/scripts/update-docs.sh +++ b/scripts/update-docs.sh @@ -1,22 +1,3 @@ #!/bin/bash -cd $(dirname $0) -cd .. - -rm -r /tmp/autodocs -set -e -python ./setup.py build -echo Switching to doc tree -cd docs -make html -cp -a _build/html /tmp/autodocs -cd .. -git checkout gh-pages -cp -a /tmp/autodocs/* . -set +e -find . | xargs git add -set -e -git commit -m "Update docs" -git push -git checkout -f master - +ssh dronekit.io "./update_python.sh" diff --git a/scripts/update-releasenotes.sh b/scripts/update-releasenotes.sh new file mode 100755 index 000000000..789aa9fc9 --- /dev/null +++ b/scripts/update-releasenotes.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +""" +This script gets the release notes, converts it from markdown to +reStructured Text format, and writes it to a text file. + +The text file can be auto-imported by Sphinx into the official release notes. +""" + +import os +from pypandoc import convert +from optparse import OptionParser +import re + +curpath = os.path.realpath(os.path.dirname(__file__)) + +#parser options +parser = OptionParser(version="%prog 1.0.0", usage="Usage: %prog [options] version") +parser.add_option("-i" , "--input", dest="input", default=os.path.join(curpath, "../CHANGELOG.md"), help="Input file") +parser.add_option("-f" , "--file", dest="file", default=os.path.join(curpath, "../docs/about/github_latest_release.txt"), help="Output file") + +(options, args) = parser.parse_args() + +rst_content = convert(options.input, 'rst') + +# Hyperlink Github issues +rst_content = re.sub(r'#\d+', lambda m: '`' + m.group() + ' `_', rst_content) + +# Prefix with some documentation +rst_content = ".. This document was auto-generated by the get_release_notes.py script using latest-release information from github \n\n" + rst_content + +release_notes_file = open(options.file,'w') +release_notes_file.write(rst_content) +release_notes_file.close() + +print 'complete.' + diff --git a/setup.py b/setup.py index 218721f38..544f3dda5 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.0.0rc13' +version = '2.0.0' setup(name='dronekit', zip_safe=True, @@ -16,7 +16,7 @@ ], author_email='tim@3drobotics.com, kevinh@geeksville.com', classifiers=[ - 'Development Status :: 4 - Beta', + 'Development Status :: 5 - Production/Stable', 'Environment :: Console', 'Intended Audience :: Science/Research', 'License :: OSI Approved :: Apache Software License', From 9c5a436051d68b9ef415d5c7774047359ec7208b Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 24 Nov 2015 20:33:47 +1100 Subject: [PATCH 245/475] Add links to legacy docs and examples on front page and migration guide. Make it a little more clear these are the v2 docs --- docs/guide/migrating.rst | 5 +++++ docs/index.rst | 7 +++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/guide/migrating.rst b/docs/guide/migrating.rst index 2bfa537b9..5cbfb367e 100644 --- a/docs/guide/migrating.rst +++ b/docs/guide/migrating.rst @@ -10,6 +10,11 @@ now need to specify the vehicle target address inside the script. The sections below outline the main migration areas. +.. note:: + + *DroneKit-Python version 1.5* has now been superseded (see these links for legacy `documentation `_ + and `examples `_). + Installation ============ diff --git a/docs/index.rst b/docs/index.rst index 8b0ee6525..b86c08ed1 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -7,13 +7,16 @@ Welcome to DroneKit-Python's documentation! =========================================== -DroneKit-Python helps you create powerful apps for UAVs. These apps run on a UAV's :ref:`Companion Computer `, and augment the autopilot by performing tasks that are both computationally intensive and require a low-latency link (e.g. computer vision). +DroneKit-Python 2.x helps you create powerful apps for UAVs. These apps run on a UAV's :ref:`Companion Computer `, and augment the autopilot by performing tasks that are both computationally intensive and require a low-latency link (e.g. computer vision). This documentation provides everything you need to :doc:`get started ` with DroneKit-Python, including an :doc:`overview ` of the API, guide material, a number of demos and examples, and :doc:`API Reference `. .. tip:: - If you're migrating from DroneKit-Python version 1, check out our comprehensive :ref:`Migration Guide `. + *DroneKit-Python version 1.5* has now been superseded (see these links for legacy `documentation `_ + and `examples `_). + + If you're migrating from *DroneKit-Python version 1.x*, check out our comprehensive :ref:`Migration Guide `. Contents: From a094ea75e7d9fcd80b4651437b285fae2a2b7254 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 26 Nov 2015 14:17:32 +1100 Subject: [PATCH 246/475] Improve information about setting baud rate when connecting --- docs/guide/getting_started.rst | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/guide/getting_started.rst b/docs/guide/getting_started.rst index 9ce99ff01..d49f0dbd4 100644 --- a/docs/guide/getting_started.rst +++ b/docs/guide/getting_started.rst @@ -137,18 +137,22 @@ the more common connection types: * - Linux computer connected to the vehicle via USB - ``/dev/ttyUSB0`` * - Linux computer connected to the vehicle via Serial port (RaspberryPi example) - - ``/dev/ttyAMA0`` - - .. note:: - To connect on a serial port you may also need to reduce the baud rate to 57600 - - e.g. ``vehicle=connect('/dev/ttyAMA0', baud=57600)`` + - ``/dev/ttyAMA0, baud=57600`` * - SITL connected to the vehicle via UDP - ``127.0.0.1:14550`` * - OSX computer connected to the vehicle via USB - ``dev/cu.usbmodem1`` * - Windows computer connected to the vehicle via USB (in this case on COM14) - ``com14`` - + * - Windows computer connected to the vehicle using a 3DR Telemetry Radio on COM14 + - ``com14, baud=57600`` + +.. note:: + The default baud rate may not be appropriate for all connection types (check this + if you can connect via a GCS but not DroneKit). + You can specify a different rate using the :py:func:`baud ` + parameter when connecting. For example: ``vehicle=connect('com14', baud=57600)``. + .. tip:: The strings above are the same as you would use if connecting with MAVProxy. For other options see the From 367be9323d1780e1bcf28babef7a01cbb27a13f3 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 26 Nov 2015 15:03:31 +1100 Subject: [PATCH 247/475] Further updates in line with feedback --- docs/guide/getting_started.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guide/getting_started.rst b/docs/guide/getting_started.rst index d49f0dbd4..8fc4bb45e 100644 --- a/docs/guide/getting_started.rst +++ b/docs/guide/getting_started.rst @@ -137,7 +137,7 @@ the more common connection types: * - Linux computer connected to the vehicle via USB - ``/dev/ttyUSB0`` * - Linux computer connected to the vehicle via Serial port (RaspberryPi example) - - ``/dev/ttyAMA0, baud=57600`` + - ``/dev/ttyAMA0`` (also set ``baud=57600``) * - SITL connected to the vehicle via UDP - ``127.0.0.1:14550`` * - OSX computer connected to the vehicle via USB @@ -145,7 +145,7 @@ the more common connection types: * - Windows computer connected to the vehicle via USB (in this case on COM14) - ``com14`` * - Windows computer connected to the vehicle using a 3DR Telemetry Radio on COM14 - - ``com14, baud=57600`` + - ``com14`` (also set ``baud=57600``) .. note:: The default baud rate may not be appropriate for all connection types (check this From 950f4fa1f660437332643acb90a1341f980d9a99 Mon Sep 17 00:00:00 2001 From: Mark Wieder Date: Sat, 28 Nov 2015 11:59:22 -0800 Subject: [PATCH 248/475] fixed Unknown Endpoint message --- dronekit/cloud/CloudClient.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/cloud/CloudClient.py b/dronekit/cloud/CloudClient.py index 4f663dad1..6b3443807 100644 --- a/dronekit/cloud/CloudClient.py +++ b/dronekit/cloud/CloudClient.py @@ -48,5 +48,5 @@ def method(*args): def _request(self, url, data): self.response = requests.get("%s%s" % (self.BASE_URL, url), headers=self.headers) if self.response.status_code == 404: - raise CloudError(self.response.status_code, 'Unkown Endpoint', self.response) + raise CloudError(self.response.status_code, 'Unknown Endpoint', self.response) return self.response From 1c714b01c7f0a5927391bb90f3bc97b67ba66a34 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 30 Nov 2015 17:37:09 -0500 Subject: [PATCH 249/475] Bumps required requests versions. --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 928cd69c7..3257caf2b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -requests==2.5.1 +requests>=2.5.0,<=2.99999 pymavlink>=1.1.62 sphinx-3dr-theme>=0.0.6 nose>=1.3.7 From 753cc67801560881988ad549cbeaf9c36fb9ef18 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 30 Nov 2015 17:40:48 -0500 Subject: [PATCH 250/475] 2.0.1 --- CHANGELOG.md | 7 +++++++ setup.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a618ea26f..c119d285d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## Version 2.0.1 (2015-11-30) + +### Bug Fixes: + +* Updates `requests` dependency to work >=2.5.0 + + ## Version 2.0.0 (2015-11-23) ### New Features: diff --git a/setup.py b/setup.py index 544f3dda5..150d587ef 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.0.0' +version = '2.0.1' setup(name='dronekit', zip_safe=True, From fe53c9b7b4c2a63bfb5caac179b9e4846ce84caa Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 30 Nov 2015 17:51:04 -0500 Subject: [PATCH 251/475] Fixes setup.py to match requirements.txt. --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 150d587ef..44b2e78cd 100644 --- a/setup.py +++ b/setup.py @@ -11,8 +11,8 @@ url='https://github.com/dronekit/dronekit-python', author='3D Robotics', install_requires=[ - 'pymavlink >= 1.1.62', - 'requests == 2.5.1', + 'pymavlink>=1.1.62', + 'requests>=2.5.0,<=2.99999', ], author_email='tim@3drobotics.com, kevinh@geeksville.com', classifiers=[ From 9130d584fc7f05b4e1cad1f54afd99fe1bc8051f Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Mon, 30 Nov 2015 17:51:09 -0500 Subject: [PATCH 252/475] 2.0.2 --- CHANGELOG.md | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c119d285d..31bf9b2fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Version 2.0.1 (2015-11-30) +## Version 2.0.2 (2015-11-30) ### Bug Fixes: diff --git a/setup.py b/setup.py index 44b2e78cd..e7cc78431 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.0.1' +version = '2.0.2' setup(name='dronekit', zip_safe=True, From af46c1b03b6df04e0f62c753a810040d5a764beb Mon Sep 17 00:00:00 2001 From: GOPI Date: Mon, 30 Nov 2015 19:35:00 -0500 Subject: [PATCH 253/475] drone_delivery fails when try to execute go to command, this is due to a bug executing simple_goto changed line 113 and 120 from self.simple_goto to self.vehicle.simple_goto --- examples/drone_delivery/drone_delivery.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/drone_delivery/drone_delivery.py b/examples/drone_delivery/drone_delivery.py index 83ba0d28f..36386f527 100644 --- a/examples/drone_delivery/drone_delivery.py +++ b/examples/drone_delivery/drone_delivery.py @@ -110,14 +110,14 @@ def goto(self, location, relative=None): self._log("Goto: {0}, {1}".format(location, self.altitude)) if relative: - self.simple_goto( + self.vehicle.simple_goto( LocationGlobalRelative( float(location[0]), float(location[1]), float(self.altitude) ) ) else: - self.simple_goto( + self.vehicle.simple_goto( LocationGlobal( float(location[0]), float(location[1]), float(self.altitude) From 610a5a6996f18bd0bb7012d1c0b21fdf2a91ab1c Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 4 Dec 2015 13:15:53 +1100 Subject: [PATCH 254/475] Remove note about not documenting patch releases --- docs/about/release_notes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/about/release_notes.rst b/docs/about/release_notes.rst index 4e5b91107..c85bc804c 100644 --- a/docs/about/release_notes.rst +++ b/docs/about/release_notes.rst @@ -6,7 +6,7 @@ This page contains the release notes for DroneKit-Python ``minor`` and ``major`` .. note:: - DroneKit-Python marks releases using the ``major.minor.patch`` release numbering convention, where ``patch`` is used to denote only bug fixes, ``minor`` is used for releases with new features, and ``major`` indicates the release contains significant API changes. Patch releases are not separately documented here. + DroneKit-Python marks releases using the ``major.minor.patch`` release numbering convention, where ``patch`` is used to denote only bug fixes, ``minor`` is used for releases with new features, and ``major`` indicates the release contains significant API changes. From 99cce835f0e1cb7dc1d231fc8d219c857cea27af Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 4 Dec 2015 15:12:49 +1100 Subject: [PATCH 255/475] Update test instructions to dkpy2 --- docs/contributing/contributions_api.rst | 94 ++++++++++++++++++------- 1 file changed, 67 insertions(+), 27 deletions(-) diff --git a/docs/contributing/contributions_api.rst b/docs/contributing/contributions_api.rst index 7e137abc5..344b0e0bc 100644 --- a/docs/contributing/contributions_api.rst +++ b/docs/contributing/contributions_api.rst @@ -57,41 +57,59 @@ For several tests, you may be required to set an **environment variable**. In yo Unit tests ---------- -Unit tests use *nosetests*. On any OS, enter the following command on a terminal/prompt to run the unit tests (and display a summary of the results): +All new features that are written should be created with accompanying unit tests. + +A good unit tests should: + +#. Verify all code paths that code can take. +#. Be concise and straightforward. +#. Be documented. + +DroneKit-Python unit tests are based on the `nose `_ test framework, +and use `mock `_ to simulate objects and APIs and +ensure correct results. + +To run the tests and display a summary of the results (on any OS), +navigate to the **dronekit-python** folder and enter the following +command on a terminal/prompt: .. code:: bash - cd dronekit-python nosetests tests/unit + -For unit tests, `mock `_ is used to simulate objects and APIs and ensure correct results. Writing a new unit test ^^^^^^^^^^^^^^^^^^^^^^^ -Good unit tests should: +Create any file named :file:`test_XXX.py` in the :file:`tests/unit` folder to add it as a test. +Feel free to copy from existing tests to get started. When *nosetests* is run, it will add your new test to its summary. -#. Accompany all new features that are written. -#. Verify all code paths that code can take. -#. Be concise and straightforward. +Tests names should be named based on their associated Github issue (for example, +``test_12.py`` for `issue #12 `_) +or describe the functionality covered (for example, ``test_waypoints.py`` +for a unit test for the waypoints API). + +Use assertions to test your code is consistent. You can use the built-in Python ``assert`` macro as well as ``assert_equals`` and ``assert_not_equals`` +from the ``notestools`` module: -Create any file named :file:`test_XXX.py` in the :file:`tests/unit` folder to add it as a test. Feel free to copy from existing tests to get started. When *nosetests* is run, it will add your new test to its summary. +.. note:: -Tests names should refer directly to a Github issue (for example, ``test_12.py`` would refer to `issue #12 `_ or describe fully what functionality they encompass (for example, ``test_waypoints.py`` would describe a unit test for the waypoints API). - -Avoiding printing any data from your test. Instead, use assertions to test your code is consistent. You can use the built-in Python ``assert`` macro as well as ``assert_equals`` from the ``nose.tools`` module: + Avoiding printing any data from your test! .. code:: python - from nose.tools import assert_equals + from nose.tools import assert_equals, assert_not_equals def test_this(the_number_two): assert the_number_two > 0, '2 should be greater than zero!' - assert_equals(the_number_two, 2, '2 should equal two!' - + assert_equals(the_number_two, 2, '2 should equal two!') + assert_not_equals(the_number_two, 1, '2 should equal one!') + Please add documentation to each test function describing what behavior it verifies. + Integration tests ----------------- @@ -101,6 +119,15 @@ Integrated tests use a custom test runner that is similar to *nosetests*. On any cd dronekit-python python -um tests.sitl + +You can choose to test specific files by passing them as arguments: + +.. code:: bash + + python -um tests.sitl test_1.py test2_.py ... + +Configuring the test environment +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Integrated tests use the SITL environment to run DroneKit tests against a simulated Copter. Because these tests emulate Copter in real-time, you can set several environment variables to tweak the environment that code is run in: @@ -108,11 +135,7 @@ Integrated tests use the SITL environment to run DroneKit tests against a simula #. ``TEST_RATE`` - Sets framerate. Default is ``TEST_RATE=200`` for copter, 50 for rover, 50 for plane. #. ``TEST_RETRY`` - Retry failed tests. Default is ``TEST_RETRY=1``. This is useful if your testing environment generates inconsistent success rates because of timing. -You can choose to test specific files by passing them as arguments: - -.. code:: bash - python -um tests.sitl test_1.py test2_.py ... Writing a new integration test ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -123,23 +146,40 @@ Integration tests should be written or improved whenever: #. Example code or documentation has been added. #. A feature could not be tested by unit tests alone (e.g. timing issues, mode changing, etc.) -You can write a new integrated test by adding a file with the naming scheme :file:`test_XXX.py` to the :file:`tests/sitl` directory. In this file, functions with the prefix ``test_`` will be called with the ``local_connect`` parameter. For example: +You can write a new integrated test by adding (or copying) a file with the naming scheme :file:`test_XXX.py` to the :file:`tests/sitl` directory. + +Tests names should be named based on their associated Github issue (for example, +``test_12.py`` for `issue #12 `_) +or describe the functionality covered (for example, ``test_waypoints.py`` +for an integration test for the waypoints API). + +Tests should minimally use the imports shown below and decorate test functions with ``@with_sitl`` +(this sets up the test and passes in a connection string for SITL). .. code:: python - from testlib import assert_equals + from dronekit import connect + from dronekit.test import with_sitl + from nose.tools import assert_equals, assert_not_equals + + @with_sitl + def test_something(connpath): + vehicle = connect(connpath) + + # Test using assert, assert_equals and assert_not_equals + ... + + vehicle.close() - def test_parameters(local_connect): - v = local_connect().get_vehicles()[0] - # Simple parameter checks - assert_equals(type(v.parameters['THR_MIN']), float) +Use assertions to test your code is consistent. You can use the built-in Python ``assert`` macro as well as ``assert_equals`` and ``assert_not_equals`` +from the ``testlib`` module: -This checks to see that the parameter object is of type `float`. +.. note:: -Tests names should refer directly to a Github issue (for example, ``test_12.py`` would refer to `issue #12 `_ or describe fully what functionality they encompass (for example, ``test_waypoints.py`` would describe a unit test for the waypoints API). + Avoiding printing any data from your test! + -Avoiding printing any data from your test. Instead, use assertions to test your code is consistent. You can use the built-in Python ``assert`` macro as well as ``assert_equals`` from the ``testlib`` module: .. code:: python From 75e1d8b11271d6f9a95097cfff19e56954f7475b Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 7 Dec 2015 11:40:34 +1100 Subject: [PATCH 256/475] Update with information on how to run tests and additional dependencies for tests --- docs/contributing/contributions_api.rst | 42 ++++++++++++++++--------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/docs/contributing/contributions_api.rst b/docs/contributing/contributions_api.rst index 344b0e0bc..8cdafc8ee 100644 --- a/docs/contributing/contributions_api.rst +++ b/docs/contributing/contributions_api.rst @@ -30,21 +30,37 @@ repository and contribute changes back to the project master branch using pull r Test code ========= -Test code should be used to verify new and changed functionality. There are three test suites in DroneKit-Python: +There are three test suites in DroneKit-Python: * **Unit tests** (:file:`tests/unit`) — verify all code paths of the API. * **Integration tests** (:file:`tests/sitl`) — verify real-world code, examples, and documentation as they would perform in a real environment. * **Web client tests** (:file:`tests/web`) — specifically verify the Python library's capability to talk to `DroneKit Cloud `_. +Test code should be used to verify new and changed functionality. New tests should: + +#. Verify all code paths that code can take. +#. Be concise and straightforward. +#. Be documented. + + Setting up local testing ------------------------ -The links below provide information on how to set up a development environment on your development computer. Changes to DroneKit can then be tested locally. +Follow the links below to set up a development environment on your Linux or Windows computer. * :ref:`dronekit_development_linux` * :ref:`dronekit_development_windows` -Several of the test suites use `nose `_, a Python library for writing test scripts and a command line tool for running these. When setting up your dev environment, all test dependencies will have been installed (via :file:`requirements.txt`). +The tests require additional pip modules, including `nose `_, a +Python library and tool for writing and running test scripts. These can be installed separately using either of the commands below: + +.. code:: bash + + # Install just the additional requirements for tests + pip install requests nose mock + + # (or) Install all requirements for dronekit, tests, and building documentation + pip install -r requirements.txt For several tests, you may be required to set an **environment variable**. In your command line, you can set the name of a variable to equal a value using the following invocation, depending on your OS: @@ -57,13 +73,7 @@ For several tests, you may be required to set an **environment variable**. In yo Unit tests ---------- -All new features that are written should be created with accompanying unit tests. - -A good unit tests should: - -#. Verify all code paths that code can take. -#. Be concise and straightforward. -#. Be documented. +All new features should be created with accompanying unit tests. DroneKit-Python unit tests are based on the `nose `_ test framework, and use `mock `_ to simulate objects and APIs and @@ -75,7 +85,7 @@ command on a terminal/prompt: .. code:: bash - nosetests tests/unit + nosetests dronekit.test.unit @@ -118,14 +128,16 @@ Integrated tests use a custom test runner that is similar to *nosetests*. On any .. code:: bash cd dronekit-python - python -um tests.sitl + nosetests dronekit.test.sitl -You can choose to test specific files by passing them as arguments: +You can choose to run a specific tests. The example below shows how to run +**\dronekit-python\dronekit\test\sitl\test_12.py**. .. code:: bash - python -um tests.sitl test_1.py test2_.py ... - + nosetests dronekit.test.sitl.test_12 + + Configuring the test environment ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 0dde190ad535b7ddcb2f801e662c549a89f359af Mon Sep 17 00:00:00 2001 From: Daniel Nugent Date: Wed, 9 Dec 2015 21:19:12 -0800 Subject: [PATCH 257/475] Gimbal: Added gimbal control --- dronekit/__init__.py | 115 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 785a4c6f7..0a6d9e8f5 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -887,6 +887,9 @@ def listener(self, name, m): self._mount_yaw = m.pointing_c / 100 self.notify_attribute_listeners('mount', self.mount_status) + # gimbal + self._gimbal = Gimbal(self) + # All keys are strings. self._channels = Channels(self, 8) @@ -1894,6 +1897,118 @@ def wait_ready(self, *types, **kwargs): return True + +class Gimbal(HasObservers): + """ + Gimbal control and status. + + An object of this type is returned by :py:attr:`Vehicle.gimbal`. + .. note:: + + All the orientation "values" (e.g. ``gimbal.yaw``) are initially + created with value ``None``. The orientation values are populated + shortly after initialisation ONLY if a gimbal is present.""" + + def __init__(self, vehicle): + super(Gimbal, self).__init__() + + self._pitch = None + self._roll = None + self._yaw = None + self._vehicle = vehicle + + @vehicle.on_message('MOUNT_STATUS') + def listener(vehicle, name, m): + self._pitch = m.pointing_a / 100 + self._roll = m.pointing_b / 100 + self._yaw = m.pointing_c / 100 + vehicle.notify_attribute_listeners('gimbal', vehicle.gimbal) + + @property + def pitch(self): + return self._pitch + + @property + def roll(self): + return self._roll + + @property + def yaw(self): + return self._yaw + + def rotate(self, pitch, roll, yaw): + """ + Rotate the gimbal to a specific vector. + + :param pitch: gimbal pitch, degrees + :param roll: gimbal roll, degrees + :param yaw: gimbal yaw, degrees in global frame + """ + msg = self._vehicle.message_factory.mount_configure_encode( + 0, 1, # target system, target component + mavutil.mavlink.MAV_MOUNT_MODE_MAVLINK_TARGETING, #mount_mode + 1, # stabilize roll + 1, # stabilize pitch + 1, # stabilize yaw + ) + self._vehicle.send_mavlink(msg) + msg = self._vehicle.message_factory.mount_control_encode( + 0, 1, # target system, target component + pitch * 100, # pitch is in centidegrees + roll * 100, # roll + yaw * 100, # yaw is in centidegrees + 0) # save position + self._vehicle.send_mavlink(msg) + + def target_gps(self,roi): + """ + Point the gimbal at a specific :py:attr:`global_relative_frame ` (:py:class:`LocationGlobalRelative`) location. + This is commonly known as a Region of Interest(ROI) + + This function can be called in AUTO or GUIDED mode + + In order to clear an ROI you can send :py:attr:`global_relative_frame ` (:py:class:`LocationGlobalRelative`) with all zeros. LocationGlobalRelative(0,0,0) + + :param roi: Target location, :py:attr:`global_relative_frame ` (:py:class:`LocationGlobalRelative`). + """ + #set gimbal to targeting mode + msg = self._vehicle.message_factory.mount_configure_encode( + 0, 1, # target system, target component + mavutil.mavlink.MAV_MOUNT_MODE_GPS_POINT, #mount_mode + 1, # stabilize roll + 1, # stabilize pitch + 1, # stabilize yaw + ) + self._vehicle.send_mavlink(msg) + #set the ROI + msg = self._vehicle.message_factory.command_long_encode( + 0, 1, # target system, target component + mavutil.mavlink.MAV_CMD_DO_SET_ROI, #command + 0, #confirmation + 0, 0, 0, 0, #params 1-4 + roi.lat, + roi.lon, + roi.alt + ) + self._vehicle.send_mavlink(msg) + + def release(self): + """ + Release control of the gimbal to the user(RC Control) + """ + msg = self._vehicle.message_factory.mount_configure_encode( + 0, 1, # target system, target component + mavutil.mavlink.MAV_MOUNT_MODE_RC_TARGETING, #mount_mode + 1, # stabilize roll + 1, # stabilize pitch + 1, # stabilize yaw + ) + self._vehicle.send_mavlink(msg) + + def __str__(self): + return "Gimbal: pitch={0}, roll={1}, yaw={2}".format(self.pitch, self.roll, self.yaw) + + class Parameters(collections.MutableMapping, HasObservers): """ This object is used to get and set the values of named parameters for a vehicle. See the following links for information about From a3e93b354f5954148f708379c9b1247c12a3d1ba Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 11 Dec 2015 11:14:07 +1100 Subject: [PATCH 258/475] Update API reference docs and add the gimbal property --- dronekit/__init__.py | 51 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 0a6d9e8f5..911114721 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -19,8 +19,8 @@ Vehicle movement is primarily controlled using the :py:attr:`Vehicle.armed` attribute and :py:func:`Vehicle.simple_takeoff` and :py:attr:`Vehicle.simple_goto` in GUIDED mode. -Control over speed, direction, altitude, camera trigger and any other aspect of the vehicle is supported -using custom MAVLink messages + +Velocity-based movement and control over other vehicle features can be achieved using custom MAVLink messages (:py:func:`Vehicle.send_mavlink`, :py:func:`Vehicle.message_factory`). It is also possible to work with vehicle "missions" using the :py:attr:`Vehicle.commands` attribute, and run them in AUTO mode. @@ -1531,10 +1531,22 @@ def airspeed(self, speed): # send command to vehicle self.send_mavlink(msg) + + + @property + def gimbal(self): + """ + Gimbal object for controlling, viewing and observing gimbal status (:py:class:`Gimbal`). + + .. versionadded:: 2.1.0 + """ + return self._gimbal @property def mount_status(self): """ + .. warning:: This method is deprecated. It has been replaced by :py:attr:`gimbal`. + Current status of the camera mount (gimbal) as a three element list: ``[ pitch, yaw, roll ]``. The values in the list are set to ``None`` if no mount is configured. @@ -1897,17 +1909,25 @@ def wait_ready(self, *types, **kwargs): return True - -class Gimbal(HasObservers): +class Gimbal(object): """ - Gimbal control and status. + Gimbal status and control. + + An object of this type is returned by :py:attr:`Vehicle.gimbal`. The current + gimbal orientation can be obtained from the :py:attr:`roll`, :py:attr:`pitch` and + :py:attr:`yaw` attributes. + + The gimbal position can be orientation can be set explicitly using :py:func:`rotate` + or you can set the gimbal (and vehicle) to track a specific position using + :py:func:`target_location`. - An object of this type is returned by :py:attr:`Vehicle.gimbal`. .. note:: - All the orientation "values" (e.g. ``gimbal.yaw``) are initially + All the orientation attributes (e.g. :py:attr:`yaw`) are initially created with value ``None``. The orientation values are populated - shortly after initialisation ONLY if a gimbal is present.""" + shortly after initialisation ONLY if a gimbal is present. + + """ def __init__(self, vehicle): super(Gimbal, self).__init__() @@ -1926,14 +1946,23 @@ def listener(vehicle, name, m): @property def pitch(self): + """ + Gimbal pitch in degrees (0-360). + """ return self._pitch @property def roll(self): + """ + Gimbal roll in degrees (0-360). + """ return self._roll @property def yaw(self): + """ + Gimbal yaw in degrees (0-360), relative to global frame - 0 is North. + """ return self._yaw def rotate(self, pitch, roll, yaw): @@ -1960,16 +1989,16 @@ def rotate(self, pitch, roll, yaw): 0) # save position self._vehicle.send_mavlink(msg) - def target_gps(self,roi): + def target_location(self,roi): """ Point the gimbal at a specific :py:attr:`global_relative_frame ` (:py:class:`LocationGlobalRelative`) location. This is commonly known as a Region of Interest(ROI) This function can be called in AUTO or GUIDED mode - In order to clear an ROI you can send :py:attr:`global_relative_frame ` (:py:class:`LocationGlobalRelative`) with all zeros. LocationGlobalRelative(0,0,0) + In order to clear an ROI you can send a :py:class:`LocationGlobalRelative` with all zeros (``LocationGlobalRelative(0,0,0)``). - :param roi: Target location, :py:attr:`global_relative_frame ` (:py:class:`LocationGlobalRelative`). + :param LocationGlobalRelative roi: Target location in global relative frame. """ #set gimbal to targeting mode msg = self._vehicle.message_factory.mount_configure_encode( From 562def4ded47faa1080de87a6535ecd1fe30a16f Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 11 Dec 2015 17:10:24 +1100 Subject: [PATCH 259/475] Update example docs and guide following testing --- docs/examples/vehicle_state.rst | 2 +- docs/guide/vehicle_state_and_parameters.rst | 45 ++++++---- dronekit/__init__.py | 94 ++++++++++++++++----- examples/vehicle_state/vehicle_state.py | 2 +- 4 files changed, 101 insertions(+), 42 deletions(-) diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index 6e2a673a0..4d9a1510e 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -64,7 +64,7 @@ On the command prompt you should see (something like): Attitude: Attitude:pitch=0.00294387154281,yaw=-0.11805768311,roll=0.00139428151306 Velocity: [-0.03, 0.02, 0.0] GPS: GPSInfo:fix=3,num_sat=10 - Mount status: [None, None, None] + Gimbal status: Gimbal: pitch=None, roll=None, yaw=None Battery: Battery:voltage=12.587,current=0.0,level=100 EKF OK?: False Last Heartbeat: 0.769999980927 diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index b6c935f23..1062e1be6 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -27,7 +27,7 @@ Vehicle state information is exposed through vehicle *attributes*. DroneKit-Pyth :py:attr:`Vehicle.attitude `, :py:attr:`Vehicle.velocity `, :py:attr:`Vehicle.gps_0 `, -:py:attr:`Vehicle.mount_status `, +:py:attr:`Vehicle.gimbal `, :py:attr:`Vehicle.battery `, :py:attr:`Vehicle.rangefinder `, :py:attr:`Vehicle.ekf_ok `, @@ -46,11 +46,12 @@ Attributes are initially created with ``None`` values for their members. In most All of the attributes can be :ref:`read `, but only the :py:attr:`Vehicle.home_location `, +:py:attr:`Vehicle.gimbal ` :py:attr:`Vehicle.airspeed `, :py:attr:`Vehicle.groundspeed `, :py:attr:`Vehicle.mode ` and :py:attr:`Vehicle.armed ` -status can be :ref:`written `. +status can be :ref:`set `. Almost all of the attributes can be :ref:`observed `. @@ -76,7 +77,7 @@ regularly updated from MAVLink messages sent by the vehicle). print "GPS: %s" % vehicle.gps_0 print "Groundspeed: %s" % vehicle.groundspeed print "Airspeed: %s" % vehicle.airspeed - print "Mount status: %s" % vehicle.mount_status + print "Gimbal status: %s" % vehicle.gimbal print "Battery: %s" % vehicle.battery print "EKF OK?: %s" % vehicle.ekf_ok print "Last Heartbeat: %s" % vehicle.last_heartbeat @@ -114,11 +115,12 @@ regularly updated from MAVLink messages sent by the vehicle). Setting attributes ------------------ -Only the :py:attr:`Vehicle.mode ` :py:attr:`Vehicle.armed ` +The :py:attr:`Vehicle.mode `, :py:attr:`Vehicle.armed ` , :py:attr:`Vehicle.airspeed ` and :py:attr:`Vehicle.groundspeed `, -attributes can be written (``Vehicle.home_location`` is a special case, as :ref:`discussed below `). +attributes can all be "directly" written (:py:attr:`Vehicle.home_location ` can also be directly written, +but has special considerations that are :ref:`discussed below `). -The attributes are set by assigning a value: +These attributes are set by assigning a value: .. code:: python @@ -128,18 +130,9 @@ The attributes are set by assigning a value: #set the default groundspeed to be used in movement commands vehicle.groundspeed = 3.2 -.. warning:: - Changing a value is **not guaranteed to succeed**. - For example, vehicle arming can fail if the vehicle doesn't pass pre-arming checks, - and it is possible that the message will not even arrive at the vehicle. - - While the autopilot does send information about the success (or failure) of the request, - this is `not currently handled by DroneKit `_. - - -Code should not assume that an attempt to set an attribute will succeed. The example code snippet below polls the attribute values -to confirm they have changed before proceeding. +Commands to change a value are **not guaranteed to succeed** (or even to be received) and code should be written with this in mind. +For example, the code snippet below polls the attribute values to confirm they have changed before proceeding. .. code:: python @@ -149,6 +142,24 @@ to confirm they have changed before proceeding. print " Getting ready to take off ..." time.sleep(1) +.. note:: + + While the autopilot does send information about the success (or failure) of the request, + this is `not currently handled by DroneKit `_. + +:py:attr:`Vehicle.gimbal ` can't be written directly, but the gimbal can be controlled using the +:py:func:`Vehicle.gimbal.rotate() ` and :py:func:`Vehicle.gimbal.target_location() ` +methods. The first method lets you set the precise orientation of the gimbal while the second makes the gimbal track a specific "region of interest". + +.. code:: python + + #Point the gimbal straight down + vehicle.gimbal.rotate(-90, 0, 0) + time.sleep(10) + + #Set the camera to track the current home position. + vehicle.gimbal.target_location(vehicle.home_location) + time.sleep(10) .. _vehicle_state_observe_attributes: diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 911114721..603601688 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -68,6 +68,8 @@ class Attitude(object): An object of this type is returned by :py:attr:`Vehicle.attitude`. + .. _figure_attitude: + .. figure:: http://upload.wikimedia.org/wikipedia/commons/thumb/c/c1/Yaw_Axis_Corrected.svg/500px-Yaw_Axis_Corrected.svg.png :width: 400px :alt: Diagram showing Pitch, Roll, Yaw @@ -1913,20 +1915,24 @@ class Gimbal(object): """ Gimbal status and control. - An object of this type is returned by :py:attr:`Vehicle.gimbal`. The current - gimbal orientation can be obtained from the :py:attr:`roll`, :py:attr:`pitch` and + An object of this type is returned by :py:attr:`Vehicle.gimbal`. The + gimbal orientation can be obtained from its :py:attr:`roll`, :py:attr:`pitch` and :py:attr:`yaw` attributes. - The gimbal position can be orientation can be set explicitly using :py:func:`rotate` - or you can set the gimbal (and vehicle) to track a specific position using + The gimbal orientation can be set explicitly using :py:func:`rotate` + or you can set the gimbal (and vehicle) to track a specific "region of interest" using :py:func:`target_location`. .. note:: - - All the orientation attributes (e.g. :py:attr:`yaw`) are initially - created with value ``None``. The orientation values are populated - shortly after initialisation ONLY if a gimbal is present. - + + * The orientation attributes are created with values of ``None``. If a gimbal is present, + the attributes are populated shortly after initialisation by messages from the autopilot. + * The attribute values reflect the last gimbal setting-values rather than actual measured values. + This means that the values won't change if you manually move the gimbal, and that the value + will change when you set it, even if the specified orientation is not supported. + * A gimbal may not support all axes of rotation. For example, the Solo gimbal will set pitch + values from 0 to -90 (straight ahead to straight down), it will rotate the vehicle to follow specified + yaw values, and will ignore roll commands (not supported). """ def __init__(self, vehicle): @@ -1947,31 +1953,52 @@ def listener(vehicle, name, m): @property def pitch(self): """ - Gimbal pitch in degrees (0-360). + Gimbal pitch in degrees relative to the vehicle (see diagram for :ref:`attitude `). + A value of 0 represents a camera pointed straight ahead relative to the front of the vehicle, + while -90 points the camera straight down. + + .. note:: + + This is the last pitch value sent to the gimbal (not the actual/measured pitch). """ return self._pitch @property def roll(self): """ - Gimbal roll in degrees (0-360). + Gimbal roll in degrees relative to the vehicle (see diagram for :ref:`attitude `). + + .. note:: + + This is the last roll value sent to the gimbal (not the actual/measured roll). """ return self._roll @property def yaw(self): """ - Gimbal yaw in degrees (0-360), relative to global frame - 0 is North. + Gimbal yaw in degrees relative to *global frame* (0 is North, 90 is West, 180 is South etc). + + .. note:: + + This is the last yaw value sent to the gimbal (not the actual/measured yaw). """ return self._yaw def rotate(self, pitch, roll, yaw): """ Rotate the gimbal to a specific vector. + + .. code-block:: python + + #Point the gimbal straight down + vehicle.gimbal.rotate(-90, 0, 0) - :param pitch: gimbal pitch, degrees - :param roll: gimbal roll, degrees - :param yaw: gimbal yaw, degrees in global frame + :param pitch: Gimbal pitch in degrees relative to the vehicle (see diagram for :ref:`attitude `). + A value of 0 represents a camera pointed straight ahead relative to the front of the vehicle, + while -90 points the camera straight down. + :param roll: Gimbal roll in degrees relative to the vehicle (see diagram for :ref:`attitude `). + :param yaw: Gimbal yaw in degrees relative to *global frame* (0 is North, 90 is West, 180 is South etc.) """ msg = self._vehicle.message_factory.mount_configure_encode( 0, 1, # target system, target component @@ -1991,14 +2018,20 @@ def rotate(self, pitch, roll, yaw): def target_location(self,roi): """ - Point the gimbal at a specific :py:attr:`global_relative_frame ` (:py:class:`LocationGlobalRelative`) location. - This is commonly known as a Region of Interest(ROI) + Point the gimbal at a specific region of interest (ROI). + + .. code-block:: python - This function can be called in AUTO or GUIDED mode + #Set the camera to track the current home location. + vehicle.gimbal.target_location(vehicle.home_location) - In order to clear an ROI you can send a :py:class:`LocationGlobalRelative` with all zeros (``LocationGlobalRelative(0,0,0)``). + The target position must be defined in a :py:class:`LocationGlobalRelative` or :py:class:`LocationGlobal`. - :param LocationGlobalRelative roi: Target location in global relative frame. + This function can be called in AUTO or GUIDED mode. + + In order to clear an ROI you can send a location with all zeros (e.g. ``LocationGlobalRelative(0,0,0)``). + + :param roi: Target location in global relative frame. """ #set gimbal to targeting mode msg = self._vehicle.message_factory.mount_configure_encode( @@ -2009,7 +2042,19 @@ def target_location(self,roi): 1, # stabilize yaw ) self._vehicle.send_mavlink(msg) - #set the ROI + + #Get altitude relative to home irrespective of Location object passed in. + if isinstance(roi, LocationGlobalRelative): + alt = roi.alt + elif isinstance(roi, LocationGlobal): + if not self.home_location: + self.commands.download() + self.commands.wait_ready() + alt = roi.alt - self.home_location.alt + else: + raise APIException('Expecting location to be LocationGlobal or LocationGlobalRelative.') + + #set the ROI msg = self._vehicle.message_factory.command_long_encode( 0, 1, # target system, target component mavutil.mavlink.MAV_CMD_DO_SET_ROI, #command @@ -2017,13 +2062,16 @@ def target_location(self,roi): 0, 0, 0, 0, #params 1-4 roi.lat, roi.lon, - roi.alt + alt ) self._vehicle.send_mavlink(msg) def release(self): """ - Release control of the gimbal to the user(RC Control) + Release control of the gimbal to the user (RC Control). + + This should be called once you've finished controlling the mount with either :py:func:`rotate` + or :py:func:`target_location`. Control will automatically be released if you change vehicle mode. """ msg = self._vehicle.message_factory.mount_configure_encode( 0, 1, # target system, target component diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index b3316dc75..b0346c232 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -31,7 +31,7 @@ print " Attitude: %s" % vehicle.attitude print " Velocity: %s" % vehicle.velocity print " GPS: %s" % vehicle.gps_0 -print " Mount status: %s" % vehicle.mount_status +print " Gimbal status: %s" % vehicle.gimbal print " Battery: %s" % vehicle.battery print " EKF OK?: %s" % vehicle.ekf_ok print " Last Heartbeat: %s" % vehicle.last_heartbeat From 0121fb66a2b800b62219f5ecdf0f1d0adf720d17 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 14 Dec 2015 14:10:48 +1100 Subject: [PATCH 260/475] Add pointer to gimbal simulation docs --- docs/examples/vehicle_state.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index 4d9a1510e..b83ccc630 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -18,10 +18,12 @@ The example can be run as described in :doc:`running_examples` (which in turn as the vehicle and DroneKit have been set up as described in :ref:`get-started`). If you're using a simulated vehicle remember to :ref:`disable arming checks ` so -that the example can run. You can also -`add a virtual rangefinder `_ -(otherwise the :py:attr:`Vehicle.rangefinder ` attribute may return -values of ``None`` for the distance and voltage). +that the example can run. You can also: + +* `add a virtual rangefinder `_ + (otherwise the :py:attr:`Vehicle.rangefinder ` attribute may return values of ``None`` for the distance and voltage). +* `add a virtual gimbal `_ + (otherwise the :py:attr:`Vehicle.gimbal ` attribute may return values of ``None`` for the yaw, pitch and roll). In summary, after cloning the repository: From 44d880083e73756955f0bb6cd0441c603eca35cc Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 23 Dec 2015 16:12:10 +1100 Subject: [PATCH 261/475] Move topics into new folders (breaks index, will repair later) --- docs/{guide => about}/migrating.rst | 0 docs/{guide => develop}/companion-computers.rst | 0 docs/{guide => develop}/sitl_setup.rst | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename docs/{guide => about}/migrating.rst (100%) rename docs/{guide => develop}/companion-computers.rst (100%) rename docs/{guide => develop}/sitl_setup.rst (100%) diff --git a/docs/guide/migrating.rst b/docs/about/migrating.rst similarity index 100% rename from docs/guide/migrating.rst rename to docs/about/migrating.rst diff --git a/docs/guide/companion-computers.rst b/docs/develop/companion-computers.rst similarity index 100% rename from docs/guide/companion-computers.rst rename to docs/develop/companion-computers.rst diff --git a/docs/guide/sitl_setup.rst b/docs/develop/sitl_setup.rst similarity index 100% rename from docs/guide/sitl_setup.rst rename to docs/develop/sitl_setup.rst From e1db3934c3c9af4a8016bb9a4e60cc752616fa4a Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 23 Dec 2015 18:33:06 +1100 Subject: [PATCH 262/475] Migrate to new structure and fix up links. Omits best-practise guide --- docs/about/index.rst | 1 + docs/about/migrating.rst | 2 +- docs/contributing/developer_setup_linux.rst | 3 +- docs/contributing/developer_setup_windows.rst | 2 +- docs/develop/coding_standards.rst | 14 ++ docs/develop/index.rst | 23 +++ docs/develop/installation.rst | 35 ++++ docs/examples/channel_overrides.rst | 2 +- docs/examples/create_attribute.rst | 2 +- docs/examples/drone_delivery.rst | 2 +- docs/examples/flight_replay.rst | 2 +- docs/examples/follow_me.rst | 2 +- docs/examples/guided-set-speed-yaw-demo.rst | 4 +- docs/examples/mission_basic.rst | 2 +- docs/examples/mission_import_export.rst | 2 +- docs/examples/simple_goto.rst | 2 +- docs/examples/vehicle_state.rst | 2 +- docs/guide/connecting_vehicle.rst | 63 ++++++ docs/guide/getting_started.rst | 183 ------------------ docs/guide/index.rst | 9 +- docs/guide/quick_start.rst | 119 ++++++++++++ docs/guide/taking_off.rst | 19 +- docs/index.rst | 10 +- examples/simple_goto/simple_goto.py | 3 +- 24 files changed, 289 insertions(+), 219 deletions(-) create mode 100644 docs/develop/coding_standards.rst create mode 100644 docs/develop/index.rst create mode 100644 docs/develop/installation.rst create mode 100644 docs/guide/connecting_vehicle.rst delete mode 100644 docs/guide/getting_started.rst create mode 100644 docs/guide/quick_start.rst diff --git a/docs/about/index.rst b/docs/about/index.rst index cee9c6eb6..1d5866a3e 100644 --- a/docs/about/index.rst +++ b/docs/about/index.rst @@ -12,6 +12,7 @@ After reading, you will understand what the kit offers and the opportunities it overview release_notes + migrating license diff --git a/docs/about/migrating.rst b/docs/about/migrating.rst index 5cbfb367e..9654f9ce1 100644 --- a/docs/about/migrating.rst +++ b/docs/about/migrating.rst @@ -19,7 +19,7 @@ The sections below outline the main migration areas. Installation ============ -DKPY 2.0 is now installed from `pip` on all platforms - see :ref:`get-started` for more information. +DKPY 2.0 is now installed from `pip` on all platforms - see :ref:`installing_dronekit` for more information. Installation is generally simpler than on DK 1.x because there are far fewer dependencies (both MAVProxy and numpy are no longer needed). diff --git a/docs/contributing/developer_setup_linux.rst b/docs/contributing/developer_setup_linux.rst index 00ffeffce..6bf8a965c 100644 --- a/docs/contributing/developer_setup_linux.rst +++ b/docs/contributing/developer_setup_linux.rst @@ -5,7 +5,8 @@ Building DroneKit-Python on Linux =================================== The setup for *developing* DroneKit-Python on Linux is almost the same as for *using* -DroneKit-Python. We therefore recommend that you start by following the instructions in :ref:`Getting Started `. +DroneKit-Python. We therefore recommend that you start by following the instructions in +:ref:`installing_dronekit`. When you've got DroneKit and a vehicle (simulated or real) communicating, you can then build and install your own fork of DroneKit, as discussed below. diff --git a/docs/contributing/developer_setup_windows.rst b/docs/contributing/developer_setup_windows.rst index 494775d0c..b9d65ef25 100644 --- a/docs/contributing/developer_setup_windows.rst +++ b/docs/contributing/developer_setup_windows.rst @@ -11,7 +11,7 @@ Install DroneKit using WinPython command line ============================================= -First set up a command line DroneKit-Python installation using *WinPython*. This process is the same as described in :ref:`Getting Started `. +First set up a command line DroneKit-Python installation. We recommend *WinPython* or *ActivePython*, as discussed in :ref:`installing_dronekit`. diff --git a/docs/develop/coding_standards.rst b/docs/develop/coding_standards.rst new file mode 100644 index 000000000..36828a5c5 --- /dev/null +++ b/docs/develop/coding_standards.rst @@ -0,0 +1,14 @@ +.. _coding_standards: + +========================== +Coding Standards +========================== + +DroneKit-Python does not impose (or recommend) a particular set of coding standards +for third party code. + +Internally we run the `YAPF formatter `_ +on major releases and we expect contributors to copy the patterns used in similar +code within the existing code base. + + \ No newline at end of file diff --git a/docs/develop/index.rst b/docs/develop/index.rst new file mode 100644 index 000000000..159cb707c --- /dev/null +++ b/docs/develop/index.rst @@ -0,0 +1,23 @@ +======================== +Developing with DroneKit +======================== + +DroneKit-Python is primarily intended for use on Linux-based :doc:`companion-computers` that travel +on a vehicle and communicate with the autopilot via a serial port. It can also be used +on ground-based computers running Linux, Windows or Mac OSX (communicating using WiFi or a telemetry radio). + +During development you'll generally run it on a development computer, communicating with a +:doc:`simulated vehicle` running on the same machine (via a UDP connection). + +This section contains topics explaining how to develop with DroneKit-Python, +covering subjects like installation, setting up the target vehicle or simulator, best practices +and coding standards. + + +.. toctree:: + :maxdepth: 1 + + installation + companion-computers + Simulated Vehicle + coding_standards \ No newline at end of file diff --git a/docs/develop/installation.rst b/docs/develop/installation.rst new file mode 100644 index 000000000..d0e0810cb --- /dev/null +++ b/docs/develop/installation.rst @@ -0,0 +1,35 @@ +.. _installing_dronekit: + +=================== +Installing DroneKit +=================== + +DroneKit-Python can be installed on a Linux, Mac OSX, or Windows computer that +has *Python 2.7* and can install Python packages from the Internet. + +It is installed from **pip** on all platforms: + +.. code-block:: bash + + pip install dronekit + + +**Installation notes:** + +* Mac and Linux require you prefix the command with ``sudo``. +* On Linux you may need to first install **pip** and **python-dev**: + + .. code-block:: bash + + sudo apt-get install python-pip python-dev + +* :doc:`companion-computers` are likely to run on stripped down versions of Linux. Ensure + you use a variant that supports Python 2.7 and can install Python packages from the Internet. +* Windows does not come with Python by default, but there are + `many distributions available `_. + We have tested against: + + * `WinPython 2.7 64bit `_ (see + `these instructions for installation and registration `_). This is the most tested version. + * `ActiveState ActivePython 2.7 `_. +* Python 3 is not supported. diff --git a/docs/examples/channel_overrides.rst b/docs/examples/channel_overrides.rst index fda53187f..2b043225a 100644 --- a/docs/examples/channel_overrides.rst +++ b/docs/examples/channel_overrides.rst @@ -24,7 +24,7 @@ Running the example =================== The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle -and DroneKit have been set up as described in :ref:`get-started`). +and DroneKit have been set up as described in :ref:`installing_dronekit`). In summary, after cloning the repository: diff --git a/docs/examples/create_attribute.rst b/docs/examples/create_attribute.rst index b44480180..0fac3e234 100644 --- a/docs/examples/create_attribute.rst +++ b/docs/examples/create_attribute.rst @@ -31,7 +31,7 @@ Running the example =================== The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle -and DroneKit have been set up as described in :ref:`get-started`). +and DroneKit have been set up as described in :ref:`installing_dronekit`). In summary, after cloning the repository: diff --git a/docs/examples/drone_delivery.rst b/docs/examples/drone_delivery.rst index 2500f8375..0c4b01eeb 100644 --- a/docs/examples/drone_delivery.rst +++ b/docs/examples/drone_delivery.rst @@ -21,7 +21,7 @@ Running the example =================== The example can be run much as described in :doc:`running_examples` (which in turn assumes that the vehicle -and DroneKit have been set up as described in :ref:`get-started`). The main exception is that you need to +and DroneKit have been set up as described in :ref:`installing_dronekit`). The main exception is that you need to install the CherryPy dependencies and view the behaviour in a web browser. If you're using a simulated vehicle remember to :ref:`disable arming checks ` so diff --git a/docs/examples/flight_replay.rst b/docs/examples/flight_replay.rst index 5ce47375c..48fbd5e87 100644 --- a/docs/examples/flight_replay.rst +++ b/docs/examples/flight_replay.rst @@ -24,7 +24,7 @@ Running the example =================== The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle -and DroneKit have been set up as described in :ref:`get-started`). +and DroneKit have been set up as described in :ref:`installing_dronekit`). If you're using a simulated vehicle, remember to :ref:`disable arming checks ` so that the example can run. diff --git a/docs/examples/follow_me.rst b/docs/examples/follow_me.rst index 4f7e44d81..f51319a43 100644 --- a/docs/examples/follow_me.rst +++ b/docs/examples/follow_me.rst @@ -18,7 +18,7 @@ python language features and libraries (OpenCV, classes, lots of packages etc... Running the example =================== -DroneKit (for Linux) and the vehicle should be set up as described in :ref:`get-started`. +DroneKit (for Linux) and the vehicle should be set up as described in :ref:`installing_dronekit`. Once you've done that: diff --git a/docs/examples/guided-set-speed-yaw-demo.rst b/docs/examples/guided-set-speed-yaw-demo.rst index fd6db8a31..86fbc65f8 100644 --- a/docs/examples/guided-set-speed-yaw-demo.rst +++ b/docs/examples/guided-set-speed-yaw-demo.rst @@ -33,7 +33,7 @@ Running the example =================== The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle -and DroneKit have been set up as described in :ref:`get-started`). +and DroneKit have been set up as described in :ref:`installing_dronekit`). If you're using a simulated vehicle, remember to :ref:`disable arming checks ` so that the example can run. @@ -382,7 +382,7 @@ At time of writing, acceleration and yaw bits are ignored. Testbed settings ================ -This example has been tested on Windows against SITL running both natively and in a virtual machine (as described in :ref:`get-started`). +This example has been tested on Windows against SITL running both natively and in a virtual machine (as described in :ref:`installing_dronekit`). * DroneKit version: 2.0.0rc12 * ArduPilot version: 3.4.0. diff --git a/docs/examples/mission_basic.rst b/docs/examples/mission_basic.rst index 746c97f50..c7af9ba73 100644 --- a/docs/examples/mission_basic.rst +++ b/docs/examples/mission_basic.rst @@ -23,7 +23,7 @@ Running the example =================== The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle -and DroneKit have been set up as described in :ref:`get-started`). +and DroneKit have been set up as described in :ref:`installing_dronekit`). If you're using a simulated vehicle, remember to :ref:`disable arming checks ` so that the example can run. diff --git a/docs/examples/mission_import_export.rst b/docs/examples/mission_import_export.rst index cd00b68c7..20fe1919b 100644 --- a/docs/examples/mission_import_export.rst +++ b/docs/examples/mission_import_export.rst @@ -23,7 +23,7 @@ Running the example =================== The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle -and DroneKit have been set up as described in :ref:`get-started`). +and DroneKit have been set up as described in :ref:`installing_dronekit`). In summary, after cloning the repository: diff --git a/docs/examples/simple_goto.rst b/docs/examples/simple_goto.rst index 576f78c0b..89c2d221c 100644 --- a/docs/examples/simple_goto.rst +++ b/docs/examples/simple_goto.rst @@ -31,7 +31,7 @@ Running the example =================== The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle -and DroneKit have been set up as described in :ref:`get-started`). +and DroneKit have been set up as described in :ref:`installing_dronekit`). If you're using a simulated vehicle, remember to :ref:`disable arming checks ` so that the example can run. diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index b83ccc630..7448ac9ad 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -15,7 +15,7 @@ Running the example =================== The example can be run as described in :doc:`running_examples` (which in turn assumes that -the vehicle and DroneKit have been set up as described in :ref:`get-started`). +the vehicle and DroneKit have been set up as described in :ref:`installing_dronekit`). If you're using a simulated vehicle remember to :ref:`disable arming checks ` so that the example can run. You can also: diff --git a/docs/guide/connecting_vehicle.rst b/docs/guide/connecting_vehicle.rst new file mode 100644 index 000000000..9f2b588e1 --- /dev/null +++ b/docs/guide/connecting_vehicle.rst @@ -0,0 +1,63 @@ +.. _connecting_vehicle: +.. _get_started_connecting: + +======================= +Connecting to a Vehicle +======================= + +The connection to the vehicle (or multiple vehicles) is set up within the +DroneKit script. Scripts import and call the :py:func:`connect() ` +method. After connecting this returns a :py:class:`Vehicle ` +object from which you can get/set parameters and attributes, and control vehicle movement: + +.. code:: python + + from dronekit import connect + + # Connect to the Vehicle (in this case a UDP endpoint) + vehicle = connect('127.0.0.1:14550', wait_ready=True) + +The first parameter above specifies the target address (in this case the loopback +address for UDP port 14550). See :ref:`get_started_connect_string` for the strings to use for +other common vehicles. + +:py:func:`connect() ` also has arguments for setting the baud rate, whether ``connect()`` returns immediately or waits until vehicle parameters and attributes are populated (:py:func:`wait_ready=True `), +the length of the connection timeout, and/or to use a :ref:`custom vehicle class `. + + +.. _get_started_connect_string: + +Connection string options +========================= + +The table below shows *connection strings* you can use for some of the more common connection types: + +.. list-table:: + :widths: 10 10 + :header-rows: 1 + + * - Connection type + - Connection string + * - Linux computer connected to the vehicle via USB + - ``/dev/ttyUSB0`` + * - Linux computer connected to the vehicle via Serial port (RaspberryPi example) + - ``/dev/ttyAMA0`` (also set ``baud=57600``) + * - SITL connected to the vehicle via UDP + - ``127.0.0.1:14550`` + * - OSX computer connected to the vehicle via USB + - ``dev/cu.usbmodem1`` + * - Windows computer connected to the vehicle via USB (in this case on COM14) + - ``com14`` + * - Windows computer connected to the vehicle using a 3DR Telemetry Radio on COM14 + - ``com14`` (also set ``baud=57600``) + +.. tip:: + + The strings above are the same as are used when connecting the MAVProxy GCS. For other options see the + `MAVProxy documentation `_. + +.. note:: + + The default baud rate may not be appropriate for all connection types (this may be the cause + if you can connect via a GCS but not DroneKit). + diff --git a/docs/guide/getting_started.rst b/docs/guide/getting_started.rst deleted file mode 100644 index 8fc4bb45e..000000000 --- a/docs/guide/getting_started.rst +++ /dev/null @@ -1,183 +0,0 @@ -.. _get-started: - -=============== -Getting Started -=============== - -DroneKit-Python apps are typically run on Linux-based *companion computers* that travel -on the vehicle and communicate with the autopilot via a serial port. However, during development it is usually easier to -prototype apps on a standard Mac, Windows, or Linux computer using a *simulated* autopilot. - - -This topic explains how to set up and run DroneKit-Python on the different host operating systems -and then create and run a basic DroneKit app. - - - -Setting up the vehicle/autopilot -================================ - -For information on how to set up a vehicle (real and simulated) see: - -* :ref:`supported-companion-computers` for links to tested hardware/software configurations for a number of onboard Linux computers. -* :ref:`sitl_setup` for links explaining how to set up a simulated vehicle for Copter, Plane, or Rover. - - - -Installing DroneKit -=================== - -*DroneKit* can be installed on Linux, Windows and Mac OSX. - - -.. _getting_started_installing_dronekit_linux: - -Installing DroneKit on Linux ----------------------------- - -If you are using Ubuntu or Debian Linux you can get most of the *DroneKit* dependencies by running: - -.. code:: bash - - sudo apt-get install python-pip python-dev - - -The remaining dependencies are installed when you get DroneKit-Python from the public PyPi repository: - -.. code:: bash - - sudo pip install dronekit - - - -.. tip:: - - If you are planning to run *DroneKit* on a :ref:`companion computer `, make sure that the - computer runs a variant of Linux that support Python and can install Python packages from the internet. - - -Installing DroneKit on Mac OSX ------------------------------- - -Install DroneKit-Python and its dependencies from the public PyPi repository: - -.. code:: bash - - sudo pip install dronekit - - - -.. _get_started_install_dk_windows: - -Installing DroneKit on Windows ------------------------------- - -Set up a command line DroneKit-Python installation using *WinPython* (this Python distribution already includes most of the needed dependencies). - - -#. Download and run the correct `WinPython installer `_ (**v2.7**) for your platform (win32 vs win64). - - * Run the installer as an administrator (**Right-click** on file, select **Run as Administrator**). - * When prompted for the destination location, specify **C:\\Program Files (x86)** - (the default location is under the **Downloads** folder). - -#. Register the Python that came from *WinPython* as the preferred interpreter for your machine: - - Open the folder where you installed WinPython, run *WinPython Control Panel* and choose **Advanced/Register Distribution**. - - .. image:: http://dev.ardupilot.com/wp-content/uploads/sites/6/2014/03/Screenshot-from-2014-09-03-083816.png - -#. Install DroneKit-Python and its remaining dependencies from the public PyPi repository: - - Open the *WinPython Command Prompt* and run the following command: - - .. code:: bash - - pip install dronekit - - - -.. _get_started_connect_string: - -.. _get_started_connecting: - -Connecting to a Vehicle -======================= - -The connection to the vehicle is set up within the DroneKit script. Scripts import and call the :py:func:`connect()` method. -After connecting this returns a :py:class:`Vehicle ` object from which you can get/set parameters -and attributes, and control vehicle movement. - -.. code:: python - - from dronekit import connect - - # Connect to UDP endpoint. - vehicle = connect('127.0.0.1:14550', wait_ready=True) - -.. note:: - - Calling ``connect()`` with ``wait_ready=True`` (as shown above) ensures that the method will not return until - :py:attr:`Vehicle.parameters ` is fully populated with values from the vehicle. - Vehicle *attributes* are populated in parallel but are not guaranteed to have values when ``connect()`` completes - (an attribute will have value ``None`` if a corresponding MAVLink message has not been received - for example, - if the attribute is not supported by the vehicle). - -The example above connects to the udp address ``127.0.0.1:14550``. The table below shows addresses to use some of -the more common connection types: - - - -.. list-table:: Connection string options - :widths: 10 10 - :header-rows: 1 - - * - Connection type - - Connection string - * - Linux computer connected to the vehicle via USB - - ``/dev/ttyUSB0`` - * - Linux computer connected to the vehicle via Serial port (RaspberryPi example) - - ``/dev/ttyAMA0`` (also set ``baud=57600``) - * - SITL connected to the vehicle via UDP - - ``127.0.0.1:14550`` - * - OSX computer connected to the vehicle via USB - - ``dev/cu.usbmodem1`` - * - Windows computer connected to the vehicle via USB (in this case on COM14) - - ``com14`` - * - Windows computer connected to the vehicle using a 3DR Telemetry Radio on COM14 - - ``com14`` (also set ``baud=57600``) - -.. note:: - The default baud rate may not be appropriate for all connection types (check this - if you can connect via a GCS but not DroneKit). - You can specify a different rate using the :py:func:`baud ` - parameter when connecting. For example: ``vehicle=connect('com14', baud=57600)``. - -.. tip:: - - The strings above are the same as you would use if connecting with MAVProxy. For other options see the - `MAVProxy documentation `_. - - -You can start this simple script in the same way you would start any other standalone Python script. - -.. code-block:: bash - - python your_dronekit_script.py - - - -.. todo:: Connect method here needs to link to the function, but it isn't exported yet. Fix that once the API tidied. - - - - -.. _getting-started-running_examples: - -Running an app/example -====================== - -This SDK has :ref:`numerous examples `. We recommend you start with :ref:`example-vehicle-state`, -which reads and writes :ref:`vehicle state and parameter ` information. - -For general information on running the examples (and other apps) see :ref:`running_examples_top`. diff --git a/docs/guide/index.rst b/docs/guide/index.rst index d63671773..c6d10c7b7 100644 --- a/docs/guide/index.rst +++ b/docs/guide/index.rst @@ -2,16 +2,13 @@ Guide ===== -The guide contains how-to documentation for using the DroneKit-Python API. These show how to :ref:`set up DroneKit` and use the API. Additional guide material can be found in the :ref:`example-toc`. - +The guide contains how-to documentation for using the DroneKit-Python API. +Additional guide material can be found in the :ref:`example-toc`. .. toctree:: :maxdepth: 1 - migrating - getting_started - companion-computers - Simulated Vehicle + connecting_vehicle vehicle_state_and_parameters taking_off copter/guided_mode diff --git a/docs/guide/quick_start.rst b/docs/guide/quick_start.rst new file mode 100644 index 000000000..2e44fbfd8 --- /dev/null +++ b/docs/guide/quick_start.rst @@ -0,0 +1,119 @@ +.. _quick_start_top: + +=========== +Quick Start +=========== + +This topic shows how to quickly install a DroneKit-Python +*development environment* and run a simple example to get +vehicle attributes from a *simulated* Copter. + + +Installation +============ + +DroneKit-Python and the *dronekit-sitl simulator* are installed +from **pip** on all platforms: + +.. code-block:: bash + + pip install dronekit + pip install dronekit-sitl + +Mac and Linux require you prefix the command with ``sudo``. +On Linux you will first need to install **pip** and **python-dev**: + +.. code-block:: bash + + sudo apt-get install python-pip python-dev + + +See :doc:`installation` and `dronekit-sitl `_ +for more detailed installation instructions. + + +Basic "Hello Drone" +=================== + +The script below first launches the simulator. It then +imports and calls the :py:func:`connect() ` method, +specifying the simulator's connection string (``tcp:127.0.0.1:5760``). +The method returns a :py:class:`Vehicle ` object that +we then use to query the attributes. + +.. code:: python + + print "Start simulator (SITL)" + from dronekit_sitl import SITL + sitl = SITL() + sitl.download('copter', '3.3', verbose=True) + sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] + sitl.launch(sitl_args, await_ready=True, restart=True) + + # Import DroneKit-Python + from dronekit import connect, VehicleMode + import time + + # Connect to the Vehicle. + print "Connecting to vehicle on: 'tcp:127.0.0.1:5760'" + vehicle = connect('tcp:127.0.0.1:5760', wait_ready=True) + + # Get some vehicle attributes (state) + print "Get some vehicle attribute values:" + print " GPS: %s" % vehicle.gps_0 + print " Battery: %s" % vehicle.battery + print " Last Heartbeat: %s" % vehicle.last_heartbeat + print " Is Armable?: %s" % vehicle.is_armable + print " System status: %s" % vehicle.system_status.state + print " Mode: %s" % vehicle.mode.name # settable + + # Close vehicle object before exiting script + vehicle.close() + + # Shut down simulator + sitl.stop() + print("Completed") + + +Copy the text above into a new text file (**hello.py**) and run it in the same way +as you would any other standalone Python script. + +.. code-block:: bash + + python hello.py + +You should see the following output from the simulated vehicle: + +.. code-block:: bash + + Start simulator (SITL) + Downloading SITL from http://dronekit-assets.s3.amazonaws.com/sitl/copter/sitl-win-copter-3.3.tar.gz + Extracted. + Connecting to vehicle on: 'tcp:127.0.0.1:5760' + >>> APM:Copter V3.3 (d6053245) + >>> Frame: QUAD + >>> Calibrating barometer + >>> Initialising APM... + >>> barometer calibration complete + >>> GROUND START + Get some vehicle attribute values: + GPS: GPSInfo:fix=3,num_sat=10 + Battery: Battery:voltage=12.587,current=0.0,level=100 + Last Heartbeat: 0.713999986649 + Is Armable?: False + System status: STANDBY + Mode: STABILIZE + Completed + +That's it- you've run your first DroneKit-Python script. + +Next Steps +========== + +* Learn a more about :doc:`../develop/index`. + This covers development best practices and coding standards, + and has more information about installation, working with a simulator + and setting up a companion computer. +* Read through our step by step :doc:`index` to learn how to connect to your + vehicle, takeoff, fly, and much more. +* Check out our :doc:`../examples/index`. diff --git a/docs/guide/taking_off.rst b/docs/guide/taking_off.rst index 8763706b7..0d9fc873f 100644 --- a/docs/guide/taking_off.rst +++ b/docs/guide/taking_off.rst @@ -4,9 +4,10 @@ Taking Off ========== -This article explains how to get your *Copter* to take off. At high level, the steps are: check that the vehicle -is able to arm (can pass pre-arm checks), set the mode to ``GUIDED``, arm the vehicle, -and then call :py:func:`Vehicle.simple_takeoff() `. +This article explains how to get your *Copter* to take off. + +At high level, the steps are: check that the vehicle is *able* to arm, set the mode to ``GUIDED``, +command the vehicle to arm, takeoff and block until we reach the desired altitude. .. todo:: @@ -26,8 +27,8 @@ and then call :py:func:`Vehicle.simple_takeoff() `_ message. - By contrast, Plane apps take off using the ``MAV_CMD_NAV_TAKEOFF`` command in a mission. Plane should first arm and then change to - ``AUTO`` mode to start the mission. + By contrast, Plane apps take off using the ``MAV_CMD_NAV_TAKEOFF`` command in a mission. + Plane should first arm and then change to ``AUTO`` mode to start the mission. The code below shows a function to arm a Copter, take off, and fly to a specified altitude. This is taken from :ref:`example_simple_goto`. @@ -42,7 +43,7 @@ The code below shows a function to arm a Copter, take off, and fly to a specifie """ print "Basic pre-arm checks" - # Don't let the user try to arm until autopilot is ready + # Don't try to arm until autopilot is ready while not vehicle.is_armable: print " Waiting for vehicle to initialise..." time.sleep(1) @@ -52,6 +53,7 @@ The code below shows a function to arm a Copter, take off, and fly to a specifie vehicle.mode = VehicleMode("GUIDED") vehicle.armed = True + # Confirm vehicle armed before attempting to take off while not vehicle.armed: print " Waiting for arming..." time.sleep(1) @@ -78,9 +80,8 @@ The function first performs some pre-arm checks. Arming turns on the vehicle's motors in preparation for flight. The flight controller will not arm until the vehicle has passed a series of pre-arm checks to ensure that it is safe to fly. -DroneKit-Python can't check every possible symptom that might prevent arming, but we can confirm that the -vehicle has booted, EKF is ready, and it has a GPS lock. These checks are encapsulated in the -:py:func:`Vehicle.is_armable ` attribute: +These checks are encapsulated by the :py:func:`Vehicle.is_armable ` +attribute, which is ``true`` when the vehicle has booted, EKF is ready, and the vehicle has GPS lock. .. code-block:: python diff --git a/docs/index.rst b/docs/index.rst index b86c08ed1..fe60ddf22 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,15 +1,11 @@ -.. DroneApi documentation master file, created by - sphinx-quickstart on Wed Mar 19 15:28:50 2014. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - =========================================== Welcome to DroneKit-Python's documentation! =========================================== DroneKit-Python 2.x helps you create powerful apps for UAVs. These apps run on a UAV's :ref:`Companion Computer `, and augment the autopilot by performing tasks that are both computationally intensive and require a low-latency link (e.g. computer vision). -This documentation provides everything you need to :doc:`get started ` with DroneKit-Python, including an :doc:`overview ` of the API, guide material, a number of demos and examples, and :doc:`API Reference `. +This documentation provides everything you need to get started with DroneKit-Python, including an :doc:`overview ` of the API, quick start, guide material, a number of demos and examples, +and :doc:`API Reference `. .. tip:: @@ -25,6 +21,8 @@ Contents: :maxdepth: 2 Introduction + guide/quick_start + Developing guide/index examples/index contributing/index diff --git a/examples/simple_goto/simple_goto.py b/examples/simple_goto/simple_goto.py index 4f67f5373..231616606 100644 --- a/examples/simple_goto/simple_goto.py +++ b/examples/simple_goto/simple_goto.py @@ -29,7 +29,7 @@ def arm_and_takeoff(aTargetAltitude): """ print "Basic pre-arm checks" - # Don't let the user try to arm until autopilot is ready + # Don't try to arm until autopilot is ready while not vehicle.is_armable: print " Waiting for vehicle to initialise..." time.sleep(1) @@ -40,6 +40,7 @@ def arm_and_takeoff(aTargetAltitude): vehicle.mode = VehicleMode("GUIDED") vehicle.armed = True + # Confirm vehicle armed before attempting to take off while not vehicle.armed: print " Waiting for arming..." time.sleep(1) From c7b53083eb19b3e7740b0ae0b8adcb7f61d548a2 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 29 Dec 2015 18:14:44 +1100 Subject: [PATCH 263/475] Add Best Practice Section --- .../MissionPlanner_ConnectPort.png | Bin docs/develop/best_practice.rst | 246 ++++++++++++++++++ docs/develop/index.rst | 1 + docs/develop/installation.rst | 7 +- 4 files changed, 253 insertions(+), 1 deletion(-) rename docs/{guide => develop}/MissionPlanner_ConnectPort.png (100%) create mode 100644 docs/develop/best_practice.rst diff --git a/docs/guide/MissionPlanner_ConnectPort.png b/docs/develop/MissionPlanner_ConnectPort.png similarity index 100% rename from docs/guide/MissionPlanner_ConnectPort.png rename to docs/develop/MissionPlanner_ConnectPort.png diff --git a/docs/develop/best_practice.rst b/docs/develop/best_practice.rst new file mode 100644 index 000000000..f2bcb750b --- /dev/null +++ b/docs/develop/best_practice.rst @@ -0,0 +1,246 @@ +.. _best_practices: + +============== +Best Practices +============== + +This guide provides a broad overview of how to use the API, its main programming idioms +and best practices. More detail information is linked from each section. + + +General considerations +====================== + +DroneKit-Python communicates with vehicle autopilots using the MAVLink protocol, +which defines how commands, telemetry and vehicle settings/parameters +are sent between vehicles, companion computers, ground stations and other systems on +a MAVLink network. + +Some general considerations from using this protocol are: + +* Messages and message acknowledgments are not guaranteed to arrive (the protocol is not "lossless"). +* Commands may be silently ignored by the Autopilot if it is not in a state where it can + safely act on them. +* Command acknowledgment and completion messages are not sent in most cases + (and if sent, may not arrive). +* Commands may be interrupted before completion. +* Autopilots may choose to interpret the protocol in slightly different ways. +* Commands can arrive at the autopilot from multiple sources. + +Developers should code defensively. Where possible: + +* Check that a vehicle is in a state to obey a command (for example, + poll on :py:func:`Vehicle.is_armable ` + before trying to arm the vehicle). +* Don't assume that a command has succeeded until the changed behaviour is observed. + In particular we recommend a launch sequence where you check that the mode and arming + have succeeded before attempting to take off. +* Monitor for state changes and react accordingly. + For example, if the user changes the mode from ``GUIDED`` your script should + stop sending commands. +* Verify that your script can run inside the normal latency limits for message passing + from the vehicle and tune any monitoring appropriately. + + +Connecting +========== + +In most cases you'll use the normal way to :ref:`connect to a vehicle `, +setting ``wait_ready=True`` to ensure that the vehicle is already populated with attributes +when the :py:func:`connect() ` returns: + +.. code:: python + + from dronekit import connect + + # Connect to the Vehicle (in this case a UDP endpoint) + vehicle = connect('REPLACE_connection_string_for_your_vehicle', wait_ready=True) + +The ``connect()`` call will sometimes fail with an exception. +Additional information about an exception can be obtained by +running the connect within a ``try-catch`` block as shown: + +.. code-block:: python + + import dronekit + import socket + import exceptions + + + try: + dronekit.connect('REPLACE_connection_string_for_your_vehicle', heartbeat_timeout=15) + + # Bad TCP connection + except socket.error: + print 'No server exists!' + except dronekit.APIException: + print 'Timeout!' + + # Bad TTY connection + except exceptions.OSError as e: + print 'No serial exists!' + except dronekit.APIException: + print 'Timeout!' + + # Other error + except: + print 'Some other error!' + +.. tip:: + + The default ``heartbeat_timeout`` on connection is 30 sections. Usually a connection will + succeed quite quickly, so you may wish to reduce this in the ``connect()`` method as shown in the + code snippet above. + +If a connection succeeds from a ground station, but not from DroneKit-Python it may be that your baud +rate is incorrect for your hardware. This rate can also be set in the ``connect()`` method. + + +Launch sequence +=============== + +Generally you should use the standard launch sequence described in :doc:`../guide/taking_off`: + +* Poll on :py:func:`Vehicle.is_armable ` + until the vehicle is ready to arm. +* Set the :py:attr:`Vehicle.mode ` to ``GUIDED`` +* Set :py:attr:`Vehicle.armed ` to ``True`` and + poll on the same attribute until the vehicle is armed. +* Call :py:func:`Vehicle.simple_takeoff ` + with a target altitude. +* Poll on the altitude and allow the code to continue only when it is reached. + +The approach ensures that commands are only sent to the vehicle when it is able +to act on them (e.g. we know :py:func:`Vehicle.is_armable ` +is ``True`` before trying to arm, we know +:py:attr:`Vehicle.armed ` is ``True`` before we take off). +It also makes debugging takeoff problems a lot easier. + + +Movement commands +================= + +DroneKit-Python provides :py:func:`Vehicle.simple_goto ` for moving to a specific position (at a defined speed). It is also possible to control movement by sending commands to specify the vehicle's :ref:`velocity components `. + +.. note:: + + As with :py:func:`Vehicle.simple_takeoff `, movement + commands are asynchronous, and will be interrupted if another command arrives + before the vehicle reaches its target. Calling code should block and wait (or + check that the operation is complete) before preceding to the next command. + +For more information see: :ref:`guided_mode_copter`. + + +Vehicle information +=================== + +Vehicle state information is exposed through vehicle *attributes* which can be read and observed (and in some cases written) +and vehicle settings which can be read, written, iterated and observed using *parameters* (a special attribute). All the attributes are documented in :doc:`../guide/vehicle_state_and_parameters`. + +Attributes are populated by MAVLink messages from the vehicle. +Information read from an attribute may not precisely reflect the actual value on the vehicle. Commands sent +to the vehicle may not arrive, or may be ignored by the autopilot. + +If low-latency is critical, we recommend you verify that the update rate is achievable and +perhaps modify script behaviour if :py:attr:`Vehicle.last_heartbeat ` falls outside +a useful range. + +When setting attributes, poll their values to confirm that they have changed. This applies, in particular, +to :py:attr:`Vehicle.armed ` and :py:attr:`Vehicle.mode `. + + + +Missions and waypoints +====================== + +DroneKit-Python can also :ref:`create and modify autonomous missions `. + +While it is possible to construct DroneKit-Python apps by dynamically constructing missions "on the fly", we recommend you use guided mode for Copter apps. This generally results in a better experience. + +.. tip:: + + If a mission command is not available in guided mode, + it can be useful to switch to a mission and call it, then change + back to normal guided mode operation. + + +Monitor and react to state changes +================================== + +Almost all attributes can be observed - see :ref:`vehicle_state_observe_attributes` for more information. + +Exactly what state information you observe, and how you react to it, depends on your particular script: + +* Most standalone apps should monitor the :py:func:`Vehicle.mode ` and + stop sending commands if the mode changes unexpectedly (this usually indicates + that the user has taken control of the vehicle). +* Apps might monitor :py:func:`Vehicle.last_heartbeat ` + and could attempt to reconnect if the value gets too high. +* Apps could monitor :py:func:`Vehicle.system_status ` + for ``CRITICAL`` or ``EMERGENCY`` in order to implement specific emergency handling. + + +Sleep the script when not needed +================================ + +Sleeping your script appropriately can reduce the memory overhead. + +For example, at low speeds you might only need to check whether you've reached a target every few seconds. +Using ``time.sleep(2)`` between checks will be more efficient than checking more often. + + +Exiting a script +================ + +Scripts should call :py:func:`Vehicle.close() ` +before exiting to ensure that all messages have flushed before the script completes: + +.. code:: python + + # About to exit script + vehicle.close() + + +Subclass Vehicle +===================================== + +If you need to use functionality that is specific to particular hardware, we +recommend you subclass :py:class:`Vehicle ` and pass this new class into +:py:func:`connect() `. + +:doc:`../examples/create_attribute` shows how you can do this. + + + + +Debugging +========= + +DroneKit-Python apps are ordinary standalone Python scripts, and can be :doc:`debugged using standard Python methods <../guide/debugging>` (including the debugger/IDE of your choice). + + +Launching scripts +================= + +Scripts are run from an ordinary Python command prompt. For example: + +.. code:: bash + + python some_python_script.py [arguments] + +Command line arguments are passed into the script as ``sys.argv`` variables (the normal) +and you can use these directly or via an argument parser (e.g. +`argparse `_). + + +Current script directory +======================== + +You can use normal Python methods for getting file system information: + +.. code-block:: python + + import os.path + full_directory_path_of_current_script = os.path.dirname(os.path.abspath(__file__)) + diff --git a/docs/develop/index.rst b/docs/develop/index.rst index 159cb707c..250992942 100644 --- a/docs/develop/index.rst +++ b/docs/develop/index.rst @@ -20,4 +20,5 @@ and coding standards. installation companion-computers Simulated Vehicle + best_practice coding_standards \ No newline at end of file diff --git a/docs/develop/installation.rst b/docs/develop/installation.rst index d0e0810cb..6fb6caba9 100644 --- a/docs/develop/installation.rst +++ b/docs/develop/installation.rst @@ -16,7 +16,12 @@ It is installed from **pip** on all platforms: **Installation notes:** -* Mac and Linux require you prefix the command with ``sudo``. +* Mac and Linux require you prefix the command with ``sudo``. + + .. code-block:: bash + + sudo pip install dronekit + * On Linux you may need to first install **pip** and **python-dev**: .. code-block:: bash From a2fa00961a2c610f4df9fce0275b416f0c1045d5 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 29 Dec 2015 18:26:57 +1100 Subject: [PATCH 264/475] Improve the Connecting topic --- docs/guide/connecting_vehicle.rst | 34 +++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/docs/guide/connecting_vehicle.rst b/docs/guide/connecting_vehicle.rst index 9f2b588e1..7d9363fb1 100644 --- a/docs/guide/connecting_vehicle.rst +++ b/docs/guide/connecting_vehicle.rst @@ -8,23 +8,33 @@ Connecting to a Vehicle The connection to the vehicle (or multiple vehicles) is set up within the DroneKit script. Scripts import and call the :py:func:`connect() ` method. After connecting this returns a :py:class:`Vehicle ` -object from which you can get/set parameters and attributes, and control vehicle movement: +object from which you can get/set parameters and attributes, and control vehicle movement. -.. code:: python +The most common way to call :py:func:`connect() ` is shown below: + +.. code-block:: python from dronekit import connect # Connect to the Vehicle (in this case a UDP endpoint) vehicle = connect('127.0.0.1:14550', wait_ready=True) -The first parameter above specifies the target address (in this case the loopback +The first parameter specifies the target address (in this case the loopback address for UDP port 14550). See :ref:`get_started_connect_string` for the strings to use for -other common vehicles. +other common vehicles. + +The second parameter (``wait_ready``) is used to determine whether ``connect()`` returns immediately +on connection or if it waits until *some* vehicle parameters and attributes are populated. In most cases you +should use ``wait_ready=True`` to wait on the default set of parameters. + +:py:func:`connect() ` also has arguments for setting the baud rate, +the length of the connection timeout, and/or to use +a :ref:`custom vehicle class `. -:py:func:`connect() ` also has arguments for setting the baud rate, whether ``connect()`` returns immediately or waits until vehicle parameters and attributes are populated (:py:func:`wait_ready=True `), -the length of the connection timeout, and/or to use a :ref:`custom vehicle class `. +There is more documentation on all of the parameters in the :py:func:`API Reference `. +.. _connection_string_options: .. _get_started_connect_string: Connection string options @@ -61,3 +71,15 @@ The table below shows *connection strings* you can use for some of the more comm The default baud rate may not be appropriate for all connection types (this may be the cause if you can connect via a GCS but not DroneKit). + +Connecting to multiple vehicles +=============================== + +You can control multiple vehicles from within a single script by calling +:py:func:`connect() ` for each vehicle +with the appropriate :ref:`connection strings `. + +The returned :py:class:`Vehicle ` objects are independent of +each other and can be separately used to control their respective +vehicle. + From 0850f92169a03fc5052e5d1c596b52d2c7b146ca Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 30 Dec 2015 08:36:00 +1100 Subject: [PATCH 265/475] Fix link typo in quickstart --- docs/guide/quick_start.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/quick_start.rst b/docs/guide/quick_start.rst index 2e44fbfd8..a0b587198 100644 --- a/docs/guide/quick_start.rst +++ b/docs/guide/quick_start.rst @@ -28,7 +28,7 @@ On Linux you will first need to install **pip** and **python-dev**: sudo apt-get install python-pip python-dev -See :doc:`installation` and `dronekit-sitl `_ +See :doc:`../develop/installation` and `dronekit-sitl `_ for more detailed installation instructions. From 59dea1edc6b2ea9f019c7f357c27f00ce2fec9bf Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 30 Dec 2015 18:17:38 +1100 Subject: [PATCH 266/475] Update instructions to use DK-SITL --- docs/develop/sitl_setup.rst | 169 +++++++++++++++++++++--------------- 1 file changed, 98 insertions(+), 71 deletions(-) diff --git a/docs/develop/sitl_setup.rst b/docs/develop/sitl_setup.rst index a83e4bd5f..73d6b74be 100644 --- a/docs/develop/sitl_setup.rst +++ b/docs/develop/sitl_setup.rst @@ -4,103 +4,124 @@ Setting up a Simulated Vehicle (SITL) ===================================== -The `SITL (software in the loop) `_ +The `SITL (Software In The Loop) `_ simulator allows you to create and test DroneKit-Python apps without a real vehicle (and from the comfort of -your own developer desktop!) +your own developer desktop!). -SITL runs natively on Linux and Windows, or within a virtual machine on Mac OSX, Linux or Windows. It can be +SITL can run natively on Linux, Mac and Windows, or within a virtual machine. It can be installed on the same computer as DroneKit, or on another computer on the same network. -The sections below explain how set up SITL for the different operating systems, -and how you can set up SITL to connect to Mission Planner and DroneKit at the same time. +The sections below explain how install and run SITL, and how to connect to DroneKit-Python and Ground +Stations at the same time. -Setting up SITL on Linux -======================== -Build and install SITL on Linux using the instructions in: -`Setting up SITL on Linux `_ (ArduPilot wiki) +DroneKit-SITL +============= +DroneKit-SITL is the simplest, fastest and easiest way to run SITL on Windows, Linux, or MAC OSX. +It is installed from Python's *pip* tool on all platforms, and works by downloading and running pre-built +vehicle binaries that are appropriate for the host operating system. -Setting up SITL on Windows -========================== +This section provides an overview of how to install and use DroneKit-SITL. For more information, see +the `project on Github `_. -Build and install SITL on Windows using the instructions in: -`Setting up SITL on Windows `_ -(ArduPilot wiki) +.. note:: + DroneKit-SITL is still relatively experimental. There are only a few pre-built vehicles and + they have not been as well tested as the native builds. + Please report any issues on `Github here `_. -.. _vagrant-sitl-from-full-image: +Installation +------------ -Set up SITL using Vagrant (MacOS) -================================= +The tool is installed (or updated) on all platforms using the command: -This section shows how to bring up a pre-built SITL instance hosted in a `Vagrant `_ -virtual machine. This approach should be used if you need to run SITL on MacOS. It can also be used for Windows -and Linux (though we recommend the native installations linked above). +.. code-block:: bash -.. warning:: + pip install dronekit-sitl -UI - The Vagrant virtual machine is "headless" (has no UI) and so SITL cannot display the MAVProxy map and console. - You can still see and send messages in the SITL Command Prompt. - +Running SITL +------------ -#. Get the software for hosting the Simulator onto your computer (Windows, OS-X and Linux are supported): +To run the latest version of Copter for which we have binaries (downloading the binaries if needed), you can simply call: - * `Download and install VirtualBox `_. - * `Download and install Vagrant `_. +.. code-block:: bash -#. Install SSH (Windows only - SSH is present by default on Linux/Mac OSX) + dronekit-sitl copter + +SITL will then start and wait for TCP connections on ``127.0.0.1:5760``. + +You can specify a particular vehicle and version, and also parameters like the home location, +the vehicle model type (e.g. "quad"), etc. For example: - * Download and install `Git for Windows `_ (or another client that comes with SSH). - After installing you can locate the file using the command ``C:\where ssh`` (normally it is installed to **C:\Program Files (x86)\Git\bin\ssh.exe** - * Add the ssh.exe location to the *Path* (**System Properties | Advanced tab | Environment Variables | Path**) +.. code-block:: bash -#. Create a new directory where you will run *Vagrant*, and open a command prompt/terminal in it: + dronekit-sitl plane-3.3.0 --home=-35.363261,149.165230,584,353 + +There are a number of other useful arguments: -#. Enter the following commands to fetch a *Vagrantfile* for the pre-built SITL image: +.. code-block:: bash - .. code:: bash + dronekit-sitl -h #List all parameters to dronekit-sitl. + dronekit-sitl copter -h #List additional parameters for the specified vehicle (in this case "copter"). + dronekit-sitl --list #List all available vehicles. + dronekit-sitl --reset #Delete all downloaded vehicle binaries. + dronekit-sitl ./path [args...] #Start SITL instance at target file location. - vagrant init 3drobotics/ardupilot-sitl -#. Launch the new image. This takes a long time the *first time* it is run while it downloads the image from the Internet. +.. note:: - .. code:: bash + DroneKit-SITL also `exposes a Python API `_, which you can use to start simulation from within your scripts. This is particularly useful for test code! + - vagrant up +.. _connecting_dronekit_sitl: -#. SSH into the vagrant instance, and start a vehicle: +Connecting to (DroneKit-) SITL +------------------------------ - .. code:: bash +SITL waits for TCP connections on ``127.0.0.1:5760``. DroneKit-Python scripts running on the same +computer can connect to the simulation using the connection string as shown: - vagrant ssh - ./sitl.sh - - When prompted, enter your desired vehicle (e.g. "copter") to build/start SITL. - Once complete, you will see a MAVProxy prompt displaying periodic vehicle-status updates: +.. code-block:: python - .. code:: bash + vehicle = connect('tcp:127.0.0.1:5760', wait_ready=True) - Ready to FLY ublox Received 454 parameters - fence breach - APM: PreArm: RC not calibrated - ... +If you need to connect to DroneKit-Python and a ground station at the same time you will need to +`install MAVProxy `_ +for your system. -.. _disable-arming-checks: +Then in a second terminal you spawn an instance of *MAVProxy* to forward messages from +TCP ``127.0.0.1:5760`` to UDP ports ``127.0.0.1:14550`` and ``127.0.0.1:14551`` (this is what **sim_vehicle.sh** does +if you build SITL from source): -#. Load a default set of parameters and disable the arming check: +.. code-block:: bash - .. code:: bash - - STABILIZE>param load ../Tools/autotest/copter_params.parm - STABILIZE>param set ARMING_CHECK 0 + mavproxy.py --master tcp:127.0.0.1:5760 --sitl 127.0.0.1:5501 --out 127.0.0.1:14550 --out 127.0.0.1:14551 - .. note:: - - SITL simulates (by default) a vehicle that may not pass the arming check. This change makes the simulated - vehicle more forgiving, which allows the examples to arm and run. - - You should never disable the arming check in a script or on a real vehicle. +You can then connect to a ground station using one UDP address, and DroneKit-Python using the other. +For example: + +.. code-block:: python + + vehicle = connect('127.0.0.1:14550', wait_ready=True) + + + +Building SITL from source +========================= + +You can natively build SITL from source on Linux, Windows and Mac OS X, +or from within a Vagrant Linux virtual environment. + +Building from source is useful if you want to need to test the latest changes (or any use +a version for which DroneKit-SITL does not have pre-built binaries). +It can also be useful if you have problems getting DroneKit-SITL to work. + +The following topics from the ArduPilot wiki explain how: + +* `Setting up SITL on Linux `_ +* `Setting up SITL on Windows `_ +* `Setting up SITL using Vagrant `_ .. _viewing_uav_on_map: @@ -108,19 +129,25 @@ and Linux (though we recommend the native installations linked above). Connecting an additional Ground Station ======================================= -This section explains how you can connect multiple ground stations to a running SITL instance in addition to your DroneKit MAVProxy link. +You can connect a ground station to an unused port to which messages +are being forwarded. You can forward messages to additional ports +when you start *MAVProxy* using the using ``-out`` +parameter (as shown :ref:`above `). -To do this you first need to get SITL to output to an additional UDP port of your computer: +Alternatively, once *MAVProxy* is started you can add new output ports in the *MAVProxy* console using: ``output add``: + +.. code:: bash + + output add 127.0.0.1:14552 + +.. note:: + + Instead of the loopback address you can also specify the network IP address of your computer + (On Windows you can get this by running *ipconfig* in the *Windows Command Prompt*). -* Find the network IP address of your computer (On Windows you can get this by running *ipconfig* in the *Windows Command Prompt*). -* In the *SITL Command Prompt*, add the IP address of the GCS computer (e.g. 192.168.2.10) and an unused port (e.g. 145502) as an output: - - .. code:: bash - - output add 192.168.2.10:14552 Then connect Mission Planner to this UDP port: - + * `Download and install Mission Planner `_ * Ensure the selection list at the top right of the Mission Planner screen says *UDP* and then select the **Connect** button next to it. When prompted, enter the port number (in this case 14552). From 9670a7158cb0b46a06a65dd1b0ccc9911395ebf2 Mon Sep 17 00:00:00 2001 From: Ramon Roche Date: Thu, 28 Jan 2016 10:17:04 -0800 Subject: [PATCH 267/475] small typo fix on quick-start guide --- docs/guide/quick_start.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/quick_start.rst b/docs/guide/quick_start.rst index a0b587198..b3567b358 100644 --- a/docs/guide/quick_start.rst +++ b/docs/guide/quick_start.rst @@ -110,7 +110,7 @@ That's it- you've run your first DroneKit-Python script. Next Steps ========== -* Learn a more about :doc:`../develop/index`. +* Learn more about :doc:`../develop/index`. This covers development best practices and coding standards, and has more information about installation, working with a simulator and setting up a companion computer. From f31bac89abf2cf5a2a84935a49204a231ab146a2 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 1 Feb 2016 16:57:00 +1100 Subject: [PATCH 268/475] Update the readme for ask community to share their cool uses of DK --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b4bc8eff9..d93fc20cd 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,8 @@ The [DroneKit Forums](http://discuss.dronekit.io) are the best place to ask for We'd love your [feedback and suggestions](https://github.com/dronekit/dronekit-python/issues) about this API and are eager to evolve it to meet your needs, please feel free to create an issue to report bugs or feature requests. +If you've created some awesome software that uses this project, [let us know on the forums here](https://discuss.dronekit.io/t/notable-projects-using-dronekit/230)! + If you want to contribute, see our [Contributing](http://python.dronekit.io/contributing/index.html) guidelines, we welcome all types of contributions but mostly contributions that would help us shrink our [issues list](https://github.com/dronekit/dronekit-python/issues). From 87deaf3315692e5ab430d99b38879024aa1b9e1d Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 29 Jan 2016 09:45:42 +1100 Subject: [PATCH 269/475] Fix minor typo in sitl introduction --- docs/develop/sitl_setup.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/sitl_setup.rst b/docs/develop/sitl_setup.rst index 73d6b74be..6fde96f80 100644 --- a/docs/develop/sitl_setup.rst +++ b/docs/develop/sitl_setup.rst @@ -11,7 +11,7 @@ your own developer desktop!). SITL can run natively on Linux, Mac and Windows, or within a virtual machine. It can be installed on the same computer as DroneKit, or on another computer on the same network. -The sections below explain how install and run SITL, and how to connect to DroneKit-Python and Ground +The sections below explain how to install and run SITL, and how to connect to DroneKit-Python and Ground Stations at the same time. From 92772b8df283bd471f7621d14d64c9f4ae6e756f Mon Sep 17 00:00:00 2001 From: Daniel Habib Date: Thu, 28 Jan 2016 08:12:11 -0500 Subject: [PATCH 270/475] Clean Documentation Remove Unnecessary import --- docs/guide/quick_start.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/guide/quick_start.rst b/docs/guide/quick_start.rst index b3567b358..38cf20663 100644 --- a/docs/guide/quick_start.rst +++ b/docs/guide/quick_start.rst @@ -52,7 +52,6 @@ we then use to query the attributes. # Import DroneKit-Python from dronekit import connect, VehicleMode - import time # Connect to the Vehicle. print "Connecting to vehicle on: 'tcp:127.0.0.1:5760'" From 66a0523bceb44e867cab3cddb89b11354198af82 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 3 Feb 2016 20:34:50 +1100 Subject: [PATCH 271/475] Fix incorrect property marker for airspeed --- dronekit/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 603601688..8dfd2c481 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1519,7 +1519,7 @@ def airspeed(self): """ return self._airspeed - @groundspeed.setter + @airspeed.setter def airspeed(self, speed): speed_type = 0 # air speed msg = self.message_factory.command_long_encode( From 01fce1f931b24a915d108d9b0d21ed238d24a793 Mon Sep 17 00:00:00 2001 From: mgrennan Date: Wed, 3 Feb 2016 13:23:42 -0600 Subject: [PATCH 272/475] Updates for debuging and connections via TCP --- docs/guide/connecting_vehicle.rst | 2 ++ docs/guide/debugging.rst | 26 +++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/docs/guide/connecting_vehicle.rst b/docs/guide/connecting_vehicle.rst index 7d9363fb1..63949a8c0 100644 --- a/docs/guide/connecting_vehicle.rst +++ b/docs/guide/connecting_vehicle.rst @@ -54,6 +54,8 @@ The table below shows *connection strings* you can use for some of the more comm - ``/dev/ttyAMA0`` (also set ``baud=57600``) * - SITL connected to the vehicle via UDP - ``127.0.0.1:14550`` + * - SITL connected to the vehical via TCP + - ``tcp:127.0.0.1:5760`` * - OSX computer connected to the vehicle via USB - ``dev/cu.usbmodem1`` * - Windows computer connected to the vehicle via USB (in this case on COM14) diff --git a/docs/guide/debugging.rst b/docs/guide/debugging.rst index b6499ceae..dde4a4aa4 100644 --- a/docs/guide/debugging.rst +++ b/docs/guide/debugging.rst @@ -58,4 +58,28 @@ for inspecting code (e.g. `dir() `_. + +.. code-block:: python + :emphasize-lines: 4 + + pip install pudb + + +To start debugging, simply insert: + +.. code-block:: python + :emphasize-lines: 4 + + from pudb import set_trace; set_trace() + +Insert either of these snippets into the piece of code you want to debug, or run the entire script with: + +.. code-block:: python + :emphasize-lines: 4 + + pudb my-script.py + + From ad726914ab9d0279d7a8d4f338ba995f9a48146b Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 4 Feb 2016 09:44:04 +1100 Subject: [PATCH 273/475] Additions to debugging and connecting_vehicle --- docs/guide/connecting_vehicle.rst | 2 +- docs/guide/debugging.rst | 48 +++++++++++++++++-------------- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/docs/guide/connecting_vehicle.rst b/docs/guide/connecting_vehicle.rst index 63949a8c0..f4430f501 100644 --- a/docs/guide/connecting_vehicle.rst +++ b/docs/guide/connecting_vehicle.rst @@ -54,7 +54,7 @@ The table below shows *connection strings* you can use for some of the more comm - ``/dev/ttyAMA0`` (also set ``baud=57600``) * - SITL connected to the vehicle via UDP - ``127.0.0.1:14550`` - * - SITL connected to the vehical via TCP + * - SITL connected to the vehicle via TCP - ``tcp:127.0.0.1:5760`` * - OSX computer connected to the vehicle via USB - ``dev/cu.usbmodem1`` diff --git a/docs/guide/debugging.rst b/docs/guide/debugging.rst index dde4a4aa4..2ce7ef0ed 100644 --- a/docs/guide/debugging.rst +++ b/docs/guide/debugging.rst @@ -34,9 +34,33 @@ add ``set-trace()`` at the point where you want to break execution: The available `debugger commands are listed here `_. - - +pudb - A full-screen, console-based Python debugger +=================================================== + +If you prefer a IDE like debug you can use `pudb - A full-screen, console-based Python debugger `_. + +.. code-block:: python + :emphasize-lines: 4 + + pip install pudb + + +To start debugging, simply insert: + +.. code-block:: python + :emphasize-lines: 4 + + from pudb import set_trace; set_trace() + +Insert either of these snippets into the piece of code you want to debug, or run the entire script with: + +.. code-block:: python + :emphasize-lines: 4 + + pudb my-script.py + + Print/log statements ==================== @@ -60,26 +84,6 @@ Other IDEs/debuggers There is no reason you should not be able to straightforwardly use other popular Python IDEs including IDLE and Eclipse. -If you prefer a IDE like debug you can use `pudb - A full-screen, console-based Python debugger `_. - -.. code-block:: python - :emphasize-lines: 4 - - pip install pudb - - -To start debugging, simply insert: - -.. code-block:: python - :emphasize-lines: 4 - - from pudb import set_trace; set_trace() -Insert either of these snippets into the piece of code you want to debug, or run the entire script with: - -.. code-block:: python - :emphasize-lines: 4 - - pudb my-script.py From cee294b38a7c6992ea5964c2d10d17591cbda569 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 3 Feb 2016 17:19:56 +1100 Subject: [PATCH 274/475] Update copyright range to 2015-2016 --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index f569024a0..47f09e962 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -42,7 +42,7 @@ # General information about the project. project = u'DroneKit Air: Python' -copyright = u'2015, 3D Robotics' +copyright = u'2015-2016, 3D Robotics' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the From b1ae74adab0f470fcad5ad20b9279e48ad088a9f Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 1 Feb 2016 10:45:23 +1100 Subject: [PATCH 275/475] Add easy_install to docs as alternative to apt-get for installing pip --- docs/develop/installation.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/develop/installation.rst b/docs/develop/installation.rst index 6fb6caba9..97b0229a8 100644 --- a/docs/develop/installation.rst +++ b/docs/develop/installation.rst @@ -28,6 +28,12 @@ It is installed from **pip** on all platforms: sudo apt-get install python-pip python-dev + Alternatively, the *easy_install* tool provides another way to install pip: + + .. code-block:: bash + + sudo easy_install pip + * :doc:`companion-computers` are likely to run on stripped down versions of Linux. Ensure you use a variant that supports Python 2.7 and can install Python packages from the Internet. * Windows does not come with Python by default, but there are From c25e837601276598538dffb0753129b762e2119e Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 5 Feb 2016 15:52:33 +1100 Subject: [PATCH 276/475] Remove test that hasn't been updated to DKPY2.0 and doesn't appear to do anything useful --- examples/perf/tx_perf_test.py | 316 ---------------------------------- 1 file changed, 316 deletions(-) delete mode 100644 examples/perf/tx_perf_test.py diff --git a/examples/perf/tx_perf_test.py b/examples/perf/tx_perf_test.py deleted file mode 100644 index 4c0e4129c..000000000 --- a/examples/perf/tx_perf_test.py +++ /dev/null @@ -1,316 +0,0 @@ -# -# This is the entry point for MavProxy running DroneAPI on the vehicle -# Usage: -# * mavproxy.py -# * module load api -# * api start TestPerformance.py -# - -""" -non native test: -mavproxy.py --master=/dev/ttyUSB0,921600 --rtscts --cmd "api start tx_perf_test.py" --max-packets=5000 --daemon - -name ncall tsub ttot tavg -..hon2.7/threading.py:752 Thread.run 1 0.000012 3.122469 3.122469 -..MAVProxy/mavproxy.py:686 main_loop 1 0.060946 3.122457 3.122457 -..mavproxy.py:510 process_master_all 1633 0.013251 2.671116 0.001636 -..oxy/mavproxy.py:470 process_master 3406 0.089617 2.657865 0.000780 -..tmega.py:6495 MAVLink.parse_buffer 2289 0.022196 2.171655 0.000949 -..lotmega.py:6433 MAVLink.parse_char 7399 0.103295 2.164799 0.000293 -..otmega.py:6428 MAVLink.__callbacks 5004 0.020360 1.178805 0.000236 -...py:230 LinkModule.master_callback 5004 0.261917 1.158446 0.000232 -..y:6461 MAVLink.__parse_char_legacy 7399 0.097154 0.835198 0.000113 -..b/python2.7/Queue.py:150 Queue.get 871.. 0.100600 0.734111 0.000084 -..dupilotmega.py:6508 MAVLink.decode 4938 0.267052 0.704184 0.000143 -../api.py:243 MPVehicle.send_mavlink 1938 0.015008 0.594257 0.000307 -..ardupilotmega.py:6402 MAVLink.send 1958 0.027275 0.528169 0.000270 -..erator/mavcrc.py:6 x25crc.__init__ 8854 0.048278 0.501256 0.000057 -.. MAVLink_command_long_message.pack 3876 0.035650 0.484348 0.000125 -..ink.py:407 LinkModule.__to_modules 5004 0.150852 0.436901 0.000087 -..143 MAVLink_heartbeat_message.pack 3916 0.080226 0.435734 0.000111 -..7/threading.py:309 _Condition.wait 189.. 0.043024 0.423701 0.000224 -..tor/mavcrc.py:14 x25crc.accumulate 12770 0.381646 0.381646 0.000030 -..b/python2.7/Queue.py:107 Queue.put 9184 0.094449 0.336993 0.000037 -..y:9626 MAVLink.command_long_encode 1938 0.015715 0.330282 0.000170 -..mavcrc.py:23 x25crc.accumulate_str 7832 0.106192 0.291197 0.000037 -..link/mavutil.py:726 mavserial.recv 3655 0.016554 0.281399 0.000077 -..ial/serialposix.py:453 Serial.read 3655 0.072221 0.264846 0.000072 -..mp_module.py:83 ParamModule.master 10611 0.027430 0.246833 0.000023 -..oxy/mavproxy.py:651 periodic_tasks 1633 0.077704 0.246205 0.000151 -..threading.py:373 _Condition.notify 17897 0.104504 0.244802 0.000014 -..oxy/mavproxy.py:188 MPState.master 10611 0.164999 0.219403 0.000021 -../python2.7/Queue.py:93 Queue.empty 12462 0.067670 0.215484 0.000017 -..77 LinkModule.master_send_callback 1958 0.052664 0.157868 0.000081 -...py:228 ParamModule.mavlink_packet 5004 0.022396 0.140830 0.000028 -..ink/mavutil.py:736 mavserial.write 1958 0.007324 0.127015 0.000065 -..util.py:212 mavserial.post_message 10008 0.100039 0.123820 0.000012 -..al/serialposix.py:488 Serial.write 1958 0.030760 0.119692 0.000061 -..eading.py:300 _Condition._is_owned 19792 0.056270 0.119383 0.000006 -..i.py:247 MPVehicle.message_factory 1938 0.008873 0.074651 0.000039 -..ings.py:104 MPSettings.__getattr__ 51190 0.070214 0.070214 0.000001 -..pi.py:396 APIModule.mavlink_packet 5004 0.035746 0.062572 0.000013 - -mavproxy.py --master=/dev/ttyUSB0,921600 --rtscts --cmd "api start tx_perf_test.py" --max-packets=5000 --daemon --native -name ncall tsub ttot tavg -..hon2.7/threading.py:752 Thread.run 1 0.000029 2.452683 2.452683 -..MAVProxy/mavproxy.py:686 main_loop 1 0.067917 2.452654 2.452654 -..mavproxy.py:510 process_master_all 1913 0.014797 1.963876 0.001027 -..oxy/mavproxy.py:470 process_master 3829 0.093805 1.949079 0.000509 -..tmega.py:6495 MAVLink.parse_buffer 2406 0.021892 1.463879 0.000608 -..lotmega.py:6433 MAVLink.parse_char 7437 0.104221 1.440324 0.000194 -..otmega.py:6428 MAVLink.__callbacks 5020 0.018822 1.160177 0.000231 -...py:230 LinkModule.master_callback 5020 0.263063 1.141356 0.000227 -..b/python2.7/Queue.py:150 Queue.get 892.. 0.103531 0.653408 0.000073 -../api.py:243 MPVehicle.send_mavlink 1958 0.016154 0.604459 0.000309 -..ardupilotmega.py:6402 MAVLink.send 1978 0.027734 0.535485 0.000271 -.. MAVLink_command_long_message.pack 3916 0.036748 0.495637 0.000127 -..143 MAVLink_heartbeat_message.pack 3956 0.083566 0.446711 0.000113 -..ink.py:407 LinkModule.__to_modules 5020 0.149475 0.428373 0.000085 -..7/threading.py:309 _Condition.wait 195.. 0.042275 0.353284 0.000181 -..y:9626 MAVLink.command_long_encode 1958 0.015960 0.335833 0.000172 -..b/python2.7/Queue.py:107 Queue.put 9404 0.094564 0.332117 0.000035 -..mavcrc.py:23 x25crc.accumulate_str 7912 0.107540 0.297585 0.000038 -..oxy/mavproxy.py:651 periodic_tasks 1913 0.089161 0.282385 0.000148 -..link/mavutil.py:726 mavserial.recv 3848 0.017526 0.269924 0.000070 -..erator/mavcrc.py:6 x25crc.__init__ 3956 0.021304 0.263655 0.000067 -..ial/serialposix.py:453 Serial.read 3848 0.073747 0.252398 0.000066 -..mp_module.py:83 ParamModule.master 10964 0.027469 0.252241 0.000023 -..threading.py:373 _Condition.notify 18331 0.105160 0.246178 0.000013 -..oxy/mavproxy.py:188 MPState.master 10964 0.168562 0.224772 0.000021 -../python2.7/Queue.py:93 Queue.empty 12996 0.071587 0.200717 0.000015 -..tor/mavcrc.py:14 x25crc.accumulate 7912 0.177303 0.177303 0.000022 -..77 LinkModule.master_send_callback 1978 0.053488 0.159170 0.000080 -...py:228 ParamModule.mavlink_packet 5020 0.021206 0.137314 0.000027 -..y:6423 MAVLink.__parse_char_native 7437 0.017084 0.129977 0.000017 -..ink/mavutil.py:736 mavserial.write 1978 0.007265 0.124608 0.000063 -..util.py:212 mavserial.post_message 10040 0.100500 0.124568 0.000012 -..eading.py:300 _Condition._is_owned 20285 0.057222 0.120491 0.000006 -..al/serialposix.py:488 Serial.write 1978 0.032346 0.117342 0.000059 -..i.py:247 MPVehicle.message_factory 1958 0.008865 0.075378 0.000038 -..ings.py:104 MPSettings.__getattr__ 54128 0.075145 0.075145 0.000001 -..param.py:232 ParamModule.idle_task 1913 0.015143 0.065751 0.000034 -..ython2.7/Queue.py:200 Queue._qsize 23873 0.044139 0.061933 0.000003 -..pi.py:396 APIModule.mavlink_packet 5020 0.035728 0.061797 0.000012 -..MAVLink_heartbeat_message.__init__ 6998 0.043136 0.060533 0.000009 - -mavproxy.py --master=/dev/ttyUSB0,921600 --rtscts --cmd "api start tx_perf_test.py" --max-packets=5000 --daemon --native --nolog -name ncall tsub ttot tavg -..hon2.7/threading.py:752 Thread.run 1 0.000020 1.909725 1.909725 -..MAVProxy/mavproxy.py:686 main_loop 1 0.078463 1.909705 1.909705 -..mavproxy.py:510 process_master_all 2355 0.015327 1.343029 0.000570 -..oxy/mavproxy.py:470 process_master 4444 0.080486 1.327703 0.000299 -..tmega.py:6495 MAVLink.parse_buffer 2618 0.020202 1.026420 0.000392 -..lotmega.py:6433 MAVLink.parse_char 7708 0.095572 1.013109 0.000131 -..otmega.py:6428 MAVLink.__callbacks 5007 0.017085 0.743219 0.000148 -...py:230 LinkModule.master_callback 5007 0.151202 0.726134 0.000145 -.. MAVLink_command_long_message.pack 3952 0.036492 0.505875 0.000128 * 0.5, 25% of remaining - can shrink -../api.py:243 MPVehicle.send_mavlink 1976 0.015951 0.455050 0.000230 -..143 MAVLink_heartbeat_message.pack 3992 0.084775 0.454919 0.000114 -..ink.py:407 LinkModule.__to_modules 5007 0.127681 0.381962 0.000076 -..ardupilotmega.py:6402 MAVLink.send 1996 0.028108 0.380732 0.000191 -..y:9626 MAVLink.command_long_encode 1976 0.016601 0.346609 0.000175 -..oxy/mavproxy.py:651 periodic_tasks 2355 0.094366 0.305242 0.000130 -..mavcrc.py:23 x25crc.accumulate_str 7984 0.111864 0.301511 0.000038 -..erator/mavcrc.py:6 x25crc.__init__ 3992 0.022327 0.265754 0.000067 -..mp_module.py:83 ParamModule.master 11413 0.027317 0.253586 0.000022 -..oxy/mavproxy.py:188 MPState.master 11413 0.172153 0.226270 0.000020 -..link/mavutil.py:726 mavserial.recv 4604 0.020573 0.197259 0.000043 -..ial/serialposix.py:453 Serial.read 4604 0.083076 0.176686 0.000038 -..tor/mavcrc.py:14 x25crc.accumulate 7984 0.176148 0.176148 0.000022 -..y:6423 MAVLink.__parse_char_native 7708 0.017185 0.128009 0.000017 -...py:228 ParamModule.mavlink_packet 5007 0.019605 0.123487 0.000025 -..ink/mavutil.py:736 mavserial.write 1996 0.007271 0.115052 0.000058 -..util.py:212 mavserial.post_message 10014 0.087308 0.108892 0.000011 -..al/serialposix.py:488 Serial.write 1996 0.032340 0.107780 0.000054 -..i.py:247 MPVehicle.message_factory 1976 0.009835 0.084162 0.000043 -..param.py:232 ParamModule.idle_task 2355 0.017717 0.074372 0.000032 -..ings.py:104 MPSettings.__getattr__ 56145 0.067339 0.067339 0.000001 -..MAVLink_heartbeat_message.__init__ 7003 0.042130 0.060125 0.000009 -..pi.py:396 APIModule.mavlink_packet 5007 0.031268 0.055463 0.000011 -..Link_command_long_message.__init__ 1976 0.024271 0.047687 0.000024 -..til.py:1058 periodic_event.trigger 11776 0.030910 0.038640 0.000003 -..y/mavproxy.py:613 set_stream_rates 2356 0.022065 0.032767 0.000014 -..k.py:291 LinkModule.__update_state 5007 0.020987 0.029680 0.000006 -..proxy_wp.py:105 WPModule.idle_task 2355 0.011025 0.029247 0.000012 -../python2.7/Queue.py:93 Queue.empty 2355 0.015377 0.026646 0.000011 -..mega.py:43 MAVLink_header.__init__ 10995 0.025427 0.025427 0.000002 -..MAVLink_heartbeat_message.get_type 37436 0.023302 0.023302 0.000001 -..b/mp_module.py:51 APIModule.status 30058 0.020056 0.020056 0.000001 -..ilotmega.py:50 MAVLink_header.pack 3992 0.011181 0.019509 0.000005 - -Same options above, but fixed to remove unneeded pack call (about a 10% speedup on send: -name ncall tsub ttot tavg -/usr/lib/python2.7/threading.py:752 Thread.run 1 0.000012 2.105375 2.105375 -..rone/MAVProxy/MAVProxy/mavproxy.py:687 main_loop 1 0.083402 2.105364 2.105364 -..roxy/MAVProxy/mavproxy.py:510 process_master_all 2271 0.016510 1.507761 0.000664 -..MAVProxy/MAVProxy/mavproxy.py:470 process_master 4357 0.088733 1.491251 0.000342 -..s/v10/ardupilotmega.py:6495 MAVLink.parse_buffer 2613 0.022761 1.165566 0.000446 -..cts/v10/ardupilotmega.py:6433 MAVLink.parse_char 7720 0.108637 1.147566 0.000149 -..ts/v10/ardupilotmega.py:6428 MAVLink.__callbacks 5001 0.019474 0.842866 0.000169 -../mavproxy_link.py:230 LinkModule.master_callback 5001 0.173330 0.823391 0.000165 -..roneapi/module/api.py:243 MPVehicle.send_mavlink 1982 0.017148 0.554968 0.000280 -../dialects/v10/ardupilotmega.py:6402 MAVLink.send 2002 0.031468 0.478323 0.000239 -..les/mavproxy_link.py:407 LinkModule.__to_modules 5001 0.145099 0.432095 0.000086 -..MAVProxy/MAVProxy/mavproxy.py:651 periodic_tasks 2271 0.106075 0.333850 0.000147 -..otmega.py:4418 MAVLink_command_long_message.pack 1982 0.022973 0.308794 0.000156 -..upilotmega.py:143 MAVLink_heartbeat_message.pack 2002 0.051051 0.274553 0.000137 -..y/modules/lib/mp_module.py:83 ParamModule.master 11334 0.029509 0.272114 0.000024 -..MAVProxy/MAVProxy/mavproxy.py:188 MPState.master 11334 0.185972 0.242605 0.000021 -..6_64-2.7/pymavlink/mavutil.py:726 mavserial.recv 4566 0.022184 0.209205 0.000046 -..t-packages/serial/serialposix.py:453 Serial.read 4566 0.087580 0.187021 0.000041 -..ink/generator/mavcrc.py:23 x25crc.accumulate_str 4004 0.072369 0.183322 0.000046 -../pymavlink/generator/mavcrc.py:6 x25crc.__init__ 2002 0.014129 0.164718 0.000082 -..rdupilotmega.py:6423 MAVLink.__parse_char_native 7720 0.019109 0.144126 0.000019 -..mavproxy_param.py:228 ParamModule.mavlink_packet 5001 0.022000 0.140084 0.000028 -../pymavlink/mavutil.py:212 mavserial.post_message 10002 0.097754 0.122129 0.000012 -.._64-2.7/pymavlink/mavutil.py:736 mavserial.write 2002 0.008113 0.122124 0.000061 -..-packages/serial/serialposix.py:488 Serial.write 2002 0.033661 0.114011 0.000057 -..mavlink/generator/mavcrc.py:14 x25crc.accumulate 4004 0.102416 0.102416 0.000026 -..eapi/module/api.py:247 MPVehicle.message_factory 1982 0.009796 0.089112 0.000045 -..ules/mavproxy_param.py:232 ParamModule.idle_task 2271 0.019467 0.080866 0.000036 -..es/lib/mp_settings.py:104 MPSettings.__getattr__ 55391 0.070717 0.070717 0.000001 -..lotmega.py:56 MAVLink_heartbeat_message.__init__ 7003 0.047517 0.068058 0.000010 -..rdupilotmega.py:9452 MAVLink.command_long_encode 1982 0.013160 0.066973 0.000034 -..neapi/module/api.py:396 APIModule.mavlink_packet 5001 0.034765 0.061318 0.000012 -..ga.py:4403 MAVLink_command_long_message.__init__ 1982 0.027512 0.053814 0.000027 -..pymavlink/mavutil.py:1058 periodic_event.trigger 11356 0.033456 0.041815 0.000004 -..VProxy/MAVProxy/mavproxy.py:613 set_stream_rates 2272 0.024629 0.035985 0.000016 -..s/mavproxy_link.py:291 LinkModule.__update_state 5001 0.023399 0.032898 0.000007 -..xy/modules/mavproxy_wp.py:105 WPModule.idle_task 2271 0.012621 0.032238 0.000014 - -New baseline with previous optimiz applied but a longer run - -mavproxy.py --master=/dev/ttyUSB0,921600 --rtscts --cmd "api start tx_perf_test.py" --max-packets=20000 --daemon --native --nolog -name ncall tsub ttot tavg -/usr/lib/python2.7/threading.py:752 Thread.run 1 0.000014 9.295308 9.295308 -..rone/MAVProxy/MAVProxy/mavproxy.py:687 main_loop 1 0.357102 9.295294 9.295294 -..roxy/MAVProxy/mavproxy.py:510 process_master_all 9222 0.073024 6.726796 0.000729 -..MAVProxy/MAVProxy/mavproxy.py:470 process_master 17691 0.396538 6.653772 0.000376 -..s/v10/ardupilotmega.py:6495 MAVLink.parse_buffer 10787 0.103953 5.217913 0.000484 -..cts/v10/ardupilotmega.py:6433 MAVLink.parse_char 30840 0.475240 5.102247 0.000165 -..ts/v10/ardupilotmega.py:6428 MAVLink.__callbacks 20001 0.083017 3.773949 0.000189 -../mavproxy_link.py:230 LinkModule.master_callback 20001 0.771989 3.690932 0.000185 -..roneapi/module/api.py:243 MPVehicle.send_mavlink 7284 0.060705 2.045226 0.000281 -..les/mavproxy_link.py:407 LinkModule.__to_modules 20001 0.664688 1.929889 0.000096 -../dialects/v10/ardupilotmega.py:6402 MAVLink.send 7362 0.113751 1.770477 0.000240 -..MAVProxy/MAVProxy/mavproxy.py:651 periodic_tasks 9222 0.478214 1.513542 0.000164 -..otmega.py:4418 MAVLink_command_long_message.pack 7284 0.083047 1.141213 0.000157 -..y/modules/lib/mp_module.py:83 ParamModule.master 44230 0.127558 1.115275 0.000025 -..upilotmega.py:143 MAVLink_heartbeat_message.pack 7362 0.191518 1.018261 0.000138 -..MAVProxy/MAVProxy/mavproxy.py:188 MPState.master 44230 0.751921 0.987717 0.000022 -..6_64-2.7/pymavlink/mavutil.py:726 mavserial.recv 17790 0.096199 0.908664 0.000051 -..t-packages/serial/serialposix.py:453 Serial.read 17790 0.376893 0.812465 0.000046 -..ink/generator/mavcrc.py:23 x25crc.accumulate_str 14724 0.265819 0.676481 0.000046 -..rdupilotmega.py:6423 MAVLink.__parse_char_native 30840 0.084953 0.631528 0.000020 -..mavproxy_param.py:228 ParamModule.mavlink_packet 20001 0.099333 0.612545 0.000031 -../pymavlink/generator/mavcrc.py:6 x25crc.__init__ 7362 0.050913 0.606722 0.000082 -../pymavlink/mavutil.py:212 mavserial.post_message 40002 0.441143 0.552693 0.000014 -.._64-2.7/pymavlink/mavutil.py:736 mavserial.write 7362 0.029389 0.457603 0.000062 -..-packages/serial/serialposix.py:488 Serial.write 7362 0.124079 0.428214 0.000058 -..mavlink/generator/mavcrc.py:14 x25crc.accumulate 14724 0.379388 0.379388 0.000026 -..ules/mavproxy_param.py:232 ParamModule.idle_task 9222 0.088616 0.367637 0.000040 -..eapi/module/api.py:247 MPVehicle.message_factory 7284 0.038850 0.325071 0.000045 -..es/lib/mp_settings.py:104 MPSettings.__getattr__ 220.. 0.310079 0.310079 0.000001 -..lotmega.py:56 MAVLink_heartbeat_message.__init__ 27363 0.194285 0.275280 0.000010 -..neapi/module/api.py:396 APIModule.mavlink_packet 20001 0.153114 0.271093 0.000014 -..rdupilotmega.py:9452 MAVLink.command_long_encode 7284 0.046631 0.234445 0.000032 -..pymavlink/mavutil.py:1058 periodic_event.trigger 46111 0.154911 0.192188 0.000004 -..ga.py:4403 MAVLink_command_long_message.__init__ 7284 0.096461 0.187814 0.000026 -..s/mavproxy_link.py:291 LinkModule.__update_state 20001 0.115403 0.162070 0.000008 -..VProxy/MAVProxy/mavproxy.py:613 set_stream_rates 9223 0.106982 0.158716 0.000017 -..xy/modules/mavproxy_wp.py:105 WPModule.idle_task 9222 0.058149 0.147688 0.000016 -/usr/lib/python2.7/Queue.py:93 Queue.empty 9222 0.074266 0.128052 0.000014 -..lotmega.py:81 MAVLink_heartbeat_message.get_type 149.. 0.116623 0.116623 0.000001 -..oxy/modules/lib/mp_module.py:51 APIModule.status 122.. 0.103564 0.103564 0.000001 -..es/lib/mp_module.py:36 LinkModule.mavlink_packet 160.. 0.097872 0.097872 0.000001 -../v10/ardupilotmega.py:43 MAVLink_header.__init__ 34725 0.094988 0.094988 0.000003 -..xy/modules/lib/mp_module.py:43 LinkModule.module 27666 0.062593 0.093906 0.000003 - -Same args as previous, but optimzations to iterate only over the modules that have packet/idle -handlers. (a 30% speedup of master_callback and 10% speedup overall in tx_perf_test) - -name ncall tsub ttot tavg -/usr/lib/python2.7/threading.py:752 Thread.run 1 0.000014 7.506126 7.506126 -..rone/MAVProxy/MAVProxy/mavproxy.py:695 main_loop 1 0.341018 7.506112 7.506112 -..roxy/MAVProxy/mavproxy.py:520 process_master_all 10080 0.064470 5.301439 0.000526 -..MAVProxy/MAVProxy/mavproxy.py:480 process_master 18691 0.343054 5.236969 0.000280 -..s/v10/ardupilotmega.py:6495 MAVLink.parse_buffer 10922 0.085098 3.990414 0.000365 -..cts/v10/ardupilotmega.py:6433 MAVLink.parse_char 31061 0.402903 3.901436 0.000126 -..ts/v10/ardupilotmega.py:6428 MAVLink.__callbacks 20002 0.071189 2.773164 0.000139 -../mavproxy_link.py:230 LinkModule.master_callback 20002 0.649377 2.701975 0.000135 -..roneapi/module/api.py:243 MPVehicle.send_mavlink 7328 0.053543 1.706073 0.000233 -../dialects/v10/ardupilotmega.py:6402 MAVLink.send 7406 0.098886 1.474602 0.000199 -..les/mavproxy_link.py:408 LinkModule.__to_modules 20002 0.365783 1.235950 0.000062 -..MAVProxy/MAVProxy/mavproxy.py:661 periodic_tasks 10080 0.346112 1.176351 0.000117 -..otmega.py:4418 MAVLink_command_long_message.pack 7328 0.070202 0.952317 0.000130 -..y/modules/lib/mp_module.py:83 ParamModule.master 45160 0.102112 0.937280 0.000021 -..upilotmega.py:143 MAVLink_heartbeat_message.pack 7406 0.159165 0.847291 0.000114 -..MAVProxy/MAVProxy/mavproxy.py:190 MPState.master 45160 0.639222 0.835168 0.000018 -..6_64-2.7/pymavlink/mavutil.py:726 mavserial.recv 18966 0.086703 0.793945 0.000042 -..t-packages/serial/serialposix.py:453 Serial.read 18966 0.339244 0.707242 0.000037 -..ink/generator/mavcrc.py:23 x25crc.accumulate_str 14812 0.222656 0.562755 0.000038 -..rdupilotmega.py:6423 MAVLink.__parse_char_native 31061 0.070296 0.532188 0.000017 -../pymavlink/generator/mavcrc.py:6 x25crc.__init__ 7406 0.043614 0.509105 0.000069 -..mavproxy_param.py:228 ParamModule.mavlink_packet 20002 0.079863 0.493304 0.000025 -../pymavlink/mavutil.py:212 mavserial.post_message 40004 0.362677 0.449900 0.000011 -.._64-2.7/pymavlink/mavutil.py:736 mavserial.write 7406 0.025578 0.374007 0.000051 -..-packages/serial/serialposix.py:488 Serial.write 7406 0.108336 0.348429 0.000047 -..ules/mavproxy_param.py:232 ParamModule.idle_task 10080 0.076702 0.320194 0.000032 -..mavlink/generator/mavcrc.py:14 x25crc.accumulate 14812 0.313900 0.313900 0.000021 -..eapi/module/api.py:247 MPVehicle.message_factory 7328 0.033713 0.288784 0.000039 -..es/lib/mp_settings.py:104 MPSettings.__getattr__ 228.. 0.260477 0.260477 0.000001 -..lotmega.py:56 MAVLink_heartbeat_message.__init__ 27408 0.162975 0.230682 0.000008 -..neapi/module/api.py:396 APIModule.mavlink_packet 20002 0.129320 0.229457 0.000011 -..rdupilotmega.py:9452 MAVLink.command_long_encode 7328 0.040013 0.202411 0.000028 -..pymavlink/mavutil.py:1058 periodic_event.trigger 50401 0.136115 0.169156 0.000003 -..ga.py:4403 MAVLink_command_long_message.__init__ 7328 0.083786 0.162398 0.000022 -..VProxy/MAVProxy/mavproxy.py:623 set_stream_rates 10081 0.098845 0.144738 0.000014 -..s/mavproxy_link.py:292 LinkModule.__update_state 20002 0.099563 0.138054 0.000007 -..xy/modules/mavproxy_wp.py:105 WPModule.idle_task 10080 0.051101 0.130417 0.000013 -/usr/lib/python2.7/Queue.py:93 Queue.empty 10080 0.066707 0.116093 0.000012 -..lotmega.py:81 MAVLink_heartbeat_message.get_type 149.. 0.095856 0.095856 0.000001 -..xy/modules/lib/mp_module.py:43 LinkModule.module 30240 0.054315 0.083003 0.000003 - -""" - -from pymavlink import mavutil -import time - -UPDATE_RATE = 50.0 - -class PerfTest(): - def __init__(self): - # First get an instance of the API endpoint - api = local_connect() - - # get our vehicle - when running with mavproxy it only knows about one vehicle (for now) - self.vehicle = api.get_vehicles()[0] - - self.vehicle.wait_init() - - while True: - msg = self.vehicle.message_factory.command_long_encode( - 0, 1, # target system, target component - mavutil.mavlink.MAV_CMD_DO_CHANGE_SPEED, # frame - 0, # confirmation - 1, 1.0, -1, # params 1-3 - 0.0, 0.0, 0.0, 0.0 ) # params 4-7 (not used) - - - # send command to vehicle - self.vehicle.send_mavlink(msg) - - msg2 = self.vehicle.message_factory.command_long_encode( - 0, 1, # target system, target component - mavutil.mavlink.MAV_CMD_DO_SET_ROI, #command - 0, #confirmation - 0, 0, 0, 0, #params 1-4 - 33.0, - 100.9, - 40.6 - ) - - self.vehicle.send_mavlink(msg2) - time.sleep( 1 / UPDATE_RATE ) - -PerfTest() \ No newline at end of file From 1a89df1bcc94953a39049734f394e7be7020b718 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 5 Feb 2016 16:01:52 +1100 Subject: [PATCH 277/475] Rename the performance test for consistency --- .../{perf/perf_test.py => performance_test/performance_test.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/{perf/perf_test.py => performance_test/performance_test.py} (100%) diff --git a/examples/perf/perf_test.py b/examples/performance_test/performance_test.py similarity index 100% rename from examples/perf/perf_test.py rename to examples/performance_test/performance_test.py From 1a112bf017d808225d93368d3c6502907b36dff5 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 5 Feb 2016 16:54:46 +1100 Subject: [PATCH 278/475] Fix/simplify and document the performance test. --- docs/examples/index.rst | 1 + examples/performance_test/performance_test.py | 265 +++++------------- 2 files changed, 74 insertions(+), 192 deletions(-) diff --git a/docs/examples/index.rst b/docs/examples/index.rst index d8ead16da..d2d815158 100644 --- a/docs/examples/index.rst +++ b/docs/examples/index.rst @@ -23,6 +23,7 @@ during missions and outside missions using custom commands. Drone Delivery Flight Replay Channel Overrides + Performance Test diff --git a/examples/performance_test/performance_test.py b/examples/performance_test/performance_test.py index 96e4cb5cd..0f7ba1bb0 100644 --- a/examples/performance_test/performance_test.py +++ b/examples/performance_test/performance_test.py @@ -1,124 +1,44 @@ -# -# This is a small example of the python drone API -# -from dronekit import connect, VehicleMode +""" +performance_test.py: + +This performance test logs the interval between messages being +sent by Dronekit-Python and an acknowledgment being received +from the autopilot. It provides a running report of the maximum, +minimum, and most recent interval for 30 seconds. + +Full documentation is provided at http://python.dronekit.io/examples/performance_test.html +""" +from dronekit import connect from pymavlink import mavutil import time +import sys from datetime import datetime -import traceback - -from matplotlib import pyplot -from numpy import arange -import bisect - -findings = """ -Reception latency: -* due to a top level select() on the udp port, the latency for calling process_master seems to be sub 1ms (limit of python timer resolution) - -Reception periodicity: -TBD - -Background processing perodicity: -TBD - -Sending perodicity: -TBD - -Computation efficency: -FIXME - -Max closed loop rate: -* 20ms+/-300us when talking to SITL (every time we recieve a cmd_ack we immediately send a pair of ROI related msgs) -* The less than 300us variablity makes me think SITL has some 20ms poll rate - need to try with real vehicle - -SITL copter load -Interval (sec) 0.019865 -MaxInterval (sec) 0.021927 -MinInterval (sec) 0.018421 - -AVR plane load: 20ms+/-7ms -Interval 0.02061 -MaxInterval 0.025496 -MinInterval 0.011533 - -PX4 quad load on Edsion: 20ms +60ms -5ms (VERY HIGH VARIABILITY - mostly due to px4 side - see below) -Interval 0.0281970000001 -MaxInterval 0.0786720000001 -MinInterval 0.0161290000001 - -PX4 quad load on a pixhawk (a9defa35) talking to my desktop - similar variability as with an Edison: -Interval 0.01989 -MaxInterval 0.0688479999999 -MinInterval 0.00722900000005 -Interval 0.019929 -MaxInterval 0.0688479999999 -MinInterval 0.00722900000005 -Interval 0.0189700000001 -MaxInterval 0.0688479999999 -MinInterval 0.00722900000005 - -or here's 20ish of the interval values seen on the px4 (a9defa35) Test -Interval 0.020012 -Interval 0.0199689999999 -Interval 0.0229640000002 -Interval 0.0171049999999 -Interval 0.0198150000001 -Interval 0.0211049999998 -Interval 0.0199740000003 -Interval 0.0199459999999 -Interval 0.0199590000002 -Interval 0.0200379999997 -Interval 0.0200850000001 -Interval 0.0198839999998 -Interval 0.0200420000001 -Interval 0.0199539999999 -Interval 0.0200760000002 -Interval 0.0199029999999 -Interval 0.0200950000003 -Interval 0.0517199999999 - -now testing with a plane load with a px4 (a9defa35) at 56kbps - highly variable 25 to 82ms -Interval 0.0589850000001 -MaxInterval 0.0829760000001 -MinInterval 0.0258819999999 - -but change to 115kbps and things are much better -Interval 0.0201160000001 -MaxInterval 0.044656 -MinInterval 0.0150279999998 - -and changing things to 500kbps everything is just peachie - 18ms -Interval 0.018119 -MaxInterval 0.02527 -MinInterval 0.015737 - -Recommendations: -Run link as fast as you can 1500kbps? -Turn on hw flow control (and use --rtscts on mavproxy) - -mavproxy.py --master=/dev/ttyMFD1,115200 --cmd="api start perf_test.py" -""" + #Set up option parsing to get connection string import argparse -parser = argparse.ArgumentParser(description='Example that demonstrates mission import/export from a file. Connects to SITL on local PC by default.') -parser.add_argument('--connect', default='127.0.0.1:14550', - help="vehicle connection target. Default '127.0.0.1:14550'") +parser = argparse.ArgumentParser(description='Generates max, min and current interval between message sent and ack recieved. Will start and connect to SITL if no connection string specified.') +parser.add_argument('--connect', + help="vehicle connection target string. If not specified, SITL automatically started and used.") args = parser.parse_args() +connection_string=args.connect -# Connect to the Vehicle -print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, wait_ready=True) +if not args.connect: + print "Starting copter simulator (SITL)" + from dronekit_sitl import SITL + sitl = SITL() + sitl.download('copter', '3.3', verbose=True) + sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] + sitl.launch(sitl_args, await_ready=True, restart=True) + connection_string='tcp:127.0.0.1:5760' -#global vehicle +# Connect to the Vehicle +print 'Connecting to vehicle on: %s' % connection_string +vehicle = connect(connection_string, wait_ready=True) -def scatterplot(x,y): - pyplot.plot(x,y,'b.') - pyplot.xlim(min(x)-1,max(x)+1) - pyplot.ylim(min(y)-1,max(y)+1) - pyplot.show() +#global vehicle def cur_usec(): @@ -138,100 +58,61 @@ def __init__(self): def reset(self): self.maxinterval = 0 self.mininterval = 10000 + + def log(self): + #print "Interval", self.previnterval + #print "MaxInterval", self.maxinterval + #print "MinInterval", self.mininterval + sys.stdout.write('MaxInterval: %s\tMinInterval: %s\tInterval: %s\r' % (self.maxinterval,self.mininterval, self.previnterval) ) + sys.stdout.flush() + def update(self): now = cur_usec() self.numcount = self.numcount + 1 self.previnterval = now - self.prevtime self.prevtime = now - self.maxinterval = max(self.previnterval, self.maxinterval) - self.mininterval = min(self.mininterval, self.previnterval) - - #print "Interval", self.previnterval - if (self.numcount % 100) == 0: - if self.numcount == 200: - # Ignore delays during startup - self.reset() - print "Interval", self.previnterval - print "MaxInterval", self.maxinterval - print "MinInterval", self.mininterval + if self.numcount>1: #ignore first value where self.prevtime not reliable. + self.maxinterval = max(self.previnterval, self.maxinterval) + self.mininterval = min(self.mininterval, self.previnterval) + self.log() acktime = MeasureTime() -def mavrx_debug_handler(message): - """Measure heartbeat periodically""" - mtype = message.get_type() - global sendtime - #if mtype == 'HEARTBEAT': - if mtype == 'COMMAND_ACK': - #traceback.print_stack() - #print "GOT ACK", message - acktime.update() - send_testpackets() +#Create COMMAND_ACK message listener. +@vehicle.on_message('COMMAND_ACK') +def listener(self, name, message): + acktime.update() + send_testpackets() def send_testpackets(): - #print "send ROI cmds" - - # create the SET_POSITION_TARGET_GLOBAL_INT command - msg = vehicle.message_factory.set_position_target_global_int_encode( - 0, # time_boot_ms (not used) - 1, 1, # target system, target component - mavutil.mavlink.MAV_FRAME_GLOBAL, # frame - 0b1000000011000111, # type_mask - enable velocity only - 0, 0, 0, # x, y, z positions (not used) - 0, 0, 0.0, # x, y, z velocity in m/s - 0, 0, 0, # x, y, z acceleration (not used) - 0, 0) # yaw, yaw_rate (not used) - - # send command to vehicle - vehicle.send_mavlink(msg) - - # set ROI - msg = vehicle.message_factory.command_long_encode( - 1, 1, # target system, target component - #mavutil.mavlink.MAV_CMD_DO_SET_RELAY, #command - mavutil.mavlink.MAV_CMD_DO_SET_ROI, #command - 0, #confirmation - 0, 0, 0, 0, #params 1-4 - 0, - 0, - 0 - ) - - vehicle.send_mavlink(msg) - - -# Print out some interesting stats about the vehicle -print "Mode: %s" % vehicle.mode -print "Location: %s" % vehicle.location -print "Attitude: %s" % vehicle.attitude -print "Velocity: %s" % vehicle.velocity -print "GPS: %s" % vehicle.gps_0 -print "Armed: %s" % vehicle.armed -print "groundspeed: %s" % vehicle.groundspeed -print "airspeed: %s" % vehicle.airspeed - -import time -time.sleep(30) - -# Use of the following method is not recommended (it is better to add observer callbacks to attributes) but if you need it -# it is available... -vehicle.set_mavlink_callback(mavrx_debug_handler) - -# You can read and write parameters -#print "Param: %s" % vehicle.parameters['THR_MAX'] - -# Now download the vehicle waypoints -cmds = vehicle.commands -cmds.download() -cmds.wait_ready() -print "Home WP: %s" % cmds[0] -print "Current dest: %s" % cmds.next - - -print "Disarming..." -vehicle.armed = False - + #Send message using `command_long_encode` (returns an ACK) + msg = vehicle.message_factory.command_long_encode( + 1, 1, # target system, target component + #mavutil.mavlink.MAV_CMD_DO_SET_RELAY, #command + mavutil.mavlink.MAV_CMD_DO_SET_ROI, #command + 0, #confirmation + 0, 0, 0, 0, #params 1-4 + 0, + 0, + 0 + ) + + vehicle.send_mavlink(msg) + +#Start logging by sending a test packet +send_testpackets() + +print "Logging for 30 seconds" +for x in range(1,30): + time.sleep(1) + +# Close vehicle object before exiting script +vehicle.close() + +if not args.connect: + # Shut down simulator if it was started. + sitl.stop() From 413dcc6d4e06819fefbcfc98b86b730d00294623 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 5 Feb 2016 12:01:16 +1100 Subject: [PATCH 279/475] Do not use a hard-coded default home location for drone_delivery Wait for the vehicle to supply us with a location before starting the web server Fixes #362 --- examples/drone_delivery/drone_delivery.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/examples/drone_delivery/drone_delivery.py b/examples/drone_delivery/drone_delivery.py index 36386f527..123555a2f 100644 --- a/examples/drone_delivery/drone_delivery.py +++ b/examples/drone_delivery/drone_delivery.py @@ -41,7 +41,7 @@ class Drone(object): - def __init__(self, home_coords, server_enabled=True): + def __init__(self, server_enabled=True): self.gps_lock = False self.altitude = 30.0 @@ -50,7 +50,6 @@ def __init__(self, home_coords, server_enabled=True): self.vehicle = vehicle self.commands = self.vehicle.commands self.current_coords = [] - self.home_coords = home_coords self.webserver_enabled = server_enabled self._log("DroneDelivery Start") @@ -58,6 +57,12 @@ def __init__(self, home_coords, server_enabled=True): self.vehicle.add_attribute_listener('location', self.location_callback) def launch(self): + self._log("Waiting for location...") + while self.vehicle.location.global_frame.lat == 0: + time.sleep(0.1) + self.home_coords = [self.vehicle.location.global_frame.lat, + self.vehicle.location.global_frame.lon] + self._log("Waiting for ability to arm...") while not self.vehicle.is_armable: time.sleep(.1) @@ -149,8 +154,8 @@ def get_options(self): 'height': 470, 'zoom': 13, 'format': 'png', - 'access_token': 'pk.eyJ1IjoibXJwb2xsbyIsImEiOiJtUG0tRk9BIn0.AqAiefUV9fFYRo-w0jFR1Q', - 'mapid': 'mrpollo.kfbnjbl0', + 'access_token': 'pk.eyJ1Ijoia2V2aW4zZHIiLCJhIjoiY2lrOGoxN2s2MDJzYnR6a3drbTYwdGxmMiJ9.bv5u7QgmcJd6dZfLDGoykw', + 'mapid': 'kevin3dr.n56ffjoo', 'home_coords': self.home_coords, 'menu': [ {'name': 'Home', 'location': '/'}, @@ -215,5 +220,8 @@ def track(self, lat=None, lon=None): print 'Connecting to vehicle on: %s' % args.connect vehicle = connect(args.connect, wait_ready=True) -Drone([32.5738, -117.0068]).launch() +print 'Launching Drone...' +Drone().launch() + +print 'Waiting for cherrypy engine...' cherrypy.engine.block() From 6287b61e33632b572864263da4028c7b57399a5e Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 8 Feb 2016 18:04:36 +1100 Subject: [PATCH 280/475] Make drone delivery example use DK-SITL simulator if no connect string specified. Fix docs --- docs/examples/drone_delivery.rst | 68 +++++++++++++++-------- examples/drone_delivery/drone_delivery.py | 23 ++++++-- 2 files changed, 62 insertions(+), 29 deletions(-) diff --git a/docs/examples/drone_delivery.rst b/docs/examples/drone_delivery.rst index 0c4b01eeb..a6299c13d 100644 --- a/docs/examples/drone_delivery.rst +++ b/docs/examples/drone_delivery.rst @@ -6,11 +6,6 @@ This example shows how to create a `CherryPy `_ based w displays a mapbox map to let you view the current vehicle position and send the vehicle commands to fly to a particular latitude and longitude. -.. warning:: - - At time of writing, this example does not work properly (the vehicle does not take off). - For more information see `#357 Mode not changed when message sent inside drone delivery example `_ - New functionality demonstrated by this example includes: * Using attribute observers to be notified of vehicle state changes. @@ -23,11 +18,6 @@ Running the example The example can be run much as described in :doc:`running_examples` (which in turn assumes that the vehicle and DroneKit have been set up as described in :ref:`installing_dronekit`). The main exception is that you need to install the CherryPy dependencies and view the behaviour in a web browser. - -If you're using a simulated vehicle remember to :ref:`disable arming checks ` so -that the example can run. You can also `add a virtual rangefinder `_ -(otherwise the :py:attr:`Vehicle.rangefinder ` attribute may return values of ``None`` for the distance -and voltage). In summary, after cloning the repository: @@ -44,42 +34,64 @@ In summary, after cloning the repository: pip install -r requirements.pip - -#. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: +#. You can run the example against the simulator by specifying the Python script without any arguments. + The example will download and start DroneKit-SITL, and then connect to it: .. code-block:: bash - python drone_delivery.py --connect 127.0.0.1:14550 - - .. note:: - - The ``--connect`` parameter above connects to SITL on udp port 127.0.0.1:14550. - This is the default value for the parameter, and may be omitted. + python drone_delivery.py On the command prompt you should see (something like): - .. code-block:: bash + .. code:: bash - Connecting to vehicle on: 127.0.0.1:14550 + >python drone_delivery.py + + D:\Github\dronekit-python\examples\drone_delivery>drone_delivery.py + Starting copter simulator (SITL) + SITL already Downloaded. + local path: D:\Github\dronekit-python\examples\drone_delivery + Connecting to vehicle on: tcp:127.0.0.1:5760 + >>> APM:Copter V3.3 (d6053245) >>> Frame: QUAD + >>> Calibrating barometer + >>> Initialising APM... + >>> barometer calibration complete + >>> GROUND START + Launching Drone... [DEBUG]: Connected to vehicle. [DEBUG]: DroneDelivery Start + [DEBUG]: Waiting for location... [DEBUG]: Waiting for ability to arm... [DEBUG]: Running initial boot sequence [DEBUG]: Changing to mode: GUIDED + [DEBUG]: ... polled mode: GUIDED [DEBUG]: Waiting for arming... + >>> ARMING MOTORS + >>> GROUND START + >>> Initialising APM... [DEBUG]: Taking off http://localhost:8080/ - + Waiting for cherrypy engine... + +#. You can run the example against a specific connection (simulated or otherwise) by passing the :ref:`connection string ` for your vehicle in the ``--connect`` parameter. + For example, to connect to Solo: + + .. code-block:: bash + + python drone_delivery.py --connect udpin:0.0.0.0:14550 + + #. After a short while you should be able to reach your new webserver at http://localhost:8080. - The command prompt will show something like + Navigate to the **Command** screen, select a target on the map, then select **Go**. + The command prompt will show something like the message below. .. code-block:: bash [DEBUG]: Goto: [u'-35.4', u'149.2'], 29.98 - On the web server you can use the **Command** button to set a target location and - the **Track** button to view the moving vehicle (see the screenshots below). + The web server will switch you to the **Track** screen. You can view the vehicle progress by pressing the + **Update** button. Screenshots @@ -134,6 +146,14 @@ We start running a web server by calling ``cherrypy.engine.start()``. +Known issues +============ + +This example has the following issues: + +* `#537: Dronekit delivery tracking needs to zoom and also ideally auto update `_ +* `#538: Dronekit delivery example does not exit `_ + Source code =========== diff --git a/examples/drone_delivery/drone_delivery.py b/examples/drone_delivery/drone_delivery.py index 123555a2f..b3ff6fb56 100644 --- a/examples/drone_delivery/drone_delivery.py +++ b/examples/drone_delivery/drone_delivery.py @@ -17,12 +17,21 @@ #Set up option parsing to get connection string import argparse -parser = argparse.ArgumentParser(description='Print out vehicle state information. Connects to SITL on local PC by default.') -parser.add_argument('--connect', default='127.0.0.1:14550', - help="vehicle connection target. Default '127.0.0.1:14550'") +parser = argparse.ArgumentParser(description='Creates a CherryPy based web application that displays a mapbox map to let you view the current vehicle position and send the vehicle commands to fly to a particular latitude and longitude. Will start and connect to SITL if no connection string specified.') +parser.add_argument('--connect', + help="vehicle connection target string. If not specified, SITL is automatically started and used.") args = parser.parse_args() +connection_string=args.connect +if not args.connect: + print "Starting copter simulator (SITL)" + from dronekit_sitl import SITL + sitl = SITL() + sitl.download('copter', '3.3', verbose=True) + sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] + sitl.launch(sitl_args, await_ready=True, restart=True) + connection_string='tcp:127.0.0.1:5760' local_path=os.path.dirname(os.path.abspath(__file__)) print "local path: %s" % local_path @@ -217,11 +226,15 @@ def track(self, lat=None, lon=None): # Connect to the Vehicle -print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, wait_ready=True) +print 'Connecting to vehicle on: %s' % connection_string +vehicle = connect(connection_string, wait_ready=True) print 'Launching Drone...' Drone().launch() print 'Waiting for cherrypy engine...' cherrypy.engine.block() + +if not args.connect: + # Shut down simulator if it was started. + sitl.stop() From c76054de61c06ec2e9ea17311a4400d11895a626 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 9 Feb 2016 09:16:36 +1100 Subject: [PATCH 281/475] whitespace fix to beat Travis into submission --- docs/examples/drone_delivery.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/examples/drone_delivery.rst b/docs/examples/drone_delivery.rst index a6299c13d..371708e9b 100644 --- a/docs/examples/drone_delivery.rst +++ b/docs/examples/drone_delivery.rst @@ -80,8 +80,8 @@ In summary, after cloning the repository: .. code-block:: bash python drone_delivery.py --connect udpin:0.0.0.0:14550 - - + + #. After a short while you should be able to reach your new webserver at http://localhost:8080. Navigate to the **Command** screen, select a target on the map, then select **Go**. The command prompt will show something like the message below. @@ -92,7 +92,7 @@ In summary, after cloning the repository: The web server will switch you to the **Track** screen. You can view the vehicle progress by pressing the **Update** button. - + Screenshots =========== From f154a3aaed3ef5efd783fbb2be0ccf9113964277 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Tue, 9 Feb 2016 10:25:29 +1100 Subject: [PATCH 282/475] Temporarily disable web tests - failing with DRONEAPI_KEY issue --- .travis.yml | 2 +- appveyor.yml | 2 +- circle.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index ac9c1f0ba..31e22d53e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ install: - 'sudo pip install -r requirements.txt -UI' script: - - '[ "${TRAVIS_PULL_REQUEST}" != "false" ] || nosetests dronekit.test.web' +# - '[ "${TRAVIS_PULL_REQUEST}" != "false" ] || nosetests dronekit.test.web' - 'nosetests dronekit.test.unit' - 'nosetests dronekit.test.sitl' diff --git a/appveyor.yml b/appveyor.yml index cddc95e06..d1376d58c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -24,7 +24,7 @@ install: - cmd: 'pip install -r requirements.txt -UI' build_script: - - cmd: 'nosetests -vx dronekit.test.web' +# - cmd: 'nosetests -vx dronekit.test.web' - cmd: 'nosetests -vx dronekit.test.unit' - cmd: 'nosetests -svx dronekit.test.sitl' diff --git a/circle.yml b/circle.yml index ab69ade37..028b319dc 100644 --- a/circle.yml +++ b/circle.yml @@ -14,7 +14,7 @@ test: - 'cd docs; make clean; make html' # code - - 'nosetests dronekit.test.web' +# - 'nosetests dronekit.test.web' - 'nosetests dronekit.test.unit' - 'nosetests dronekit.test.sitl' From b8e5449a57c0a02a54d6c991e6210144aa0b60a4 Mon Sep 17 00:00:00 2001 From: Niels Joubert Date: Mon, 11 Jan 2016 16:05:42 -0800 Subject: [PATCH 283/475] Fix mount status to return float degrees, not int degrees --- dronekit/__init__.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 8dfd2c481..6712ce260 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -884,9 +884,9 @@ def listener(self, name, m): @self.on_message('MOUNT_STATUS') def listener(self, name, m): - self._mount_pitch = m.pointing_a / 100 - self._mount_roll = m.pointing_b / 100 - self._mount_yaw = m.pointing_c / 100 + self._mount_pitch = m.pointing_a / 100.0 + self._mount_roll = m.pointing_b / 100.0 + self._mount_yaw = m.pointing_c / 100.0 self.notify_attribute_listeners('mount', self.mount_status) # gimbal @@ -1945,9 +1945,9 @@ def __init__(self, vehicle): @vehicle.on_message('MOUNT_STATUS') def listener(vehicle, name, m): - self._pitch = m.pointing_a / 100 - self._roll = m.pointing_b / 100 - self._yaw = m.pointing_c / 100 + self._pitch = m.pointing_a / 100.0 + self._roll = m.pointing_b / 100.0 + self._yaw = m.pointing_c / 100.0 vehicle.notify_attribute_listeners('gimbal', vehicle.gimbal) @property From 17fb12e3c7bb7eff4bc38ccebb047e2511eefdfd Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Tue, 9 Feb 2016 11:02:49 +1100 Subject: [PATCH 284/475] Harmonise nosetest options across each of the integration platforms This should make the outputs comparable --- .travis.yml | 6 +++--- appveyor.yml | 4 ++-- circle.yml | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 31e22d53e..82a6a9da7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,9 +11,9 @@ install: - 'sudo pip install -r requirements.txt -UI' script: -# - '[ "${TRAVIS_PULL_REQUEST}" != "false" ] || nosetests dronekit.test.web' - - 'nosetests dronekit.test.unit' - - 'nosetests dronekit.test.sitl' +# - '[ "${TRAVIS_PULL_REQUEST}" != "false" ] || nosetests -svx dronekit.test.web' + - 'nosetests -svx dronekit.test.unit' + - 'nosetests -svx dronekit.test.sitl' git: depth: 10 diff --git a/appveyor.yml b/appveyor.yml index d1376d58c..86dda3947 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -24,8 +24,8 @@ install: - cmd: 'pip install -r requirements.txt -UI' build_script: -# - cmd: 'nosetests -vx dronekit.test.web' - - cmd: 'nosetests -vx dronekit.test.unit' +# - cmd: 'nosetests -svx dronekit.test.web' + - cmd: 'nosetests -svx dronekit.test.unit' - cmd: 'nosetests -svx dronekit.test.sitl' clone_depth: 10 diff --git a/circle.yml b/circle.yml index 028b319dc..486707359 100644 --- a/circle.yml +++ b/circle.yml @@ -14,9 +14,9 @@ test: - 'cd docs; make clean; make html' # code -# - 'nosetests dronekit.test.web' - - 'nosetests dronekit.test.unit' - - 'nosetests dronekit.test.sitl' +# - 'nosetests -svx dronekit.test.web' + - 'nosetests -svx dronekit.test.unit' + - 'nosetests -svx dronekit.test.sitl' general: build_dir: . From 0ae3f5652029008f6b7fc4f2838b136969fb72df Mon Sep 17 00:00:00 2001 From: Daniel Habib Date: Mon, 8 Feb 2016 17:37:53 -0500 Subject: [PATCH 285/475] Update best_practice.rst --- docs/develop/best_practice.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/develop/best_practice.rst b/docs/develop/best_practice.rst index f2bcb750b..4fa4e9c0c 100644 --- a/docs/develop/best_practice.rst +++ b/docs/develop/best_practice.rst @@ -73,12 +73,12 @@ running the connect within a ``try-catch`` block as shown: # Bad TCP connection except socket.error: print 'No server exists!' - except dronekit.APIException: - print 'Timeout!' # Bad TTY connection except exceptions.OSError as e: print 'No serial exists!' + + # API Error except dronekit.APIException: print 'Timeout!' From 5de7dcd326ecdabb7f26088842276f26cf02c405 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 10 Feb 2016 13:45:36 +1100 Subject: [PATCH 286/475] Increase timeouts, factor out a wait_for call --- dronekit/test/__init__.py | 8 ++++++++ dronekit/test/sitl/test_110.py | 11 ++++++----- dronekit/test/sitl/test_locations.py | 24 +++++------------------- 3 files changed, 19 insertions(+), 24 deletions(-) diff --git a/dronekit/test/__init__.py b/dronekit/test/__init__.py index 50639b872..fa1442c74 100644 --- a/dronekit/test/__init__.py +++ b/dronekit/test/__init__.py @@ -3,6 +3,7 @@ import sys from dronekit_sitl import SITL from nose.tools import assert_equals, with_setup +import time sitl = None sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] @@ -26,3 +27,10 @@ def with_sitl(fn): def test(*args, **kargs): return fn('tcp:127.0.0.1:5760', *args, **kargs) return test + +def wait_for(condition, time_max): + time_start = time.time() + while not condition(): + if time.time() - time_start > time_max: + break + time.sleep(0.1) diff --git a/dronekit/test/sitl/test_110.py b/dronekit/test/sitl/test_110.py index f2f9c7ab5..8386ba0b2 100644 --- a/dronekit/test/sitl/test_110.py +++ b/dronekit/test/sitl/test_110.py @@ -2,7 +2,7 @@ import sys import os from dronekit import connect, VehicleMode -from dronekit.test import with_sitl +from dronekit.test import with_sitl, wait_for from nose.tools import assert_equals @@ -17,8 +17,7 @@ def test_110(connpath): vehicle.parameters['FS_EKF_THRESH'] = 100 # Await armability. - while not vehicle.is_armable: - time.sleep(.1) + wait_for(lambda : vehicle.is_armable, 60) # Change the vehicle into STABILIZE mode vehicle.mode = VehicleMode("GUIDED") @@ -42,11 +41,12 @@ def armed_callback(vehicle, attribute, value): # arm and see update. vehicle.armed = True + # Wait for ACK. - time.sleep(3) + wait_for(lambda : armed_callback.called, 10) # Ensure the callback was called. - assert armed_callback.called > 0, "Callback should have been called." + assert armed_callback.called > 0, "Callback should have been called within %d seconds" % (time_max,) # Rmove all listeners. The first call should remove all listeners # we've added; the second call should be ignored and not throw. @@ -59,6 +59,7 @@ def armed_callback(vehicle, attribute, value): # Disarm and see update. vehicle.armed = False + # Wait for ack time.sleep(3) diff --git a/dronekit/test/sitl/test_locations.py b/dronekit/test/sitl/test_locations.py index a7a52fbdb..c1e5ef2b7 100644 --- a/dronekit/test/sitl/test_locations.py +++ b/dronekit/test/sitl/test_locations.py @@ -1,6 +1,6 @@ import time from dronekit import connect, VehicleMode, LocationGlobal -from dronekit.test import with_sitl +from dronekit.test import with_sitl, wait_for from nose.tools import assert_equals, assert_not_equals @@ -20,28 +20,17 @@ def arm_and_takeoff(aTargetAltitude): """ # Don't let the user try to fly autopilot is booting - i = 60 - while not vehicle.is_armable and i > 0: - time.sleep(1) - i = i - 1 + wait_for(lambda : vehicle.is_armable, 60) assert_equals(vehicle.is_armable, True) # Copter should arm in GUIDED mode vehicle.mode = VehicleMode("GUIDED") - i = 60 - while vehicle.mode.name != 'GUIDED' and i > 0: - # print " Waiting for guided %s seconds..." % (i,) - time.sleep(1) - i = i - 1 + wait_for(lambda : vehicle.mode.name == 'GUIDED', 60) assert_equals(vehicle.mode.name, 'GUIDED') # Arm copter. vehicle.armed = True - i = 60 - while not vehicle.armed and vehicle.mode.name == 'GUIDED' and i > 0: - # print " Waiting for arming %s seconds..." % (i,) - time.sleep(1) - i = i - 1 + wait_for(lambda : vehicle.armed, 60) assert_equals(vehicle.armed, True) # Take off to target altitude @@ -91,9 +80,6 @@ def callback(*args): assert_not_equals(args[2].alt, 0) ret['success'] = True - i = 15 - while i > 0 and not ret['success']: - time.sleep(1) - i = i - 1 + wait_for(lambda : ret['success'], 30) assert ret['success'], 'Expected location object to emit notifications.' From 1c1b72363958eb7145c72d7e97302a007b762b91 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 9 Feb 2016 21:12:50 +1100 Subject: [PATCH 287/475] Update mission_import_export.py to use dk-sitl by default --- docs/examples/mission_import_export.rst | 121 +++++++++--------- .../mission_import_export.py | 38 +++++- 2 files changed, 95 insertions(+), 64 deletions(-) diff --git a/docs/examples/mission_import_export.rst b/docs/examples/mission_import_export.rst index 20fe1919b..c8b0954db 100644 --- a/docs/examples/mission_import_export.rst +++ b/docs/examples/mission_import_export.rst @@ -33,72 +33,77 @@ In summary, after cloning the repository: cd dronekit-python/examples/mission_import_export/ - -#. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: +#. You can run the example against a simulator (DroneKit-SITL) by specifying the Python script without any arguments. + The example will download SITL binaries (if needed), start the simulator, and then connect to it: .. code-block:: bash - python mission_import_export.py --connect 127.0.0.1:14550 + python mission_import_export.py - - .. note:: + On the command prompt you should see (something like): - The ``--connect`` parameter above connects to SITL on udp port 127.0.0.1:14550. - This is the default value for the parameter, and may be omitted. - - -On the command prompt you should see (something like): - - -.. code:: bash - - Connecting to vehicle on: 127.0.0.1:14550 - >>> APM:Copter V3.3 (d6053245) - >>> Frame: QUAD - - Reading mission from file: mpmission.txt - - Upload mission from a file: mpmission.txt - Clear mission - Upload mission - - Save mission from Vehicle to file: exportedmission.txt - Download mission from vehicle - >>> flight plan received - Write mission to file - Close vehicle object - - Show original and uploaded/downloaded files: - - Mission file: mpmission.txt - QGC WPL 110 - 0 1 0 16 0 0 0 0 -35.363262 149.165237 584.000000 1 - 1 0 0 22 0.000000 0.000000 0.000000 0.000000 -35.361988 149.163753 100.000000 1 - 2 0 0 16 0.000000 0.000000 0.000000 0.000000 -35.361992 149.163593 100.000000 1 - 3 0 0 16 0.000000 0.000000 0.000000 0.000000 -35.363812 149.163609 100.000000 1 - 4 0 0 16 0.000000 0.000000 0.000000 0.000000 -35.363768 149.166055 100.000000 1 - 5 0 0 16 0.000000 0.000000 0.000000 0.000000 -35.361835 149.166012 100.000000 1 - 6 0 0 16 0.000000 0.000000 0.000000 0.000000 -35.362150 149.165046 100.000000 1 - - Mission file: exportedmission.txt - QGC WPL 110 - 0 1 0 16 0 0 0 0 0.0 0.0 0.0 1 - 1 0 0 22 0.0 0.0 0.0 0.0 -35.3619880676 149.163757324 100.0 1 - 2 0 0 16 0.0 0.0 0.0 0.0 -35.3619918823 149.163589478 100.0 1 - 3 0 0 16 0.0 0.0 0.0 0.0 -35.3638114929 149.163604736 100.0 1 - 4 0 0 16 0.0 0.0 0.0 0.0 -35.3637695312 149.166061401 100.0 1 - 5 0 0 16 0.0 0.0 0.0 0.0 -35.3618354797 149.166015625 100.0 1 - 6 0 0 16 0.0 0.0 0.0 0.0 -35.3621482849 149.165039062 100.0 1 - + .. code:: bash + + Starting copter simulator (SITL) + SITL already Downloaded. + Connecting to vehicle on: tcp:127.0.0.1:5760 + >>> APM:Copter V3.3 (d6053245) + >>> Frame: QUAD + >>> Calibrating barometer + >>> Initialising APM... + >>> barometer calibration complete + >>> GROUND START + Waiting for vehicle to initialise... + Waiting for vehicle to initialise... + Waiting for vehicle to initialise... + Waiting for vehicle to initialise... + Waiting for vehicle to initialise... + Reading mission from file: mpmission.txt + Upload mission from a file: mpmission.txt + Clear mission + Upload mission + Save mission from Vehicle to file: exportedmission.txt + Download mission from vehicle + >>> flight plan received + Write mission to file + Close vehicle object + Show original and uploaded/downloaded files: + + Mission file: mpmission.txt + QGC WPL 110 + 0 1 0 16 0 0 0 0 -35.363262 149.165237 584.000000 1 + 1 0 0 22 0.000000 0.000000 0.000000 0.000000 -35.361988 149.163753 00.000000 1 + 2 0 0 16 0.000000 0.000000 0.000000 0.000000 -35.361992 149.163593 00.000000 1 + 3 0 0 16 0.000000 0.000000 0.000000 0.000000 -35.363812 149.163609 00.000000 1 + 4 0 0 16 0.000000 0.000000 0.000000 0.000000 -35.363768 149.166055 00.000000 1 + 5 0 0 16 0.000000 0.000000 0.000000 0.000000 -35.361835 149.166012 00.000000 1 + 6 0 0 16 0.000000 0.000000 0.000000 0.000000 -35.362150 149.165046 00.000000 1 + + Mission file: exportedmission.txt + QGC WPL 110 + 0 1 0 16 0 0 0 0 -35.3632621765 149.165237427 583.989990234 1 + 1 0 0 22 0.0 0.0 0.0 0.0 -35.3619880676 149.163757324 100.0 1 + 2 0 0 16 0.0 0.0 0.0 0.0 -35.3619918823 149.163589478 100.0 1 + 3 0 0 16 0.0 0.0 0.0 0.0 -35.3638114929 149.163604736 100.0 1 + 4 0 0 16 0.0 0.0 0.0 0.0 -35.3637695312 149.166061401 100.0 1 + 5 0 0 16 0.0 0.0 0.0 0.0 -35.3618354797 149.166015625 100.0 1 + 6 0 0 16 0.0 0.0 0.0 0.0 -35.3621482849 149.165039062 100.0 1 + + + .. note:: + + The position values uploaded and then downloaded above do not match exactly. This rounding error can be ignored + because the difference is much smaller than the precision provided by GPS. + + The error occurs because all the params are encoded as 32-bit floats rather than 64-bit doubles (Python's native datatype). -.. note:: +#. You can run the example against a specific connection (simulated or otherwise) by passing the :ref:`connection string ` for your vehicle in the ``--connect`` parameter. - The position values uploaded and then downloaded above do not match exactly. This rounding error can be ignored - because the difference is much smaller than the precision provided by GPS. - - The error occurs because all the params are encoded as 32-bit floats rather than 64-bit doubles (Python's native datatype). + For example, to connect to SITL running on UDP port 14550 on your local computer: + .. code-block:: bash + python mission_import_export.py --connect 127.0.0.1:14550 How does it work? @@ -116,7 +121,7 @@ Known issues There are no known issues with this example. - + .. _example_mission_import_export_source_code: diff --git a/examples/mission_import_export/mission_import_export.py b/examples/mission_import_export/mission_import_export.py index 8669ce6c8..5b5cff6f8 100644 --- a/examples/mission_import_export/mission_import_export.py +++ b/examples/mission_import_export/mission_import_export.py @@ -10,19 +10,41 @@ from dronekit import connect, Command +import time #Set up option parsing to get connection string import argparse -parser = argparse.ArgumentParser(description='Example that demonstrates mission import/export from a file. Connects to SITL on local PC by default.') -parser.add_argument('--connect', default='127.0.0.1:14550', - help="vehicle connection target. Default '127.0.0.1:14550'") +parser = argparse.ArgumentParser(description='Demonstrates mission import/export from a file.') +parser.add_argument('--connect', + help="Vehicle connection target string. If not specified, SITL automatically started and used.") args = parser.parse_args() +connection_string = args.connect +sitl = None -#Connect to the Vehicle -print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, wait_ready=True) + +#Start SITL if no connection string specified +if not args.connect: + print "Starting copter simulator (SITL)" + from dronekit_sitl import SITL + sitl = SITL() + sitl.download('copter', '3.3', verbose=True) + sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] + sitl.launch(sitl_args, await_ready=True, restart=True) + connection_string='tcp:127.0.0.1:5760' + + +# Connect to the Vehicle +print 'Connecting to vehicle on: %s' % connection_string +vehicle = connect(connection_string, wait_ready=True) + +# Check that vehicle is armable. +# This ensures home_location is set (needed when saving WP file) + +while not vehicle.is_armable: + print " Waiting for vehicle to initialise..." + time.sleep(1) def readmission(aFileName): @@ -127,6 +149,7 @@ def printfile(aFileName): import_mission_filename = 'mpmission.txt' export_mission_filename = 'exportedmission.txt' + #Upload mission from file upload_mission(import_mission_filename) @@ -137,6 +160,9 @@ def printfile(aFileName): print "Close vehicle object" vehicle.close() +# Shut down simulator if it was started. +if sitl is not None: + sitl.stop() print "\nShow original and uploaded/downloaded files:" From 318c778cc4eda306dfdc7b74fb7fca072a87c669 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 9 Feb 2016 19:43:18 +1100 Subject: [PATCH 288/475] Update simple_goto example to use dronekit-sitl by default Minor tidy up to wording of using dk-sitl Improve code for closing sitl in examples --- docs/examples/simple_goto.rst | 108 ++++++++++++++-------------- examples/simple_goto/simple_goto.py | 36 +++++++--- 2 files changed, 79 insertions(+), 65 deletions(-) diff --git a/docs/examples/simple_goto.rst b/docs/examples/simple_goto.rst index 89c2d221c..3a3fc45d2 100644 --- a/docs/examples/simple_goto.rst +++ b/docs/examples/simple_goto.rst @@ -8,7 +8,7 @@ This example demonstrates how to arm and launch a Copter in GUIDED mode, travel to the home location. It uses :py:func:`Vehicle.simple_takeoff() `, :py:func:`Vehicle.simple_goto() ` and :py:attr:`Vehicle.mode `. -The target locations are centred around the home location when the :ref:`Simulated Vehicle ` is booted; +The target locations are centered around the home location when the :ref:`Simulated Vehicle ` is booted; you can edit the latitude and longitude to use more appropriate positions for your own vehicle. .. note:: @@ -33,9 +33,6 @@ Running the example The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle and DroneKit have been set up as described in :ref:`installing_dronekit`). -If you're using a simulated vehicle, remember to :ref:`disable arming checks ` so -that the example can run. - In summary, after cloning the repository: #. Navigate to the example folder as shown: @@ -43,66 +40,65 @@ In summary, after cloning the repository: .. code-block:: bash cd dronekit-python/examples/simple_goto/ - - -#. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: + +#. You can run the example against a simulator (DroneKit-SITL) by specifying the Python script without any arguments. + The example will download SITL binaries if needed, start the simulator, and then connect to it: .. code-block:: bash - python simple_goto.py --connect 127.0.0.1:14550 + python simple_goto.py - .. note:: + On the command prompt you should see (something like): - The ``--connect`` parameter above connects to SITL on udp port 127.0.0.1:14550. - This is the default value for this example, and may be omitted. - + .. code:: bash + + Starting copter simulator (SITL) + SITL already Downloaded. + Connecting to vehicle on: tcp:127.0.0.1:5760 + >>> APM:Copter V3.3 (d6053245) + >>> Frame: QUAD + >>> Calibrating barometer + >>> Initialising APM... + >>> barometer calibration complete + >>> GROUND START + Basic pre-arm checks + Waiting for vehicle to initialise... + ... + Waiting for vehicle to initialise... + Arming motors + Waiting for arming... + ... + Waiting for arming... + >>> ARMING MOTORS + >>> GROUND START + Waiting for arming... + >>> Initialising APM... + Taking off! + Altitude: 0.0 + ... + Altitude: 7.4 + Altitude: 9.0 + Altitude: 9.65 + Reached target altitude + Set default/target airspeed to 3 + Going towards first point for 30 seconds ... + Going towards second point for 30 seconds (groundspeed set to 10 m/s) ... + Returning to Launch + Close vehicle object -.. tip:: + .. tip:: - It is more interesting to watch the example above on a map than the console. The topic :ref:`viewing_uav_on_map` - explains how to set up *Mission Planner* to view a vehicle running on the simulator (SITL). - -On the command prompt you should see (something like): - -.. code-block:: bash - - Connecting to vehicle on: 127.0.0.1:14550 - >>> APM:Copter V3.4-dev (d52279af) - >>> Frame: QUAD - Basic pre-arm checks - Arming motors - Waiting for arming... - >>> ARMING MOTORS - >>> Initialising APM... - Taking off! - Altitude: 0.0 - Altitude: 0.0 - Altitude: 0.1 - Altitude: 1.25 - Altitude: 3.08 - Altitude: 5.14 - Altitude: 7.28 - Altitude: 9.2 - Altitude: 9.71 - Reached target altitude - Set default/target airspeed to 3 - Going towards first point for 30 seconds ... - Going towards second point for 30 seconds (groundspeed set to 10 m/s) ... - Returning to Launch - Close vehicle object + It is more interesting to watch the example run on a map than the console. The topic :ref:`viewing_uav_on_map` + explains how to set up *Mission Planner* to view a vehicle running on the simulator (SITL). + +#. You can run the example against a specific connection (simulated or otherwise) by passing the :ref:`connection string ` for your vehicle in the ``--connect`` parameter. -.. tip:: + For example, to connect to SITL running on UDP port 14550 on your local computer: - The code waits on :py:func:`Vehicle.is_armable `, so you shouldn't get stuck in ``Waiting for arming...``. - If you do, then: - - * On a real device you can view the controller LEDs to determine possible causes. - * On the Simulator console you can disable the checks if needed: + .. code-block:: bash - .. code-block:: bash + python simple_goto.py --connect 127.0.0.1:14550 - STABILIZE>param load ../Tools/autotest/copter_params.parm - STABILIZE>param set ARMING_CHECK 0 How does it work? @@ -119,8 +115,8 @@ Then set the mode to ``GUIDED``, arm the vehicle, and call is explained in the guide topic :ref:`taking-off`. -Flying to a point - Goto ------------------------- +Flying to a point - simple_goto +------------------------------- The vehicle is already in ``GUIDED`` mode, so to send it to a certain point we just need to call :py:func:`Vehicle.simple_goto() ` with the target @@ -159,7 +155,7 @@ attribute. For the second point the example specifies the target groundspeed whe RTL - Return to launch ------------------------- +---------------------- To return to the home position and land, we set the mode to ``RTL``. The vehicle travels at the previously set default speed: diff --git a/examples/simple_goto/simple_goto.py b/examples/simple_goto/simple_goto.py index 231616606..b2e581dc2 100644 --- a/examples/simple_goto/simple_goto.py +++ b/examples/simple_goto/simple_goto.py @@ -12,15 +12,29 @@ #Set up option parsing to get connection string import argparse -parser = argparse.ArgumentParser(description='Print out vehicle state information. Connects to SITL on local PC by default.') -parser.add_argument('--connect', default='127.0.0.1:14550', - help="vehicle connection target. Default '127.0.0.1:14550'") +parser = argparse.ArgumentParser(description='Commands vehicle using vehicle.simple_goto.') +parser.add_argument('--connect', + help="Vehicle connection target string. If not specified, SITL automatically started and used.") args = parser.parse_args() +connection_string = args.connect +sitl = None + + +#Start SITL if no connection string specified +if not args.connect: + print "Starting copter simulator (SITL)" + from dronekit_sitl import SITL + sitl = SITL() + sitl.download('copter', '3.3', verbose=True) + sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] + sitl.launch(sitl_args, await_ready=True, restart=True) + connection_string = 'tcp:127.0.0.1:5760' + # Connect to the Vehicle -print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, wait_ready=True) +print 'Connecting to vehicle on: %s' % connection_string +vehicle = connect(connection_string, wait_ready=True) def arm_and_takeoff(aTargetAltitude): @@ -37,8 +51,8 @@ def arm_and_takeoff(aTargetAltitude): print "Arming motors" # Copter should arm in GUIDED mode - vehicle.mode = VehicleMode("GUIDED") - vehicle.armed = True + vehicle.mode = VehicleMode("GUIDED") + vehicle.armed = True # Confirm vehicle armed before attempting to take off while not vehicle.armed: @@ -61,7 +75,7 @@ def arm_and_takeoff(aTargetAltitude): arm_and_takeoff(10) print "Set default/target airspeed to 3" -vehicle.airspeed=3 +vehicle.airspeed = 3 print "Going towards first point for 30 seconds ..." point1 = LocationGlobalRelative(-35.361354, 149.165218, 20) @@ -78,8 +92,12 @@ def arm_and_takeoff(aTargetAltitude): time.sleep(30) print "Returning to Launch" -vehicle.mode = VehicleMode("RTL") +vehicle.mode = VehicleMode("RTL") #Close vehicle object before exiting script print "Close vehicle object" vehicle.close() + +# Shut down simulator if it was started. +if sitl is not None: + sitl.stop() From 86761010d1e9952fea6dbc7a011ab568b7f4975d Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 10 Feb 2016 13:43:18 +1100 Subject: [PATCH 289/475] Update channel_overrides example to use dronekit-sitl by default --- docs/examples/channel_overrides.rst | 102 +++++++++--------- .../channel_overrides/channel_overrides.py | 28 ++++- 2 files changed, 74 insertions(+), 56 deletions(-) diff --git a/docs/examples/channel_overrides.rst b/docs/examples/channel_overrides.rst index 2b043225a..8c95143f9 100644 --- a/docs/examples/channel_overrides.rst +++ b/docs/examples/channel_overrides.rst @@ -35,65 +35,65 @@ In summary, after cloning the repository: cd dronekit-python/examples/channel_overrides/ -#. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: +#. You can run the example against a simulator (DroneKit-SITL) by specifying the Python script without any arguments. + The example will download SITL binaries (if needed), start the simulator, and then connect to it: .. code-block:: bash - python channel_overrides.py --connect 127.0.0.1:14550 + python channel_overrides.py - .. note:: + On the command prompt you should see (something like): - The ``--connect`` parameter above connects to SITL on udp port 127.0.0.1:14550. - This is the default value for the parameter, and may be omitted. - - - -On the command prompt you should see (something like): - -.. code:: bash - - Connecting to vehicle on: 170.0.0.1:14550 - >>> APM:Copter V3.3 (d6053245) - >>> Frame: QUAD - >>> Calibrating barometer - >>> Initialising APM... - >>> barometer calibration complete - >>> GROUND START - Channel values from RC Tx: {'1': 1500, '3': 1000, '2': 1500, '5': 1800, '4': 1500, '7': 1000, '6': 1000, '8': 1800} - Read channels individually: - Ch1: 1500 - Ch2: 1500 - Ch3: 1000 - Ch4: 1500 - Ch5: 1800 - Ch6: 1000 - Ch7: 1000 - Ch8: 1800 - Number of channels: 8 - - Channel overrides: {} - Set Ch2 override to 200 (indexing syntax) - Channel overrides: {'2': 200} - Ch2 override: 200 - Set Ch3 override to 300 (dictionary syntax) - Channel overrides: {'3': 300} - Set Ch1-Ch8 overrides to 110-810 respectively - Channel overrides: {'1': 110, '3': 310, '2': 210, '5': 510, '4': 4100, '7': 710, '6': 610, '8': 810} - - Cancel Ch2 override (indexing syntax) - Channel overrides: {'1': 110, '3': 310, '5': 510, '4': 4100, '7': 710, '6': 610, '8': 810} - Clear Ch3 override (del syntax) - Channel overrides: {'1': 110, '5': 510, '4': 4100, '7': 710, '6': 610, '8': 810} - Clear Ch5, Ch6 override and set channel 3 to 500 (dictionary syntax) - Channel overrides: {'3': 500} - Clear all overrides - Channel overrides: {} - - Close vehicle object - Completed + .. code:: bash + + Starting copter simulator (SITL) + SITL already Downloaded. + Connecting to vehicle on: tcp:127.0.0.1:5760 + >>> APM:Copter V3.3 (d6053245) + >>> Frame: QUAD + >>> Calibrating barometer + >>> Initialising APM... + >>> barometer calibration complete + >>> GROUND START + Channel values from RC Tx: {'1': 1500, '3': 1000, '2': 1500, '5': 1800, '4': 1500, '7': 1000, '6': 1000, '8': 1800} + Read channels individually: + Ch1: 1500 + Ch2: 1500 + Ch3: 1000 + Ch4: 1500 + Ch5: 1800 + Ch6: 1000 + Ch7: 1000 + Ch8: 1800 + Number of channels: 8 + Channel overrides: {} + Set Ch2 override to 200 (indexing syntax) + Channel overrides: {'2': 200} + Ch2 override: 200 + Set Ch3 override to 300 (dictionary syntax) + Channel overrides: {'3': 300} + Set Ch1-Ch8 overrides to 110-810 respectively + Channel overrides: {'1': 110, '3': 310, '2': 210, '5': 510, '4': 4100, '7': 710, '6': 610, '8': 810} + Cancel Ch2 override (indexing syntax) + Channel overrides: {'1': 110, '3': 310, '5': 510, '4': 4100, '7': 710, '6': 610, '8': 810} + Clear Ch3 override (del syntax) + Channel overrides: {'1': 110, '5': 510, '4': 4100, '7': 710, '6': 610, '8': 810} + Clear Ch5, Ch6 override and set channel 3 to 500 (dictionary syntax) + Channel overrides: {'3': 500} + Clear all overrides + Channel overrides: {} + Close vehicle object + Completed + +#. You can run the example against a specific connection (simulated or otherwise) by passing the :ref:`connection string ` for your vehicle in the ``--connect`` parameter. + + For example, to connect to SITL running on UDP port 14550 on your local computer: + .. code-block:: bash + python channel_overrides.py --connect 127.0.0.1:14550 + How does it work? ================= diff --git a/examples/channel_overrides/channel_overrides.py b/examples/channel_overrides/channel_overrides.py index cecd9943f..424733a23 100644 --- a/examples/channel_overrides/channel_overrides.py +++ b/examples/channel_overrides/channel_overrides.py @@ -17,15 +17,29 @@ #Set up option parsing to get connection string import argparse -parser = argparse.ArgumentParser(description='Example showing how to set and clear vehicle channel-override information. Connects to SITL on local PC by default.') -parser.add_argument('--connect', default='127.0.0.1:14550', - help="vehicle connection target. Default '127.0.0.1:14550'") +parser = argparse.ArgumentParser(description='Example showing how to set and clear vehicle channel-override information.') +parser.add_argument('--connect', + help="vehicle connection target string. If not specified, SITL automatically started and used.") args = parser.parse_args() +connection_string = args.connect +sitl = None + + +#Start SITL if no connection string specified +if not args.connect: + print "Starting copter simulator (SITL)" + from dronekit_sitl import SITL + sitl = SITL() + sitl.download('copter', '3.3', verbose=True) + sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] + sitl.launch(sitl_args, await_ready=True, restart=True) + connection_string = 'tcp:127.0.0.1:5760' + # Connect to the Vehicle -print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, wait_ready=True) +print 'Connecting to vehicle on: %s' % connection_string +vehicle = connect(connection_string, wait_ready=True) # Get all original channel values (before override) print "Channel values from RC Tx:", vehicle.channels @@ -81,4 +95,8 @@ print "\nClose vehicle object" vehicle.close() +# Shut down simulator if it was started. +if sitl is not None: + sitl.stop() + print("Completed") From c78511697439dd48761570b76cfb2f64d827efd0 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 9 Feb 2016 21:24:01 +1100 Subject: [PATCH 290/475] Update create_attribute example to use dk-sitl by default Improve code for closing sitl in examples --- docs/examples/create_attribute.rst | 83 +++++++++++-------- examples/create_attribute/create_attribute.py | 33 ++++++-- examples/create_attribute/my_vehicle.py | 2 +- 3 files changed, 74 insertions(+), 44 deletions(-) diff --git a/docs/examples/create_attribute.rst b/docs/examples/create_attribute.rst index 0fac3e234..0f83b22f2 100644 --- a/docs/examples/create_attribute.rst +++ b/docs/examples/create_attribute.rst @@ -41,48 +41,59 @@ In summary, after cloning the repository: cd dronekit-python\examples\create_attribute\ +#. You can run the example against a simulator (DroneKit-SITL) by specifying the Python script without any arguments. + The example will download SITL binaries (if needed), start the simulator, and then connect to it: -#. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: + .. code-block:: bash + + python create_attribute.py + + On the command prompt you should see (something like): + + .. code:: bash + + Starting copter simulator (SITL) + SITL already Downloaded. + Connecting to vehicle on: tcp:127.0.0.1:5760 + >>> APM:Copter V3.3 (d6053245) + >>> Frame: QUAD + >>> Calibrating barometer + >>> Initialising APM... + >>> barometer calibration complete + >>> GROUND START + Display RAW_IMU messages for 5 seconds and then exit. + RAW_IMU: time_boot_us=15340000,xacc=0,yacc=0,zacc=-1000,xgyro=0,ygyro=1,zgyro=0,xmag=161,ymag=19,zmag=-365 + RAW_IMU: time_boot_us=15580000,xacc=0,yacc=0,zacc=-1000,xgyro=0,ygyro=0,zgyro=0,xmag=161,ymag=19,zmag=-365 + RAW_IMU: time_boot_us=15820000,xacc=0,yacc=0,zacc=-999,xgyro=0,ygyro=1,zgyro=0,xmag=161,ymag=19,zmag=-365 + RAW_IMU: time_boot_us=16060000,xacc=0,yacc=1,zacc=-999,xgyro=0,ygyro=0,zgyro=0,xmag=161,ymag=19,zmag=-365 + RAW_IMU: time_boot_us=16300000,xacc=0,yacc=0,zacc=-999,xgyro=0,ygyro=0,zgyro=0,xmag=161,ymag=19,zmag=-365 + RAW_IMU: time_boot_us=16540000,xacc=0,yacc=0,zacc=-1000,xgyro=0,ygyro=1,zgyro=0,xmag=161,ymag=19,zmag=-365 + RAW_IMU: time_boot_us=16780000,xacc=0,yacc=0,zacc=-999,xgyro=0,ygyro=0,zgyro=0,xmag=161,ymag=19,zmag=-365 + RAW_IMU: time_boot_us=17020000,xacc=1,yacc=0,zacc=-999,xgyro=0,ygyro=0,zgyro=0,xmag=161,ymag=19,zmag=-365 + RAW_IMU: time_boot_us=17260000,xacc=0,yacc=0,zacc=-999,xgyro=0,ygyro=0,zgyro=0,xmag=161,ymag=19,zmag=-365 + RAW_IMU: time_boot_us=17500000,xacc=0,yacc=0,zacc=-1000,xgyro=1,ygyro=0,zgyro=0,xmag=161,ymag=19,zmag=-365 + RAW_IMU: time_boot_us=17740000,xacc=0,yacc=0,zacc=-999,xgyro=0,ygyro=0,zgyro=0,xmag=161,ymag=19,zmag=-365 + RAW_IMU: time_boot_us=17980000,xacc=0,yacc=0,zacc=-999,xgyro=0,ygyro=0,zgyro=0,xmag=161,ymag=19,zmag=-365 + RAW_IMU: time_boot_us=18220000,xacc=0,yacc=0,zacc=-1000,xgyro=0,ygyro=0,zgyro=1,xmag=161,ymag=19,zmag=-365 + RAW_IMU: time_boot_us=18460000,xacc=0,yacc=0,zacc=-1000,xgyro=0,ygyro=0,zgyro=0,xmag=161,ymag=19,zmag=-365 + RAW_IMU: time_boot_us=18700000,xacc=0,yacc=0,zacc=-999,xgyro=0,ygyro=0,zgyro=0,xmag=161,ymag=19,zmag=-365 + RAW_IMU: time_boot_us=18940000,xacc=1,yacc=0,zacc=-1000,xgyro=0,ygyro=1,zgyro=0,xmag=161,ymag=19,zmag=-365 + RAW_IMU: time_boot_us=19180000,xacc=1,yacc=0,zacc=-1000,xgyro=0,ygyro=0,zgyro=0,xmag=161,ymag=19,zmag=-365 + RAW_IMU: time_boot_us=19420000,xacc=0,yacc=0,zacc=-999,xgyro=0,ygyro=0,zgyro=0,xmag=161,ymag=19,zmag=-365 + RAW_IMU: time_boot_us=19660000,xacc=0,yacc=0,zacc=-1000,xgyro=0,ygyro=0,zgyro=0,xmag=154,ymag=52,zmag=-365 + RAW_IMU: time_boot_us=19900000,xacc=0,yacc=0,zacc=-999,xgyro=0,ygyro=0,zgyro=0,xmag=154,ymag=52,zmag=-365 + RAW_IMU: time_boot_us=20140000,xacc=0,yacc=0,zacc=-1000,xgyro=0,ygyro=0,zgyro=0,xmag=154,ymag=52,zmag=-365 + Close vehicle object + + +#. You can run the example against a specific connection (simulated or otherwise) by passing the :ref:`connection string ` for your vehicle in the ``--connect`` parameter. + + For example, to connect to SITL running on UDP port 14550 on your local computer: .. code-block:: bash python create_attribute.py --connect 127.0.0.1:14550 - .. note:: - - The ``--connect`` parameter above connects to SITL on udp port 127.0.0.1:14550. - This is the default value for the parameter, and may be omitted. - - - -On the command prompt you should see (something like): - -.. code:: bash - - Connecting to vehicle on: tcp:127.0.0.1:14550 - >>> APM:Copter V3.3 (d6053245) - >>> Frame: QUAD - Display RAW_IMU messages for 5 seconds and then exit. - RAW_IMU: time_boot_us=1593318928,xacc=-3,yacc=5,zacc=-999,xgyro=0,ygyro=0,zgyro=0,xmag=156,ymag=41,zmag=-365 - RAW_IMU: time_boot_us=1593558928,xacc=-4,yacc=5,zacc=-1000,xgyro=0,ygyro=1,zgyro=1,xmag=156,ymag=41,zmag=-365 - RAW_IMU: time_boot_us=1593798928,xacc=-2,yacc=6,zacc=-1000,xgyro=1,ygyro=0,zgyro=0,xmag=156,ymag=41,zmag=-365 - RAW_IMU: time_boot_us=1594038928,xacc=-2,yacc=6,zacc=-1000,xgyro=1,ygyro=1,zgyro=1,xmag=156,ymag=41,zmag=-365 - RAW_IMU: time_boot_us=1594278928,xacc=-2,yacc=5,zacc=-999,xgyro=0,ygyro=1,zgyro=1,xmag=156,ymag=41,zmag=-365 - RAW_IMU: time_boot_us=1594518928,xacc=-2,yacc=4,zacc=-998,xgyro=1,ygyro=1,zgyro=1,xmag=156,ymag=41,zmag=-365 - RAW_IMU: time_boot_us=1594758928,xacc=-3,yacc=5,zacc=-1000,xgyro=0,ygyro=1,zgyro=0,xmag=156,ymag=41,zmag=-365 - RAW_IMU: time_boot_us=1594998928,xacc=-2,yacc=4,zacc=-999,xgyro=1,ygyro=0,zgyro=0,xmag=156,ymag=41,zmag=-365 - RAW_IMU: time_boot_us=1595238928,xacc=-3,yacc=5,zacc=-1000,xgyro=0,ygyro=1,zgyro=1,xmag=156,ymag=41,zmag=-365 - RAW_IMU: time_boot_us=1595478928,xacc=-2,yacc=4,zacc=-1000,xgyro=1,ygyro=0,zgyro=0,xmag=156,ymag=41,zmag=-365 - RAW_IMU: time_boot_us=1595718928,xacc=-2,yacc=4,zacc=-999,xgyro=0,ygyro=1,zgyro=0,xmag=156,ymag=41,zmag=-365 - RAW_IMU: time_boot_us=1595958928,xacc=-3,yacc=6,zacc=-1000,xgyro=0,ygyro=1,zgyro=1,xmag=156,ymag=41,zmag=-365 - RAW_IMU: time_boot_us=1596198928,xacc=-4,yacc=6,zacc=-1000,xgyro=1,ygyro=1,zgyro=1,xmag=156,ymag=41,zmag=-365 - RAW_IMU: time_boot_us=1596438928,xacc=-2,yacc=6,zacc=-1000,xgyro=0,ygyro=1,zgyro=0,xmag=156,ymag=41,zmag=-365 - RAW_IMU: time_boot_us=1596678928,xacc=-3,yacc=4,zacc=-999,xgyro=1,ygyro=0,zgyro=0,xmag=156,ymag=41,zmag=-365 - RAW_IMU: time_boot_us=1596918928,xacc=-2,yacc=4,zacc=-999,xgyro=0,ygyro=1,zgyro=0,xmag=156,ymag=41,zmag=-365 - RAW_IMU: time_boot_us=1597158928,xacc=-2,yacc=6,zacc=-1000,xgyro=0,ygyro=1,zgyro=1,xmag=156,ymag=41,zmag=-365 - RAW_IMU: time_boot_us=1597398928,xacc=-2,yacc=5,zacc=-1000,xgyro=0,ygyro=1,zgyro=0,xmag=156,ymag=41,zmag=-365 - RAW_IMU: time_boot_us=1597638928,xacc=-3,yacc=5,zacc=-1000,xgyro=1,ygyro=0,zgyro=0,xmag=156,ymag=41,zmag=-365 - Close vehicle object diff --git a/examples/create_attribute/create_attribute.py b/examples/create_attribute/create_attribute.py index 8b7e516c1..3fce5693a 100644 --- a/examples/create_attribute/create_attribute.py +++ b/examples/create_attribute/create_attribute.py @@ -1,7 +1,7 @@ """ create_attribute.py: -Demonstrates how to create attributes for MAVLink messages within your DroneKit-Python script +Demonstrates how to create attributes from MAVLink messages within your DroneKit-Python script and use them in the same way as the built-in Vehicle attributes. The code adds a new attribute to the Vehicle class, populating it with information from RAW_IMU messages @@ -18,14 +18,29 @@ #Set up option parsing to get connection string import argparse -parser = argparse.ArgumentParser(description='Print out vehicle state information. Connects to SITL on local PC by default.') -parser.add_argument('--connect', default='127.0.0.1:14550', - help="vehicle connection target. Default '127.0.0.1:14550'") +parser = argparse.ArgumentParser(description='Demonstrates how to create attributes from MAVLink messages. ') +parser.add_argument('--connect', + help="Vehicle connection target string. If not specified, SITL automatically started and used.") args = parser.parse_args() -# Connect to our custom vehicle_class MyVehicle -print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, wait_ready=True, vehicle_class=MyVehicle) +connection_string = args.connect +sitl = None + + +#Start SITL if no connection string specified +if not args.connect: + print "Starting copter simulator (SITL)" + from dronekit_sitl import SITL + sitl = SITL() + sitl.download('copter', '3.3', verbose=True) + sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] + sitl.launch(sitl_args, await_ready=True, restart=True) + connection_string = 'tcp:127.0.0.1:5760' + + +# Connect to the Vehicle +print 'Connecting to vehicle on: %s' % connection_string +vehicle = connect(connection_string, wait_ready=True, vehicle_class=MyVehicle) # Add observer for the custom attribute @@ -44,3 +59,7 @@ def raw_imu_callback(self, attr_name, value): #Close vehicle object before exiting script print "Close vehicle object" vehicle.close() + +# Shut down simulator if it was started. +if sitl is not None: + sitl.stop() diff --git a/examples/create_attribute/my_vehicle.py b/examples/create_attribute/my_vehicle.py index 6a1b31c99..2b56a352e 100644 --- a/examples/create_attribute/my_vehicle.py +++ b/examples/create_attribute/my_vehicle.py @@ -77,7 +77,7 @@ def listener(self, name, message): # Notify all observers of new message (with new value) # Note that argument `cache=False` by default so listeners - # are updaed with every new message + # are updated with every new message self.notify_attribute_listeners('raw_imu', self._raw_imu) @property From d436bf37241fd2ea7357f02d2560d010efa73f64 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 10 Feb 2016 12:03:42 +1100 Subject: [PATCH 291/475] Update follow_me example to use dk-sitl by default --- docs/examples/follow_me.rst | 80 +++++++++++++++++---------------- examples/follow_me/follow_me.py | 32 ++++++++++--- 2 files changed, 67 insertions(+), 45 deletions(-) diff --git a/docs/examples/follow_me.rst b/docs/examples/follow_me.rst index f51319a43..532c362b9 100644 --- a/docs/examples/follow_me.rst +++ b/docs/examples/follow_me.rst @@ -51,54 +51,58 @@ Once you've done that: cd dronekit-python/examples/follow_me/ -#. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: +#. You can run the example against a simulator (DroneKit-SITL) by specifying the Python script without any arguments. + The example will download SITL binaries (if needed), start the simulator, and then connect to it: .. code-block:: bash - python follow_me.py --connect 127.0.0.1:14550 - + python follow_me.py - .. note:: + On the command prompt you should see (something like): - The examples uses the ``--connect`` parameter to pass the :ref:`connection string ` into the script. - The command above is used to connect to :ref:`SITL ` running on the local Linux machine via UDP port 14550. + .. code:: bash + + Starting copter simulator (SITL) + SITL already Downloaded. + Connecting to vehicle on: tcp:127.0.0.1:5760 + >>> APM:Copter V3.4-dev (e0810c2e) + >>> Frame: QUAD + Link timeout, no heartbeat in last 5 seconds + Basic pre-arm checks + Waiting for GPS...: None + ... + Waiting for GPS...: None + Taking off! + Altitude: 0.019999999553 + ... + Altitude: 4.76000022888 + Reached target altitude + Going to: Location:lat=50.616468333,lon=7.131903333,alt=30,is_relative=True + ... + Going to: Location:lat=50.616468333,lon=7.131903333,alt=30,is_relative=True + Going to: Location:lat=50.616468333,lon=7.131903333,alt=30,is_relative=True + User has changed flight modes - aborting follow-me + Close vehicle object + Completed + + .. note:: + The terminal output above was created using simulated GPS data + (which is why the same target location is returned every time). + + To stop follow-me you can change the vehicle mode or do Ctrl+C + (on a real flight you can just change the mode switch on your + RC transmitter). + -On the terminal you should see (something like): +#. You can run the example against a specific connection (simulated or otherwise) by passing the :ref:`connection string ` for your vehicle in the ``--connect`` parameter. + For example, to connect to SITL running on UDP port 14550 on your local computer: -.. code-block:: bash - - Connecting to vehicle on: 127.0.0.1:14550 - >>> APM:Copter V3.4-dev (e0810c2e) - >>> Frame: QUAD - Link timeout, no heartbeat in last 5 seconds - Basic pre-arm checks - Waiting for GPS...: None - ... - Waiting for GPS...: None - Taking off! - Altitude: 0.019999999553 - ... - Altitude: 4.76000022888 - Reached target altitude - Going to: Location:lat=50.616468333,lon=7.131903333,alt=30,is_relative=True - ... - Going to: Location:lat=50.616468333,lon=7.131903333,alt=30,is_relative=True - Going to: Location:lat=50.616468333,lon=7.131903333,alt=30,is_relative=True - User has changed flight modes - aborting follow-me - Close vehicle object - Completed - - -To stop follow-me you can change the vehicle mode (on a real flight you can just change the mode switch on your RC transmitter). - -.. note:: + .. code-block:: bash - The terminal output above was created using simulated GPS data - (which is why the same target location is returned every time). It was exited by changing - the mode from GUIDED to STABILIZE using MAVProxy. - + python follow_me.py --connect 127.0.0.1:14550 + How does it work? diff --git a/examples/follow_me/follow_me.py b/examples/follow_me/follow_me.py index 581c5c0c4..b62b32a5f 100644 --- a/examples/follow_me/follow_me.py +++ b/examples/follow_me/follow_me.py @@ -18,15 +18,29 @@ #Set up option parsing to get connection string import argparse -parser = argparse.ArgumentParser(description='Tracks GPS position of your computer (Linux only). Connects to SITL on local PC by default.') -parser.add_argument('--connect', default='127.0.0.1:14550', - help="vehicle connection target. Default '127.0.0.1:14550'") +parser = argparse.ArgumentParser(description='Tracks GPS position of your computer (Linux only).') +parser.add_argument('--connect', + help="vehicle connection target string. If not specified, SITL automatically started and used.") args = parser.parse_args() +connection_string = args.connect +sitl = None + + +#Start SITL if no connection string specified +if not args.connect: + print "Starting copter simulator (SITL)" + from dronekit_sitl import SITL + sitl = SITL() + sitl.download('copter', '3.3', verbose=True) + sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] + sitl.launch(sitl_args, await_ready=True, restart=True) + connection_string = 'tcp:127.0.0.1:5760' + # Connect to the Vehicle -print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, wait_ready=True) +print 'Connecting to vehicle on: %s' % connection_string +vehicle = connect(connection_string, wait_ready=True) @@ -44,8 +58,8 @@ def arm_and_takeoff(aTargetAltitude): print "Arming motors" # Copter should arm in GUIDED mode - vehicle.mode = VehicleMode("GUIDED") - vehicle.armed = True + vehicle.mode = VehicleMode("GUIDED") + vehicle.armed = True while not vehicle.armed: print " Waiting for arming..." @@ -102,4 +116,8 @@ def arm_and_takeoff(aTargetAltitude): print "Close vehicle object" vehicle.close() +# Shut down simulator if it was started. +if sitl is not None: + sitl.stop() + print("Completed") From 533c14f3c5d7f563d38f5340561b1444d1357452 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 9 Feb 2016 20:46:30 +1100 Subject: [PATCH 292/475] Update mission_basic.py example to use dk-sitl by default --- docs/examples/mission_basic.rst | 157 +++++++++++------------- examples/mission_basic/mission_basic.py | 46 ++++--- 2 files changed, 105 insertions(+), 98 deletions(-) diff --git a/docs/examples/mission_basic.rst b/docs/examples/mission_basic.rst index c7af9ba73..a37afc571 100644 --- a/docs/examples/mission_basic.rst +++ b/docs/examples/mission_basic.rst @@ -24,9 +24,6 @@ Running the example The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle and DroneKit have been set up as described in :ref:`installing_dronekit`). - -If you're using a simulated vehicle, remember to :ref:`disable arming checks ` so -that the example can run. In summary, after cloning the repository: @@ -36,92 +33,86 @@ In summary, after cloning the repository: cd dronekit-python/examples/mission_basic/ - -#. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: +#. You can run the example against a simulator (DroneKit-SITL) by specifying the Python script without any arguments. + The example will download SITL binaries (if needed), start the simulator, and then connect to it: .. code-block:: bash - python mission_basic.py --connect 127.0.0.1:14550 + python mission_basic.py - .. note:: + On the command prompt you should see (something like): - The ``--connect`` parameter above connects to SITL on udp port 127.0.0.1:14550. - This is the default value for the parameter, and may be omitted. - + .. code:: bash + + Starting copter simulator (SITL) + SITL already Downloaded. + Connecting to vehicle on: tcp:127.0.0.1:5760 + >>> APM:Copter V3.3 (d6053245) + >>> Frame: QUAD + >>> Calibrating barometer + >>> Initialising APM... + >>> barometer calibration complete + >>> GROUND START + >>> Mission Planner 1.3.35 + Create a new mission (for current location) + Clear any existing commands + Define/add new commands. + Upload new commands to vehicle + Basic pre-arm checks + Waiting for vehicle to initialise... + >>> flight plan received + Waiting for vehicle to initialise... + ... + Waiting for vehicle to initialise... + Arming motors + Waiting for arming... + ... + Waiting for arming... + >>> ARMING MOTORS + >>> GROUND START + Waiting for arming... + >>> Initialising APM... + Taking off! + Altitude: 0.0 + Altitude: 0.11 + ... + Altitude: 8.9 + Altitude: 9.52 + Reached target altitude + Starting mission + Distance to waypoint (0): None + Distance to waypoint (1): 78.8000191616 + Distance to waypoint (1): 78.3723704927 + ... + Distance to waypoint (1): 20.7131390269 + Distance to waypoint (1): 15.4196151863 + >>> Reached Command #1 + Distance to waypoint (2): 115.043560356 + Distance to waypoint (2): 117.463458185 + ... + Distance to waypoint (2): 25.7122243168 + Distance to waypoint (2): 16.8624794106 + >>> Reached Command #2 + Distance to waypoint (3): 100.45231832 + Skipping to Waypoint 5 when reach waypoint 3 + Distance to waypoint (5): 154.645144788 + Exit 'standard' mission when start heading to final waypoint (5) + Return to launch + Close vehicle object + + + .. tip:: + + It is more interesting to watch the example run on a map than the console. The topic :ref:`viewing_uav_on_map` + explains how to set up *Mission Planner* to view a vehicle running on the simulator (SITL). -.. tip:: - - It is more interesting to watch the example above on a map than the console. The topic :ref:`viewing_uav_on_map` - explains how to set up *Mission Planner* to view a vehicle running on the simulator (SITL). - - -On the command prompt you should see (something like): - -.. code:: bash - - Connecting to vehicle on: 127.0.0.1:14550 - >>> APM:Copter V3.4-dev (e0810c2e) - >>> Frame: QUAD - Create a new mission - Clear any existing commands - Define/add new commands. - Upload new commands to vehicle - Basic pre-arm checks - MODE: STABILIZE - Arming motors - Waiting for arming... - >>> flight plan received - Waiting for arming... - Waiting for arming... - >>> ARMING MOTORS - >>> GROUND START - Waiting for arming... - Waiting for arming... - >>> Initialising APM... - Taking off! - Altitude: 0.0 - Altitude: 0.170000001788 - Altitude: 1.37000000477 - ... - Altitude: 8.98999977112 - Altitude: 9.64000034332 - Reached target altitude - Starting mission - Distance to waypoint (0): None - Distance to waypoint (1): 78.8589586333 - Distance to waypoint (1): 78.4539918222 - ... - Distance to waypoint (1): 21.1854880899 - Distance to waypoint (1): 15.9962142785 - >>> Reached Command #1 - Distance to waypoint (2): 114.244008966 - Distance to waypoint (2): 117.552371221 - Distance to waypoint (2): 120.961820592 - ... - Distance to waypoint (2): 25.2782487833 - Distance to waypoint (2): 19.3676312264 - >>> Reached Command #2 - Distance to waypoint (3): 101.094964838 - Skipping to Waypoint 5 when reach waypoint 3 - Distance to waypoint (3): 100.297254801 - Skipping to Waypoint 5 when reach waypoint 3 - ... - Distance to waypoint (3): 19.3298648648 - Skipping to Waypoint 5 when reach waypoint 3 - Distance to waypoint (3): 14.5179746603 - Skipping to Waypoint 5 when reach waypoint 3 - >>> Reached Command #3 - Distance to waypoint (4): 123.867292399 - Distance to waypoint (4): 123.019536579 - Distance to waypoint (4): 121.278259418 - ... - Distance to waypoint (4): 27.7386666676 - Distance to waypoint (4): 20.3805334778 - >>> Reached Command #4 - Distance to waypoint (5): 14.5141106814 - Exit 'standard' mission when start heading to final waypoint (5) - Return to launch - Close vehicle object +#. You can run the example against a specific connection (simulated or otherwise) by passing the :ref:`connection string ` for your vehicle in the ``--connect`` parameter. + + For example, to connect to SITL running on UDP port 14550 on your local computer: + + .. code-block:: bash + + python mission_basic.py --connect 127.0.0.1:14550 diff --git a/examples/mission_basic/mission_basic.py b/examples/mission_basic/mission_basic.py index e811ff859..d98f85af9 100644 --- a/examples/mission_basic/mission_basic.py +++ b/examples/mission_basic/mission_basic.py @@ -12,15 +12,29 @@ #Set up option parsing to get connection string import argparse -parser = argparse.ArgumentParser(description='Example which runs basic mission operations. Connects to SITL on local PC by default.') -parser.add_argument('--connect', default='127.0.0.1:14550', - help="vehicle connection target. Default '127.0.0.1:14550'") +parser = argparse.ArgumentParser(description='Demonstrates basic mission operations.') +parser.add_argument('--connect', + help="vehicle connection target string. If not specified, SITL automatically started and used.") args = parser.parse_args() +connection_string = args.connect +sitl = None + + +#Start SITL if no connection string specified +if not args.connect: + print "Starting copter simulator (SITL)" + from dronekit_sitl import SITL + sitl = SITL() + sitl.download('copter', '3.3', verbose=True) + sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] + sitl.launch(sitl_args, await_ready=True, restart=True) + connection_string='tcp:127.0.0.1:5760' + # Connect to the Vehicle -print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, wait_ready=True) +print 'Connecting to vehicle on: %s' % connection_string +vehicle = connect(connection_string, wait_ready=True) def get_location_metres(original_location, dNorth, dEast): @@ -65,14 +79,14 @@ def distance_to_current_waypoint(): Gets distance in metres to the current waypoint. It returns None for the first waypoint (Home location). """ - nextwaypoint=vehicle.commands.next - if nextwaypoint ==0: + nextwaypoint = vehicle.commands.next + if nextwaypoint==0: return None missionitem=vehicle.commands[nextwaypoint-1] #commands are zero indexed - lat=missionitem.x - lon=missionitem.y - alt=missionitem.z - targetWaypointLocation=LocationGlobalRelative(lat,lon,alt) + lat = missionitem.x + lon = missionitem.y + alt = missionitem.z + targetWaypointLocation = LocationGlobalRelative(lat,lon,alt) distancetopoint = get_distance_metres(vehicle.location.global_frame, targetWaypointLocation) return distancetopoint @@ -137,8 +151,8 @@ def arm_and_takeoff(aTargetAltitude): print "Arming motors" # Copter should arm in GUIDED mode - vehicle.mode = VehicleMode("GUIDED") - vehicle.armed = True + vehicle.mode = VehicleMode("GUIDED") + vehicle.armed = True while not vehicle.armed: print " Waiting for arming..." @@ -183,7 +197,7 @@ def arm_and_takeoff(aTargetAltitude): if nextwaypoint==3: #Skip to next waypoint print 'Skipping to Waypoint 5 when reach waypoint 3' - vehicle.commands.next=5 + vehicle.commands.next = 5 if nextwaypoint==5: #Dummy waypoint - as soon as we reach waypoint 4 this is true and we exit. print "Exit 'standard' mission when start heading to final waypoint (5)" break; @@ -197,4 +211,6 @@ def arm_and_takeoff(aTargetAltitude): print "Close vehicle object" vehicle.close() - +# Shut down simulator if it was started. +if sitl is not None: + sitl.stop() From 729dc9acf14453f12343b4f8b3f02063c00cffff Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 9 Feb 2016 20:23:58 +1100 Subject: [PATCH 293/475] Update guided example to use dronekit-sitl by default --- docs/examples/guided-set-speed-yaw-demo.rst | 245 +++++++++--------- .../guided_set_speed_yaw.py | 71 +++-- 2 files changed, 174 insertions(+), 142 deletions(-) diff --git a/docs/examples/guided-set-speed-yaw-demo.rst b/docs/examples/guided-set-speed-yaw-demo.rst index 86fbc65f8..49cefdf23 100644 --- a/docs/examples/guided-set-speed-yaw-demo.rst +++ b/docs/examples/guided-set-speed-yaw-demo.rst @@ -35,9 +35,6 @@ Running the example The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle and DroneKit have been set up as described in :ref:`installing_dronekit`). -If you're using a simulated vehicle, remember to :ref:`disable arming checks ` so -that the example can run. - In summary, after cloning the repository: #. Navigate to the example folder as shown: @@ -47,125 +44,137 @@ In summary, after cloning the repository: cd dronekit-python/examples/guided_set_speed_yaw/ -#. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: +#. You can run the example against a simulator (DroneKit-SITL) by specifying the Python script without any arguments. + The example will download SITL binaries if needed, start the simulator, and then connect to it: .. code-block:: bash - python guided_set_speed_yaw.py --connect 127.0.0.1:14550 + python guided_set_speed_yaw.py - .. note:: + On the command prompt you should see (something like): - The ``--connect`` parameter above connects to SITL on udp port 127.0.0.1:14550. - This is the default value for the parameter, and may be omitted. - + .. code:: bash + + Starting copter simulator (SITL) + SITL already Downloaded. + Connecting to vehicle on: tcp:127.0.0.1:5760 + >>> APM:Copter V3.3 (d6053245) + >>> Frame: QUAD + >>> Calibrating barometer + >>> Initialising APM... + >>> barometer calibration complete + >>> GROUND START + Basic pre-arm checks + Waiting for vehicle to initialise... + ... + Waiting for vehicle to initialise... + Arming motors + Waiting for arming... + ... + Waiting for arming... + >>> ARMING MOTORS + >>> GROUND START + Waiting for arming... + >>> Link timeout, no heartbeat in last 5 seconds + >>> ...link restored. + >>> Initialising APM... + Taking off! + Altitude: 0.0 + Altitude: 0.28 + ... + Altitude: 4.76 + Reached target altitude + TRIANGLE path using standard Vehicle.simple_goto() + Set groundspeed to 5m/s. + Position North 80 West 50 + Distance to target: 100.792763565 + Distance to target: 99.912599325 + ... + Distance to target: 1.21731863826 + Distance to target: 0.846001925791 + Reached target + Position North 0 East 100 + Distance to target: 122.623210813 + ... + Distance to target: 4.75876224557 + Distance to target: 0.244650555031 + Reached target + Position North -80 West 50 + Distance to target: 100.792430814 + Distance to target: 100.592652053 + ... + Distance to target: 2.48849019535 + Distance to target: 0.73822537077 + Reached target + TRIANGLE path using standard SET_POSITION_TARGET_GLOBAL_INT message and with varying speed. + Position South 100 West 130 + Set groundspeed to 5m/s. + Distance to target: 188.180927131 + Distance to target: 186.578341133 + ... + Distance to target: 9.87090024758 + Distance to target: 1.4668164732 + Reached target + Set groundspeed to 15m/s (max). + Position South 0 East 200 + Distance to target: 318.826732298 + Distance to target: 320.787965033 + ... + Distance to target: 11.5626483964 + Distance to target: 0.335164775811 + Reached target + Set airspeed to 10m/s (max). + Position North 100 West 130 + Distance to target: 188.182420209 + Distance to target: 189.860730713 + ... + Distance to target: 10.4263414971 + Distance to target: 1.29857175712 + Reached target + SQUARE path using SET_POSITION_TARGET_LOCAL_NED and position parameters + North 50m, East 0m, 10m altitude for 20 seconds + Point ROI at current location (home position) + North 50m, East 50m, 10m altitude + Point ROI at current location + North 0m, East 50m, 10m altitude + North 0m, East 0m, 10m altitude + SQUARE path using SET_POSITION_TARGET_LOCAL_NED and velocity parameters + Yaw 180 absolute (South) + Velocity South & up + Yaw 270 absolute (West) + Velocity West & down + Yaw 0 absolute (North) + Velocity North + Yaw 90 absolute (East) + Velocity East + DIAMOND path using SET_POSITION_TARGET_GLOBAL_INT and velocity parameters + Yaw 225 absolute + Velocity South, West and Up + Yaw 90 relative (to previous yaw heading) + Velocity North, West and Down + Set new home location to current location + Get new home location + Home Location: LocationGlobal:lat=-35.363243103,lon=149.164337158,alt=593.890014648 + Yaw 90 relative (to previous yaw heading) + Velocity North and East + Yaw 90 relative (to previous yaw heading) + Velocity South and East + Setting LAND mode... + Close vehicle object + Completed + + .. tip:: + + It is more interesting to watch the example run on a map than the console. The topic :ref:`viewing_uav_on_map` + explains how to set up *Mission Planner* to view a vehicle running on the simulator (SITL). -.. tip:: - - It is more interesting to watch the example above on a map than the console. The topic :ref:`viewing_uav_on_map` - explains how to set up *Mission Planner* to view a vehicle running on the simulator (SITL). - -On the command prompt you should see (something like): - - -.. code-block:: bash - - Basic pre-arm checks - Arming motors - Waiting for arming... - Waiting for arming... - Taking off! - Altitude: 0.00999999977648 - Altitude: 0.159999996424 - Altitude: 0.920000016689 - Altitude: 2.38000011444 - Altitude: 3.93000006676 - Altitude: 4.65000009537 - Altitude: 4.82999992371 - Reached target altitude - - TRIANGLE path using standard Vehicle.simple_goto() - Position North 80 West 50 - Distance to target: 100.792762965 - Distance to target: 100.25918006 - ... - Distance to target: 2.34237912414 - Distance to target: 0.308823685384 - Reached target - Position North 0 East 100 - Distance to target: 122.62321461 - ... - Distance to target: 5.39403923852 - Distance to target: 1.00445126117 - Reached target - Position North -80 West 50 - goto_target_globalint_position - Distance to target: 100.792430952 - Distance to target: 100.221083739 - ... - Distance to target: 1.69678155659 - Distance to target: 0.0798488767383 - Reached target - - TRIANGLE path using standard SET_POSITION_TARGET_GLOBAL_INT message and with varying speed. - Position South 100 West 130 - Set speed to 5m/s. - Distance to target: 181.439594672 - Distance to target: 132.170351744 - ... - Distance to target: 2.67615248028 - Distance to target: 0.382959594982 - Reached target - Set speed to 15m/s (max). - Position South 0 East 200 - Distance to target: 318.826739407 - Distance to target: 317.613357051 - ... - Distance to target: 3.5935761745 - Distance to target: 0.114090613451 - Reached target - Set speed to 10m/s (max). - Position North 100 West 130 - goto_target_globalint_position - Distance to target: 188.182423388 - Distance to target: 187.540272979 - ... - Distance to target: 4.82317050152 - Distance to target: 0.377390539948 - Reached target - - SQUARE path using SET_POSITION_TARGET_LOCAL_NED and position parameters - North 50m, East 0m, 10m altitude for 20 seconds - Point ROI at current location (home position) - North 50m, East 50m, 10m altitude - Point ROI at current location - North 0m, East 50m, 10m altitude - North 0m, East 0m, 10m altitude - - SQUARE path using SET_POSITION_TARGET_LOCAL_NED and velocity parameters - Velocity South & up - Yaw 180 absolute (South) - Velocity West & down - Yaw 270 absolute (West) - Velocity North - Yaw 0 absolute (North) - Velocity East - - DIAMOND path using SET_POSITION_TARGET_GLOBAL_INT and velocity parameters - Velocity North, East and up - Yaw 225 absolute - Velocity South, East and down - Yaw 90 relative (to previous yaw heading) - Set new Home location to current location - Get new home location - Home Location: LocationGlobal:lat=-35.3639335632,lon=149.165328979,alt=628.679992676,is_relative=False - Velocity South and West - Yaw 90 relative (to previous yaw heading) - Velocity North and West - Yaw 90 relative (to previous yaw heading) - - Setting LAND mode... - Close vehicle object - Completed +#. You can run the example against a specific connection (simulated or otherwise) by passing the :ref:`connection string ` for your vehicle in the ``--connect`` parameter. + + For example, to connect to SITL running on UDP port 14550 on your local computer: + + .. code-block:: bash + + python guided_set_speed_yaw.py --connect 127.0.0.1:14550 @@ -384,8 +393,8 @@ Testbed settings This example has been tested on Windows against SITL running both natively and in a virtual machine (as described in :ref:`installing_dronekit`). -* DroneKit version: 2.0.0rc12 -* ArduPilot version: 3.4.0. +* DroneKit version: 2.0.2 +* ArduPilot version: 3.3 diff --git a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py index 30bddb2e9..b81f0bb6f 100644 --- a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py +++ b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py @@ -15,15 +15,29 @@ #Set up option parsing to get connection string import argparse -parser = argparse.ArgumentParser(description='Print out vehicle state information. Connects to SITL on local PC by default.') -parser.add_argument('--connect', default='127.0.0.1:14550', - help="vehicle connection target. Default '127.0.0.1:14550'") +parser = argparse.ArgumentParser(description='Control Copter and send commands in GUIDED mode ') +parser.add_argument('--connect', + help="Vehicle connection target string. If not specified, SITL automatically started and used.") args = parser.parse_args() +connection_string = args.connect +sitl = None + + +#Start SITL if no connection string specified +if not args.connect: + print "Starting copter simulator (SITL)" + from dronekit_sitl import SITL + sitl = SITL() + sitl.download('copter', '3.3', verbose=True) + sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] + sitl.launch(sitl_args, await_ready=True, restart=True) + connection_string='tcp:127.0.0.1:5760' + # Connect to the Vehicle -print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, wait_ready=True) +print 'Connecting to vehicle on: %s' % connection_string +vehicle = connect(connection_string, wait_ready=True) def arm_and_takeoff(aTargetAltitude): @@ -40,8 +54,8 @@ def arm_and_takeoff(aTargetAltitude): print "Arming motors" # Copter should arm in GUIDED mode - vehicle.mode = VehicleMode("GUIDED") - vehicle.armed = True + vehicle.mode = VehicleMode("GUIDED") + vehicle.armed = True while not vehicle.armed: print " Waiting for arming..." @@ -93,9 +107,9 @@ def condition_yaw(heading, relative=False): http://copter.ardupilot.com/wiki/common-mavlink-mission-command-messages-mav_cmd/#mav_cmd_condition_yaw """ if relative: - is_relative=1 #yaw relative to direction of travel + is_relative = 1 #yaw relative to direction of travel else: - is_relative=0 #yaw is an absolute angle + is_relative = 0 #yaw is an absolute angle # create the CONDITION_YAW command using command_long_encode() msg = vehicle.message_factory.command_long_encode( 0, 0, # target system, target component @@ -162,7 +176,7 @@ def get_location_metres(original_location, dNorth, dEast): For more information see: http://gis.stackexchange.com/questions/2951/algorithm-for-offsetting-a-latitude-longitude-by-some-amount-of-meters """ - earth_radius=6378137.0 #Radius of "spherical" earth + earth_radius = 6378137.0 #Radius of "spherical" earth #Coordinate offsets in radians dLat = dNorth/earth_radius dLon = dEast/(earth_radius*math.cos(math.pi*original_location.lat/180)) @@ -291,12 +305,17 @@ def goto(dNorth, dEast, gotoFunction=vehicle.simple_goto): The method reports the distance to target every two seconds. """ - currentLocation=vehicle.location.global_relative_frame - targetLocation=get_location_metres(currentLocation, dNorth, dEast) - targetDistance=get_distance_metres(currentLocation, targetLocation) + + currentLocation = vehicle.location.global_relative_frame + targetLocation = get_location_metres(currentLocation, dNorth, dEast) + targetDistance = get_distance_metres(currentLocation, targetLocation) gotoFunction(targetLocation) + + #print "DEBUG: targetLocation: %s" % targetLocation + #print "DEBUG: targetLocation: %s" % targetDistance while vehicle.mode.name=="GUIDED": #Stop action if we are no longer in guided mode. + #print "DEBUG: mode: %s" % vehicle.mode.name remainingDistance=get_distance_metres(vehicle.location.global_relative_frame, targetLocation) print "Distance to target: ", remainingDistance if remainingDistance<=targetDistance*0.01: #Just below target, in case of undershoot. @@ -430,16 +449,16 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z, duration): print("Position South 100 West 130") print("Set groundspeed to 5m/s.") -vehicle.groundspeed=5 +vehicle.groundspeed = 5 goto(-100, -130, goto_position_target_global_int) print("Set groundspeed to 15m/s (max).") -vehicle.groundspeed=15 +vehicle.groundspeed = 15 print("Position South 0 East 200") goto(0, 260, goto_position_target_global_int) print("Set airspeed to 10m/s (max).") -vehicle.airspeed=10 +vehicle.airspeed = 10 print("Position North 100 West 130") goto(100, -130, goto_position_target_global_int) @@ -463,7 +482,7 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z, duration): """ print("SQUARE path using SET_POSITION_TARGET_LOCAL_NED and position parameters") -DURATION=20 #Set duration for each segment. +DURATION = 20 #Set duration for each segment. print("North 50m, East 0m, 10m altitude for %s seconds" % DURATION) goto_position_target_local_ned(50,0,-10) @@ -504,20 +523,20 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z, duration): #Set up velocity vector to map to each direction. # vx > 0 => fly North # vx < 0 => fly South -NORTH=2 -SOUTH=-2 +NORTH = 2 +SOUTH = -2 # Note for vy: # vy > 0 => fly East # vy < 0 => fly West -EAST=2 -WEST=-2 +EAST = 2 +WEST = -2 # Note for vz: # vz < 0 => ascend # vz > 0 => descend -UP=-0.5 -DOWN=0.5 +UP = -0.5 +DOWN = 0.5 # Square path using velocity @@ -623,4 +642,8 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z, duration): print "Close vehicle object" vehicle.close() -print("Completed") \ No newline at end of file +# Shut down simulator if it was started. +if sitl is not None: + sitl.stop() + +print("Completed") From 2e99e07854ae43cdb435c8ca098b9c69f3f5fa62 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 11 Feb 2016 14:47:03 +1100 Subject: [PATCH 294/475] Update setup.py and doc.conf to release 2.1.0 --- docs/conf.py | 6 +++--- setup.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 47f09e962..bdb723a8d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -41,7 +41,7 @@ master_doc = 'index' # General information about the project. -project = u'DroneKit Air: Python' +project = u'DroneKit Python' copyright = u'2015-2016, 3D Robotics' # The version info for the project you're documenting, acts as replacement for @@ -49,9 +49,9 @@ # built documents. # # The short X.Y version. -version = '0.5' +version = '2.1' # The full version, including alpha/beta/rc tags. -release = '0.5' +release = '2.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/setup.py b/setup.py index e7cc78431..4f657e5d5 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.0.2' +version = '2.1.0' setup(name='dronekit', zip_safe=True, From 197c8b1f3719ccf94240fde6c6ca099959410d0e Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 11 Feb 2016 14:52:39 +1100 Subject: [PATCH 295/475] Fix best practice information regarding sleeping your thread to refer to CPU not memory --- docs/develop/best_practice.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/best_practice.rst b/docs/develop/best_practice.rst index 4fa4e9c0c..dec8c0640 100644 --- a/docs/develop/best_practice.rst +++ b/docs/develop/best_practice.rst @@ -184,7 +184,7 @@ Exactly what state information you observe, and how you react to it, depends on Sleep the script when not needed ================================ -Sleeping your script appropriately can reduce the memory overhead. +Sleeping your script can reduce the CPU overhead. For example, at low speeds you might only need to check whether you've reached a target every few seconds. Using ``time.sleep(2)`` between checks will be more efficient than checking more often. From 8a2322ffaf15f2b7ce76bd716174838f8b9abe65 Mon Sep 17 00:00:00 2001 From: squilter Date: Tue, 5 Jan 2016 22:02:11 -0500 Subject: [PATCH 296/475] Remove duplicate imports --- dronekit/__init__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 6712ce260..60a5702f2 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -47,8 +47,6 @@ import copy import collections from pymavlink.dialects.v10 import ardupilotmega -from pymavlink import mavutil, mavwp -from dronekit.util import errprinter class APIException(Exception): From ceff0d37d0dd068f5dd5d7f708e9e31d483f2780 Mon Sep 17 00:00:00 2001 From: squilter Date: Tue, 5 Jan 2016 22:04:53 -0500 Subject: [PATCH 297/475] Implement version class and capabilities class --- dronekit/__init__.py | 172 ++++++++++++++++++ .../test/sitl/test_capability_and_version.py | 14 ++ examples/vehicle_state/vehicle_state.py | 1 + 3 files changed, 187 insertions(+) create mode 100644 dronekit/test/sitl/test_capability_and_version.py diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 60a5702f2..b16b62d39 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -252,6 +252,148 @@ def __init__(self, distance, voltage): def __str__(self): return "Rangefinder: distance={}, voltage={}".format(self.distance, self.voltage) +class Version(object): + """ + Version numbers. + + An object of this type is returned by :py:attr:`Vehicle.version` + The version number can be read in a few different formats. To get it in a human-readable + format, just print `vehicle.version`. This might print somthing like "APM:Copter-3.3.2-rc4". + + .. py:attribute:: major + + Major version number (integer). + + .. py:attribute::minor + + Minor version number (integer). + + .. py:attribute:: patch + + Patch version number (integer). + + .. py:attribute:: release + + Release type (integer). See the enum `FIRMWARE_VERSION_TYPE `_. + """ + def __init__(self, raw_version, autopilot_type, vehicle_type): + self.autopilot_type = autopilot_type + self.vehicle_type = vehicle_type + self.raw_version = raw_version + if(raw_version == None): + self.major = None + self.minor = None + self.patch = None + self.release = None + else: + self.major = raw_version >> 24 & 0xFF + self.minor = raw_version >> 16 & 0xFF + self.patch = raw_version >> 8 & 0xFF + self.release = raw_version & 0xFF + + def is_stable(self): + """ + Returns True if the autopilot reports that the current firmware is a stable + release, not a pre-release or development version. + """ + return self.release == 255 + + def __str__(self): + prefix="" + if(self.autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_ARDUPILOTMEGA): + prefix += "APM:" + elif(self.autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_PX4): + prefix += "PX4" + if(self.vehicle_type == mavutil.mavlink.MAV_TYPE_QUADROTOR): + prefix += "Copter-" + elif(self.vehicle_type == mavutil.mavlink.MAV_TYPE_FIXED_WING): + prefix += "Plane-" + elif(self.vehicle_type == mavutil.mavlink.MAV_TYPE_ROVER): + prefix += "Rover-" + + release_type="-dev" + if(self.release != None): + if(self.release == 255): + release_type = "" + if(self.release > 192-1): + release_type = "-rc" + str(self.release-(192-1)) + if(self.release > 128-1): + release_type = "-beta" + str(self.release-(192-1)) + if(self.release > 64-1): + release_type = "-alpha" + str(self.release-(192-1)) + return prefix + "%s.%s.%s" % (self.major, self.minor, self.patch) + release_type + +class Capabilities: + """ + The capabilities tells us what messages the autopilot is capable of interpreting. + + .. py:attribute:: mission_float + + Autopilot supports MISSION float message type (Boolean). + + .. py:attribute:: param_float + + Autopilot supports the new param float message type (Boolean). + + .. py:attribute:: mission_int + + Autopilot supports MISSION_INT scaled integer message type (Boolean). + + .. py:attribute:: command_int + + Autopilot supports COMMAND_INT scaled integer message type (Boolean). + + .. py:attribute:: param_union + + Autopilot supports the new param union message type (Boolean). + + .. py:attribute:: ftp + + Autopilot supports ftp for file transfers (Boolean). + + .. py:attribute:: set_attitude_target + + Autopilot supports commanding attitude offboard (Boolean). + + .. py:attribute:: set_attitude_target_local_ned + + Autopilot supports commanding position and velocity targets in local NED frame (Boolean). + + .. py:attribute:: set_attitude_target_global_int + + Autopilot supports commanding position and velocity targets in global scaled integers (Boolean). + + .. py:attribute:: terrain + + Autopilot supports terrain protocol / data handling (Boolean). + + .. py:attribute:: set_actuator_target + + Autopilot supports direct actuator control (Boolean). + + .. py:attribute:: flight_termination + + Autopilot supports the flight termination command (Boolean). + + .. py:attribute:: compass_calibration + + Autopilot supports onboard compass calibration (Boolean). + """ + def __init__(self, capabilities): + self.mission_float = (((capabilities >> 0) & 1) == 1) + self.param_float = (((capabilities >> 1) & 1) == 1) + self.mission_int = (((capabilities >> 2) & 1) == 1) + self.command_int = (((capabilities >> 3) & 1) == 1) + self.param_union = (((capabilities >> 4) & 1) == 1) + self.ftp = (((capabilities >> 5) & 1) == 1) + self.set_attitude_target = (((capabilities >> 6) & 1) == 1) + self.set_attitude_target_local_ned = (((capabilities >> 7) & 1) == 1) + self.set_altitude_target_global_int = (((capabilities >> 8) & 1) == 1) + self.terrain = (((capabilities >> 9) & 1) == 1) + self.set_actuator_target = (((capabilities >> 10) & 1) == 1) + self.flight_termination = (((capabilities >> 11) & 1) == 1) + self.compass_calibration = (((capabilities >> 12) & 1) == 1) + class VehicleMode(object): """ @@ -887,6 +1029,14 @@ def listener(self, name, m): self._mount_yaw = m.pointing_c / 100.0 self.notify_attribute_listeners('mount', self.mount_status) + self._capabilities = None + self._raw_version =None + + @self.on_message('AUTOPILOT_VERSION') + def listener(vehicle, name, m): + self._capabilities = m.capabilities + self._raw_version = m.flight_sw_version + # gimbal self._gimbal = Gimbal(self) @@ -958,6 +1108,8 @@ def listener(self, name, m): self._flightmode = 'AUTO' self._armed = False self._system_status = None + self._autopilot_type = None#PX4, ArduPilot, etc. + self._vehicle_type = None#quadcopter, plane, etc. @self.on_message('HEARTBEAT') def listener(self, name, m): @@ -967,6 +1119,8 @@ def listener(self, name, m): self.notify_attribute_listeners('mode', self.mode, cache=True) self._system_status = m.system_status self.notify_attribute_listeners('system_status', self.system_status, cache=True) + self._autopilot_type = m.autopilot + self._vehicle_type = m.type # Waypoints. @@ -1389,6 +1543,20 @@ def velocity(self): """ return [self._vx, self._vy, self._vz] + @property + def version(self): + """ + The autopilot version in a :py:class:`Version object`. + """ + return Version(self._raw_version, self._autopilot_type, self._vehicle_type) + + @property + def capabilities(self): + """ + The capabilities of the autopilot in a :py:class:`Capabilities` object. + """ + return Capabilities(self._capabilities) + @property def attitude(self): """ @@ -1843,6 +2011,10 @@ def initialize(self, rate=4, heartbeat_timeout=30): self._master.mav.request_data_stream_send(0, 0, mavutil.mavlink.MAV_DATA_STREAM_ALL, rate, 1) + #Request an AUTOPILOT_VERSION packet + capability_msg = self.message_factory.command_long_encode(0, 0, mavutil.mavlink.MAV_CMD_REQUEST_AUTOPILOT_CAPABILITIES, 0, 1, 0, 0, 0, 0, 0, 0) + self.send_mavlink(capability_msg) + # Ensure initial parameter download has started. while True: # This fn actually rate limits itself to every 2s. diff --git a/dronekit/test/sitl/test_capability_and_version.py b/dronekit/test/sitl/test_capability_and_version.py new file mode 100644 index 000000000..88d11eee0 --- /dev/null +++ b/dronekit/test/sitl/test_capability_and_version.py @@ -0,0 +1,14 @@ +import time + +from dronekit import VehicleMode, connect +from dronekit.test import with_sitl +from nose.tools import assert_false, assert_true + + +@with_sitl +def test_115(connpath): + v = connect(connpath, wait_ready=True) + time.sleep(5) + assert_false(v.capabilities.ftp) + assert_true(v.capabilities.mission_float) + assert_true(v.version.major is not None) diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index b0346c232..8c74cb7c4 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -25,6 +25,7 @@ # Get all vehicle attributes (state) print "\nGet all vehicle attribute values:" +print " Autopilot Firmware version: %s" % vehicle.version print " Global Location: %s" % vehicle.location.global_frame print " Global Location (relative altitude): %s" % vehicle.location.global_relative_frame print " Local Location: %s" % vehicle.location.local_frame From 6a38b5380b09b1d2d4a4f1390fa7c8dececf1779 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Tue, 9 Feb 2016 13:20:33 +1100 Subject: [PATCH 298/475] Refetch capabilities until ArduCopter complies --- dronekit/__init__.py | 12 ++++++++-- .../test/sitl/test_capability_and_version.py | 22 ++++++++++++++++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index b16b62d39..0c8156c36 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -951,6 +951,9 @@ def __init__(self, handler): self._handler = handler self._master = handler.master + # a message listener to set Autopilot version and capabilties: + self.listener_capa = None + # Cache all updated attributes for wait_ready. # By default, we presume all "commands" are loaded. self._ready_attrs = set(['commands']) @@ -1036,6 +1039,8 @@ def listener(self, name, m): def listener(vehicle, name, m): self._capabilities = m.capabilities self._raw_version = m.flight_sw_version + if self.listener_capa is not None: + self.remove_attribute_listener('HEARTBEAT', self.listener_capa) # gimbal self._gimbal = Gimbal(self) @@ -2012,8 +2017,11 @@ def initialize(self, rate=4, heartbeat_timeout=30): rate, 1) #Request an AUTOPILOT_VERSION packet - capability_msg = self.message_factory.command_long_encode(0, 0, mavutil.mavlink.MAV_CMD_REQUEST_AUTOPILOT_CAPABILITIES, 0, 1, 0, 0, 0, 0, 0, 0) - self.send_mavlink(capability_msg) + def send_capabilties_request(vehicle, name, m): + capability_msg = self.message_factory.command_long_encode(0, 0, mavutil.mavlink.MAV_CMD_REQUEST_AUTOPILOT_CAPABILITIES, 0, 1, 0, 0, 0, 0, 0, 0) + self.send_mavlink(capability_msg) + + self.listener_capa = self.add_message_listener('HEARTBEAT', send_capabilties_request) # Ensure initial parameter download has started. while True: diff --git a/dronekit/test/sitl/test_capability_and_version.py b/dronekit/test/sitl/test_capability_and_version.py index 88d11eee0..5ba817873 100644 --- a/dronekit/test/sitl/test_capability_and_version.py +++ b/dronekit/test/sitl/test_capability_and_version.py @@ -10,5 +10,25 @@ def test_115(connpath): v = connect(connpath, wait_ready=True) time.sleep(5) assert_false(v.capabilities.ftp) - assert_true(v.capabilities.mission_float) + + # versions of ArduCopter prior to v3.3 will send out capabilities + # flags before they are initialised. Vehicle attempts to refetch + # until capabilities are non-zero, but we may need to wait: + start_time = time.time() + nonzero_capabilities = True + slept = False + while v.capabilities.mission_float == 0: + if time.time() > start_time + 30: + nonzero_capabilities = False + break + time.sleep(0.1) + slept = True + if v.capabilities.mission_float: + if slept: + assert_true(v.version.major <= 3) + assert_true(v.version_minor <= 3) + else: + # fail it + assert_true(v.capabilities.mission_float) + assert_true(v.version.major is not None) From d65471b44e720583a6ef3728dcb44a01050a50ab Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Tue, 9 Feb 2016 14:49:38 +1100 Subject: [PATCH 299/475] Improve stringification of Version object --- dronekit/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 0c8156c36..03ec2fc1d 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -300,16 +300,22 @@ def is_stable(self): def __str__(self): prefix="" + if(self.autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_ARDUPILOTMEGA): prefix += "APM:" elif(self.autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_PX4): prefix += "PX4" + else: + prefix += "UnknownAutoPilot" + if(self.vehicle_type == mavutil.mavlink.MAV_TYPE_QUADROTOR): prefix += "Copter-" elif(self.vehicle_type == mavutil.mavlink.MAV_TYPE_FIXED_WING): prefix += "Plane-" elif(self.vehicle_type == mavutil.mavlink.MAV_TYPE_ROVER): prefix += "Rover-" + else: + prefix += "UnknownVehicleType%d-" % (self.vehicle_type) release_type="-dev" if(self.release != None): From dd196378cea92a274fb65ee1d399d65424a852d7 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 9 Feb 2016 15:44:57 +1100 Subject: [PATCH 300/475] Fix doc strings in library --- dronekit/__init__.py | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 03ec2fc1d..656da1f26 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -254,11 +254,14 @@ def __str__(self): class Version(object): """ - Version numbers. + Autopilot version and type. - An object of this type is returned by :py:attr:`Vehicle.version` + An object of this type is returned by :py:attr:`Vehicle.version`. + The version number can be read in a few different formats. To get it in a human-readable - format, just print `vehicle.version`. This might print somthing like "APM:Copter-3.3.2-rc4". + format, just print `vehicle.version`. This might print something like "APM:Copter-3.3.2-rc4". + + .. versionadded:: 2.0.3 .. py:attribute:: major @@ -274,7 +277,7 @@ class Version(object): .. py:attribute:: release - Release type (integer). See the enum `FIRMWARE_VERSION_TYPE `_. + Release type (integer). See the enum `FIRMWARE_VERSION_TYPE `_. """ def __init__(self, raw_version, autopilot_type, vehicle_type): self.autopilot_type = autopilot_type @@ -294,7 +297,7 @@ def __init__(self, raw_version, autopilot_type, vehicle_type): def is_stable(self): """ Returns True if the autopilot reports that the current firmware is a stable - release, not a pre-release or development version. + release (not a pre-release or development version). """ return self.release == 255 @@ -331,15 +334,23 @@ def __str__(self): class Capabilities: """ - The capabilities tells us what messages the autopilot is capable of interpreting. - + Autopilot capabilities (supported message types and functionality). + + An object of this type is returned by :py:attr:`Vehicle.capabilities`. + + See the enum + `MAV_PROTOCOL_CAPABILITY `_. + + .. versionadded:: 2.0.3 + + .. py:attribute:: mission_float Autopilot supports MISSION float message type (Boolean). .. py:attribute:: param_float - Autopilot supports the new param float message type (Boolean). + Autopilot supports the PARAM float message type (Boolean). .. py:attribute:: mission_int @@ -351,7 +362,7 @@ class Capabilities: .. py:attribute:: param_union - Autopilot supports the new param union message type (Boolean). + Autopilot supports the PARAM_UNION message type (Boolean). .. py:attribute:: ftp @@ -365,7 +376,7 @@ class Capabilities: Autopilot supports commanding position and velocity targets in local NED frame (Boolean). - .. py:attribute:: set_attitude_target_global_int + .. py:attribute:: set_altitude_target_global_int Autopilot supports commanding position and velocity targets in global scaled integers (Boolean). @@ -1557,14 +1568,18 @@ def velocity(self): @property def version(self): """ - The autopilot version in a :py:class:`Version object`. + The autopilot version and type in a :py:class:`Version` object. + + .. versionadded:: 2.0.3 """ return Version(self._raw_version, self._autopilot_type, self._vehicle_type) @property def capabilities(self): """ - The capabilities of the autopilot in a :py:class:`Capabilities` object. + The autopilot capabilities in a :py:class:`Capabilities` object. + + .. versionadded:: 2.0.3 """ return Capabilities(self._capabilities) @@ -1587,7 +1602,7 @@ def armed(self): """ This attribute can be used to get and set the ``armed`` state of the vehicle (``boolean``). - The code below shows how to read the state, and to arm/disam the vehicle: + The code below shows how to read the state, and to arm/disarm the vehicle: .. code:: python @@ -1717,7 +1732,7 @@ def gimbal(self): """ Gimbal object for controlling, viewing and observing gimbal status (:py:class:`Gimbal`). - .. versionadded:: 2.1.0 + .. versionadded:: 2.0.1 """ return self._gimbal From b1207a170ecbecb465ae52a63ca7c95da35951c5 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 9 Feb 2016 16:54:58 +1100 Subject: [PATCH 301/475] Fix up examples for new version and capabilities attributes --- docs/examples/vehicle_state.rst | 307 +++++++++++--------- docs/guide/vehicle_state_and_parameters.rst | 6 +- examples/vehicle_state/vehicle_state.py | 45 ++- 3 files changed, 213 insertions(+), 145 deletions(-) diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index 7448ac9ad..6b3cbcf28 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -17,14 +17,6 @@ Running the example The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle and DroneKit have been set up as described in :ref:`installing_dronekit`). -If you're using a simulated vehicle remember to :ref:`disable arming checks ` so -that the example can run. You can also: - -* `add a virtual rangefinder `_ - (otherwise the :py:attr:`Vehicle.rangefinder ` attribute may return values of ``None`` for the distance and voltage). -* `add a virtual gimbal `_ - (otherwise the :py:attr:`Vehicle.gimbal ` attribute may return values of ``None`` for the yaw, pitch and roll). - In summary, after cloning the repository: #. Navigate to the example folder as shown: @@ -34,143 +26,178 @@ In summary, after cloning the repository: cd dronekit-python/examples/vehicle_state/ -#. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: +#. You can run the example against the simulator by specifying the Python script without any arguments. + The example will download and start DroneKit-SITL, and then connect to it: + + .. code-block:: bash + + python vehicle_state.py + + On the command prompt you should see (something like): + + .. code:: bash + + Connecting to vehicle on: 170.0.0.1:14550 + >>> APM:Copter V3.3 (d6053245) + >>> Frame: QUAD + >>> Calibrating barometer + >>> Initialising APM... + >>> barometer calibration complete + >>> GROUND START + + Get all vehicle attribute values: + Autopilot Firmware version: APM:Copter-3.3.0-alpha64 + Major version number: 3 + Minor version number: 3 + Patch version number: 0 + Release type: 255 + Stable release?: True + Autopilot capabilities + Supports MISSION_FLOAT message type: True + Supports PARAM_FLOAT message type: True + Supports MISSION_INT message type: False + Supports COMMAND_INT message type: False + Supports PARAM_UNION message type: False + Supports ftp for file transfers: False + Supports commanding attitude offboard: False + Supports commanding position and velocity targets in local NED frame: True + Supports set position + velocity targets in global scaled integers: True + Supports terrain protocol / data handling: True + Supports direct actuator control: False + Supports the flight termination command: True + Supports mission_float message type: True + Supports onboard compass calibration: False + Global Location: LocationGlobal:lat=-35.363261,lon=149.1652299,alt=None + Global Location (relative altitude): LocationGlobalRelative:lat=-35.363261,lon=149.1652299,alt=0.0 + Local Location: LocationLocal:north=None,east=None,down=None + Attitude: Attitude:pitch=0.00294387154281,yaw=-0.11805768311,roll=0.00139428151306 + Velocity: [-0.03, 0.02, 0.0] + GPS: GPSInfo:fix=3,num_sat=10 + Gimbal status: Gimbal: pitch=None, roll=None, yaw=None + Battery: Battery:voltage=12.587,current=0.0,level=100 + EKF OK?: False + Last Heartbeat: 0.769999980927 + Rangefinder: Rangefinder: distance=None, voltage=None + Rangefinder distance: None + Rangefinder voltage: None + Heading: 353 + Is Armable?: False + System status: STANDBY + Groundspeed: 0.0 + Airspeed: 0.0 + Mode: STABILIZE + Armed: False + Waiting for home location ... + ... + Waiting for home location ... + Waiting for home location ... + + Home location: LocationGlobal:lat=-35.3632621765,lon=149.165237427,alt=583.989990234 + + Set new home location + New Home Location (from attribute - altitude should be 222): LocationGlobal:lat=-35.363261,lon=149.1652299,alt=222 + New Home Location (from vehicle - altitude should be 222): LocationGlobal:lat=-35.3632621765,lon=149.165237427,alt=222.0 + + Set Vehicle.mode=GUIDED (currently: STABILIZE) + Waiting for mode change ... + + Set Vehicle.armed=True (currently: False) + Waiting for arming... + Waiting for arming... + Waiting for arming... + >>> ARMING MOTORS + >>> GROUND START + Waiting for arming... + Waiting for arming... + >>> Initialising APM... + Vehicle is armed: True + + Add `attitude` attribute callback/observer on `vehicle` + Wait 2s so callback invoked before observer removed + CALLBACK: Attitude changed to Attitude:pitch=-0.000483880605316,yaw=-0.0960851684213,roll=-0.00799709651619 + CALLBACK: Attitude changed to Attitude:pitch=0.000153727291035,yaw=-0.0962921902537,roll=-0.00707155792043 + ... + CALLBACK: Attitude changed to Attitude:pitch=0.00485319690779,yaw=-0.100129388273,roll=0.00181497994345 + Remove Vehicle.attitude observer + + Add `mode` attribute callback/observer using decorator + Set mode=STABILIZE (currently: GUIDED) and wait for callback + Wait 2s so callback invoked before moving to next example + CALLBACK: Mode changed to VehicleMode:STABILIZE + + Attempt to remove observer added with `on_attribute` decorator (should fail) + Exception: Cannot remove observer added using decorator + + Add attribute callback detecting ANY attribute change + Wait 1s so callback invoked before observer removed + CALLBACK: (attitude): Attitude:pitch=0.00716688157991,yaw=-0.0950401723385,roll=0.00759896961972 + CALLBACK: (heading): 354 + CALLBACK: (location): + CALLBACK: (airspeed): 0.0 + CALLBACK: (groundspeed): 0.0 + CALLBACK: (ekf_ok): True + CALLBACK: (battery): Battery:voltage=12.538,current=3.48,level=99 + CALLBACK: (gps_0): GPSInfo:fix=3,num_sat=10 + CALLBACK: (location): + CALLBACK: (velocity): [-0.14, 0.1, 0.0] + CALLBACK: (local_position): LocationLocal:north=-0.136136248708,east=-0.0430941730738,down=-0.00938374921679 + CALLBACK: (channels): {'1': 1500, '3': 1000, '2': 1500, '5': 1800, '4': 1500, '7': 1000, '6': 1000, '8': 1800} + ... + CALLBACK: (ekf_ok): True + Remove Vehicle attribute observer + + Read and write parameters + Read vehicle param 'THR_MIN': 130.0 + Write vehicle param 'THR_MIN' : 10 + Read new value of param 'THR_MIN': 10.0 + + Print all parameters (iterate `vehicle.parameters`): + Key:RC7_REV Value:1.0 + Key:GPS_INJECT_TO Value:127.0 + Key:FLTMODE1 Value:7.0 + ... + Key:SR2_POSITION Value:0.0 + Key:SIM_FLOW_DELAY Value:0.0 + Key:BATT_CURR_PIN Value:12.0 + + Create parameter observer using decorator + Write vehicle param 'THR_MIN' : 20 (and wait for callback) + PARAMETER CALLBACK: THR_MIN changed to: 20.0 + + Create (removable) observer for any parameter using wildcard string + Change THR_MID and THR_MIN parameters (and wait for callback) + ANY PARAMETER CALLBACK: THR_MID changed to: 400.0 + PARAMETER CALLBACK: THR_MIN changed to: 30.0 + ANY PARAMETER CALLBACK: THR_MIN changed to: 30.0 + + Reset vehicle attributes/parameters and exit + >>> DISARMING MOTORS + PARAMETER CALLBACK: THR_MIN changed to: 130.0 + ANY PARAMETER CALLBACK: THR_MIN changed to: 130.0 + ANY PARAMETER CALLBACK: THR_MID changed to: 500.0 + + Close vehicle object + Completed + +#. You can run the example against a specific connection (simulated or otherwise) by passing the :ref:`connection string ` for your vehicle in the ``--connect`` parameter. + For example, to connect to SITL running on UDP port 14550 on your local computer: .. code-block:: bash python vehicle_state.py --connect 127.0.0.1:14550 - .. note:: - - The ``--connect`` parameter above connects to SITL on udp port 127.0.0.1:14550. - This is the default value for the parameter, and may be omitted. - - - -On the command prompt you should see (something like): - -.. code:: bash - - Connecting to vehicle on: 170.0.0.1:14550 - >>> APM:Copter V3.3 (d6053245) - >>> Frame: QUAD - >>> Calibrating barometer - >>> Initialising APM... - >>> barometer calibration complete - >>> GROUND START - - Get all vehicle attribute values: - Global Location: LocationGlobal:lat=-35.363261,lon=149.1652299,alt=None - Global Location (relative altitude): LocationGlobalRelative:lat=-35.363261,lon=149.1652299,alt=0.0 - Local Location: LocationLocal:north=None,east=None,down=None - Attitude: Attitude:pitch=0.00294387154281,yaw=-0.11805768311,roll=0.00139428151306 - Velocity: [-0.03, 0.02, 0.0] - GPS: GPSInfo:fix=3,num_sat=10 - Gimbal status: Gimbal: pitch=None, roll=None, yaw=None - Battery: Battery:voltage=12.587,current=0.0,level=100 - EKF OK?: False - Last Heartbeat: 0.769999980927 - Rangefinder: Rangefinder: distance=None, voltage=None - Rangefinder distance: None - Rangefinder voltage: None - Heading: 353 - Is Armable?: False - System status: STANDBY - Groundspeed: 0.0 - Airspeed: 0.0 - Mode: STABILIZE - Armed: False - Waiting for home location ... - ... - Waiting for home location ... - Waiting for home location ... - - Home location: LocationGlobal:lat=-35.3632621765,lon=149.165237427,alt=583.989990234 - - Set new home location - New Home Location (from attribute - altitude should be 222): LocationGlobal:lat=-35.363261,lon=149.1652299,alt=222 - New Home Location (from vehicle - altitude should be 222): LocationGlobal:lat=-35.3632621765,lon=149.165237427,alt=222.0 - - Set Vehicle.mode=GUIDED (currently: STABILIZE) - Waiting for mode change ... - - Set Vehicle.armed=True (currently: False) - Waiting for arming... - Waiting for arming... - Waiting for arming... - >>> ARMING MOTORS - >>> GROUND START - Waiting for arming... - Waiting for arming... - >>> Initialising APM... - Vehicle is armed: True - - Add `attitude` attribute callback/observer on `vehicle` - Wait 2s so callback invoked before observer removed - CALLBACK: Attitude changed to Attitude:pitch=-0.000483880605316,yaw=-0.0960851684213,roll=-0.00799709651619 - CALLBACK: Attitude changed to Attitude:pitch=0.000153727291035,yaw=-0.0962921902537,roll=-0.00707155792043 - ... - CALLBACK: Attitude changed to Attitude:pitch=0.00485319690779,yaw=-0.100129388273,roll=0.00181497994345 - Remove Vehicle.attitude observer - - Add `mode` attribute callback/observer using decorator - Set mode=STABILIZE (currently: GUIDED) and wait for callback - Wait 2s so callback invoked before moving to next example - CALLBACK: Mode changed to VehicleMode:STABILIZE - - Attempt to remove observer added with `on_attribute` decorator (should fail) - Exception: Cannot remove observer added using decorator - - Add attribute callback detecting ANY attribute change - Wait 1s so callback invoked before observer removed - CALLBACK: (attitude): Attitude:pitch=0.00716688157991,yaw=-0.0950401723385,roll=0.00759896961972 - CALLBACK: (heading): 354 - CALLBACK: (location): - CALLBACK: (airspeed): 0.0 - CALLBACK: (groundspeed): 0.0 - CALLBACK: (ekf_ok): True - CALLBACK: (battery): Battery:voltage=12.538,current=3.48,level=99 - CALLBACK: (gps_0): GPSInfo:fix=3,num_sat=10 - CALLBACK: (location): - CALLBACK: (velocity): [-0.14, 0.1, 0.0] - CALLBACK: (local_position): LocationLocal:north=-0.136136248708,east=-0.0430941730738,down=-0.00938374921679 - CALLBACK: (channels): {'1': 1500, '3': 1000, '2': 1500, '5': 1800, '4': 1500, '7': 1000, '6': 1000, '8': 1800} - ... - CALLBACK: (ekf_ok): True - Remove Vehicle attribute observer - - Read and write parameters - Read vehicle param 'THR_MIN': 130.0 - Write vehicle param 'THR_MIN' : 10 - Read new value of param 'THR_MIN': 10.0 - - Print all parameters (iterate `vehicle.parameters`): - Key:RC7_REV Value:1.0 - Key:GPS_INJECT_TO Value:127.0 - Key:FLTMODE1 Value:7.0 - ... - Key:SR2_POSITION Value:0.0 - Key:SIM_FLOW_DELAY Value:0.0 - Key:BATT_CURR_PIN Value:12.0 - - Create parameter observer using decorator - Write vehicle param 'THR_MIN' : 20 (and wait for callback) - PARAMETER CALLBACK: THR_MIN changed to: 20.0 - - Create (removable) observer for any parameter using wildcard string - Change THR_MID and THR_MIN parameters (and wait for callback) - ANY PARAMETER CALLBACK: THR_MID changed to: 400.0 - PARAMETER CALLBACK: THR_MIN changed to: 30.0 - ANY PARAMETER CALLBACK: THR_MIN changed to: 30.0 - - Reset vehicle attributes/parameters and exit - >>> DISARMING MOTORS - PARAMETER CALLBACK: THR_MIN changed to: 130.0 - ANY PARAMETER CALLBACK: THR_MIN changed to: 130.0 - ANY PARAMETER CALLBACK: THR_MID changed to: 500.0 - - Close vehicle object - Completed + +.. note:: + + DroneKit-SITL automatically disables arming checks, but if you're using another simulated environment remember to :ref:`disable arming checks ` so that the example can run. In that case you can also: + + * `add a virtual rangefinder `_ + (otherwise the :py:attr:`Vehicle.rangefinder ` attribute may return values of ``None`` for the distance and voltage). + * `add a virtual gimbal `_ + (otherwise the :py:attr:`Vehicle.gimbal ` attribute may return values of ``None`` for the yaw, pitch and roll). + + + diff --git a/docs/guide/vehicle_state_and_parameters.rst b/docs/guide/vehicle_state_and_parameters.rst index 1062e1be6..1bb23ddde 100644 --- a/docs/guide/vehicle_state_and_parameters.rst +++ b/docs/guide/vehicle_state_and_parameters.rst @@ -20,7 +20,9 @@ Attributes ========== Vehicle state information is exposed through vehicle *attributes*. DroneKit-Python currently supports the following -"standard" attributes: +"standard" attributes: +:py:attr:`Vehicle.version `, +:py:attr:`Vehicle.location.capabilities `, :py:attr:`Vehicle.location.global_frame `, :py:attr:`Vehicle.location.global_relative_frame `, :py:attr:`Vehicle.location.local_frame `, @@ -69,6 +71,8 @@ regularly updated from MAVLink messages sent by the vehicle). .. code:: python # vehicle is an instance of the Vehicle class + print "Autopilot Firmware version: %s" % vehicle.version + print "Autopilot capabilities (supports ftp): %s" % vehicle.capabilities.ftp print "Global Location: %s" % vehicle.location.global_frame print "Global Location (relative altitude): %s" % vehicle.location.global_relative_frame print "Local Location: %s" % vehicle.location.local_frame #NED diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 8c74cb7c4..38833c48f 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -12,20 +12,52 @@ #Set up option parsing to get connection string import argparse parser = argparse.ArgumentParser(description='Print out vehicle state information. Connects to SITL on local PC by default.') -parser.add_argument('--connect', default='127.0.0.1:14550', - help="vehicle connection target. Default '127.0.0.1:14550'") +parser.add_argument('--connect', + help="vehicle connection target string. If not specified, SITL automatically started and used.") args = parser.parse_args() +connection_string=args.connect + +#No connection string specified, so start SITL +if not args.connect: + print "Starting copter simulator (SITL)" + from dronekit_sitl import SITL + sitl = SITL() + sitl.download('copter', '3.3', verbose=True) + sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] + sitl.launch(sitl_args, await_ready=True, restart=True) + connection_string='tcp:127.0.0.1:5760' + # Connect to the Vehicle. # Set `wait_ready=True` to ensure default attributes are populated before `connect()` returns. -print "\nConnecting to vehicle on: %s" % args.connect -vehicle = connect(args.connect, wait_ready=True) +print "\nConnecting to vehicle on: %s" % connection_string +vehicle = connect(connection_string, wait_ready=True) # Get all vehicle attributes (state) print "\nGet all vehicle attribute values:" print " Autopilot Firmware version: %s" % vehicle.version +print " Major version number: %s" % vehicle.version.major +print " Minor version number: %s" % vehicle.version.minor +print " Patch version number: %s" % vehicle.version.patch +print " Release type: %s" % vehicle.version.release +print " Stable release?: %s" % vehicle.version.is_stable() +print " Autopilot capabilities" +print " Supports MISSION_FLOAT message type: %s" % vehicle.capabilities.mission_float +print " Supports PARAM_FLOAT message type: %s" % vehicle.capabilities.param_float +print " Supports MISSION_INT message type: %s" % vehicle.capabilities.mission_int +print " Supports COMMAND_INT message type: %s" % vehicle.capabilities.command_int +print " Supports PARAM_UNION message type: %s" % vehicle.capabilities.param_union +print " Supports ftp for file transfers: %s" % vehicle.capabilities.ftp +print " Supports commanding attitude offboard: %s" % vehicle.capabilities.set_attitude_target +print " Supports commanding position and velocity targets in local NED frame: %s" % vehicle.capabilities.set_attitude_target_local_ned +print " Supports set position + velocity targets in global scaled integers: %s" % vehicle.capabilities.set_altitude_target_global_int +print " Supports terrain protocol / data handling: %s" % vehicle.capabilities.terrain +print " Supports direct actuator control: %s" % vehicle.capabilities.set_actuator_target +print " Supports the flight termination command: %s" % vehicle.capabilities.flight_termination +print " Supports mission_float message type: %s" % vehicle.capabilities.mission_float +print " Supports onboard compass calibration: %s" % vehicle.capabilities.compass_calibration print " Global Location: %s" % vehicle.location.global_frame print " Global Location (relative altitude): %s" % vehicle.location.global_relative_frame print " Local Location: %s" % vehicle.location.local_frame @@ -223,6 +255,11 @@ def any_parameter_callback(self, attr_name, value): print "\nClose vehicle object" vehicle.close() + +if not args.connect: + # Shut down simulator if it was started. + sitl.stop() + print("Completed") From 684c663f65c4791e5c782c8a489d2f1098f9ea47 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 10 Feb 2016 09:07:29 +1100 Subject: [PATCH 302/475] Wait for autpilot version, correct version numbers Also break out methods to get version and release type print more information in vehcicle_state --- dronekit/__init__.py | 41 ++++++++++++++----- .../test/sitl/test_capability_and_version.py | 2 + examples/vehicle_state/vehicle_state.py | 4 +- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 656da1f26..c8de28805 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -278,6 +278,9 @@ class Version(object): .. py:attribute:: release Release type (integer). See the enum `FIRMWARE_VERSION_TYPE `_. + + This is a composite of the product release cycle stage (rc, beta etc) and the version in that cycle - e.g. 23. + """ def __init__(self, raw_version, autopilot_type, vehicle_type): self.autopilot_type = autopilot_type @@ -301,6 +304,25 @@ def is_stable(self): """ return self.release == 255 + """ + Returns the version (an integer) within the release type. This method returns "23" for Copter-3.3rc23 + """ + def release_version(self): + if self.release is None: + return None + if(self.release == 255): + return 0 + return self.release % 64 + + """ + Returns text describing the release type e.g. "alpha", "stable" etc + """ + def release_type(self): + if self.release is None: + return None + types = [ "dev", "alpha", "beta", "rc" ] + return types[self.release/64] + def __str__(self): prefix="" @@ -320,16 +342,14 @@ def __str__(self): else: prefix += "UnknownVehicleType%d-" % (self.vehicle_type) - release_type="-dev" - if(self.release != None): - if(self.release == 255): - release_type = "" - if(self.release > 192-1): - release_type = "-rc" + str(self.release-(192-1)) - if(self.release > 128-1): - release_type = "-beta" + str(self.release-(192-1)) - if(self.release > 64-1): - release_type = "-alpha" + str(self.release-(192-1)) + if self.release_type() is None: + release_type = "UnknownReleaseType" + elif self.is_stable(): + release_type = "" + else: + # e.g. "-rc23" + release_type = "-" + str(self.release_type()) + str(self.release_version()) + return prefix + "%s.%s.%s" % (self.major, self.minor, self.patch) + release_type class Capabilities: @@ -1058,6 +1078,7 @@ def listener(vehicle, name, m): self._raw_version = m.flight_sw_version if self.listener_capa is not None: self.remove_attribute_listener('HEARTBEAT', self.listener_capa) + self.notify_attribute_listeners('autopilot_version', self._raw_version) # gimbal self._gimbal = Gimbal(self) diff --git a/dronekit/test/sitl/test_capability_and_version.py b/dronekit/test/sitl/test_capability_and_version.py index 5ba817873..ed466cdd3 100644 --- a/dronekit/test/sitl/test_capability_and_version.py +++ b/dronekit/test/sitl/test_capability_and_version.py @@ -32,3 +32,5 @@ def test_115(connpath): assert_true(v.capabilities.mission_float) assert_true(v.version.major is not None) + assert_true(len(v.version.release_type()) >= 2) + assert_true(v.version.release_version() is not None) diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 38833c48f..95d0fe8dc 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -34,6 +34,7 @@ print "\nConnecting to vehicle on: %s" % connection_string vehicle = connect(connection_string, wait_ready=True) +vehicle.wait_ready('autopilot_version') # Get all vehicle attributes (state) print "\nGet all vehicle attribute values:" @@ -41,7 +42,8 @@ print " Major version number: %s" % vehicle.version.major print " Minor version number: %s" % vehicle.version.minor print " Patch version number: %s" % vehicle.version.patch -print " Release type: %s" % vehicle.version.release +print " Release type: %s" % vehicle.version.release_type() +print " Release version: %s" % vehicle.version.release_version() print " Stable release?: %s" % vehicle.version.is_stable() print " Autopilot capabilities" print " Supports MISSION_FLOAT message type: %s" % vehicle.capabilities.mission_float From e4ec935a66ff807f760bde9835b1f995d20a482d Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 10 Feb 2016 10:27:11 +1100 Subject: [PATCH 303/475] Update docs for new release_type et al methods --- docs/examples/vehicle_state.rst | 18 +++++++----------- dronekit/__init__.py | 11 +++++++---- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index 6b3cbcf28..f43dfd62a 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -26,8 +26,8 @@ In summary, after cloning the repository: cd dronekit-python/examples/vehicle_state/ -#. You can run the example against the simulator by specifying the Python script without any arguments. - The example will download and start DroneKit-SITL, and then connect to it: +#. You can run the example against a simulator (DroneKit-SITL) by specifying the Python script without any arguments. + The example will download SITL binaries (if needed), start the simulator, and then connect to it: .. code-block:: bash @@ -50,7 +50,8 @@ In summary, after cloning the repository: Major version number: 3 Minor version number: 3 Patch version number: 0 - Release type: 255 + Release type: rc + Release version: 0 Stable release?: True Autopilot capabilities Supports MISSION_FLOAT message type: True @@ -180,6 +181,7 @@ In summary, after cloning the repository: Completed #. You can run the example against a specific connection (simulated or otherwise) by passing the :ref:`connection string ` for your vehicle in the ``--connect`` parameter. + For example, to connect to SITL running on UDP port 14550 on your local computer: .. code-block:: bash @@ -189,14 +191,8 @@ In summary, after cloning the repository: .. note:: - DroneKit-SITL automatically disables arming checks, but if you're using another simulated environment remember to :ref:`disable arming checks ` so that the example can run. In that case you can also: - - * `add a virtual rangefinder `_ - (otherwise the :py:attr:`Vehicle.rangefinder ` attribute may return values of ``None`` for the distance and voltage). - * `add a virtual gimbal `_ - (otherwise the :py:attr:`Vehicle.gimbal ` attribute may return values of ``None`` for the yaw, pitch and roll). - - + DroneKit-SITL does not automatically add a virtual gimbal and rangefinder, + so these attributes will always report ``None``. diff --git a/dronekit/__init__.py b/dronekit/__init__.py index c8de28805..4554482a5 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -304,20 +304,23 @@ def is_stable(self): """ return self.release == 255 + + def release_version(self): """ - Returns the version (an integer) within the release type. This method returns "23" for Copter-3.3rc23 + Returns the version within the release type (an integer). + This method returns "23" for Copter-3.3rc23. """ - def release_version(self): if self.release is None: return None if(self.release == 255): return 0 return self.release % 64 + + def release_type(self): """ - Returns text describing the release type e.g. "alpha", "stable" etc + Returns text describing the release type e.g. "alpha", "stable" etc. """ - def release_type(self): if self.release is None: return None types = [ "dev", "alpha", "beta", "rc" ] From 2857410b4b86a255d6a4a2183ac259e5e234c86d Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 10 Feb 2016 11:12:22 +1100 Subject: [PATCH 304/475] Tidy up Sitl startup/shut down code. Add consistent example spacing --- examples/vehicle_state/vehicle_state.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 95d0fe8dc..1d73e1de4 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -16,9 +16,11 @@ help="vehicle connection target string. If not specified, SITL automatically started and used.") args = parser.parse_args() -connection_string=args.connect +connection_string = args.connect +sitl = None -#No connection string specified, so start SITL + +#Start SITL if no connection string specified if not args.connect: print "Starting copter simulator (SITL)" from dronekit_sitl import SITL @@ -26,7 +28,7 @@ sitl.download('copter', '3.3', verbose=True) sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] sitl.launch(sitl_args, await_ready=True, restart=True) - connection_string='tcp:127.0.0.1:5760' + connection_string = 'tcp:127.0.0.1:5760' # Connect to the Vehicle. @@ -99,9 +101,9 @@ print "\nSet new home location" # Home location must be within 50km of EKF home location (or setting will fail silently) # In this case, just set value to current location with an easily recognisable altitude (222) -my_location_alt=vehicle.location.global_frame -my_location_alt.alt=222.0 -vehicle.home_location=my_location_alt +my_location_alt = vehicle.location.global_frame +my_location_alt.alt = 222.0 +vehicle.home_location = my_location_alt print " New Home Location (from attribute - altitude should be 222): %s" % vehicle.home_location #Confirm current value on vehicle by re-downloading commands @@ -111,7 +113,7 @@ print " New Home Location (from vehicle - altitude should be 222): %s" % vehicle.home_location -print "\nSet Vehicle.mode=GUIDED (currently: %s)" % vehicle.mode.name +print "\nSet Vehicle.mode = GUIDED (currently: %s)" % vehicle.mode.name vehicle.mode = VehicleMode("GUIDED") while not vehicle.mode.name=='GUIDED': #Wait until mode has changed print " Waiting for mode change ..." @@ -136,7 +138,7 @@ # Add and remove and attribute callbacks #Define callback for `vehicle.attitude` observer -last_attitude_cache=None +last_attitude_cache = None def attitude_callback(self, attr_name, value): # `attr_name` - the observed attribute (used if callback is used for multiple attributes) # `self` - the associated vehicle object (used if a callback is different for multiple vehicles) @@ -257,9 +259,8 @@ def any_parameter_callback(self, attr_name, value): print "\nClose vehicle object" vehicle.close() - -if not args.connect: - # Shut down simulator if it was started. +# Shut down simulator if it was started. +if sitl is not None: sitl.stop() print("Completed") From bc7ece78d3c83c6532233185c0fae9077600e6f9 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 10 Feb 2016 17:36:46 +1100 Subject: [PATCH 305/475] UPdate running examples page and simulation instructions --- docs/develop/sitl_setup.rst | 90 ++++++++++++++++++++---------- docs/examples/running_examples.rst | 32 +++++++---- 2 files changed, 80 insertions(+), 42 deletions(-) diff --git a/docs/develop/sitl_setup.rst b/docs/develop/sitl_setup.rst index 6fde96f80..d308d7881 100644 --- a/docs/develop/sitl_setup.rst +++ b/docs/develop/sitl_setup.rst @@ -15,6 +15,8 @@ The sections below explain how to install and run SITL, and how to connect to Dr Stations at the same time. +.. _dronekit_sitl: + DroneKit-SITL ============= @@ -68,42 +70,38 @@ There are a number of other useful arguments: dronekit-sitl --reset #Delete all downloaded vehicle binaries. dronekit-sitl ./path [args...] #Start SITL instance at target file location. - -.. note:: - - DroneKit-SITL also `exposes a Python API `_, which you can use to start simulation from within your scripts. This is particularly useful for test code! .. _connecting_dronekit_sitl: -Connecting to (DroneKit-) SITL ------------------------------- +Connecting to DroneKit-SITL +--------------------------- -SITL waits for TCP connections on ``127.0.0.1:5760``. DroneKit-Python scripts running on the same +DroneKit-SITL waits for TCP connections on ``127.0.0.1:5760``. DroneKit-Python scripts running on the same computer can connect to the simulation using the connection string as shown: .. code-block:: python vehicle = connect('tcp:127.0.0.1:5760', wait_ready=True) -If you need to connect to DroneKit-Python and a ground station at the same time you will need to -`install MAVProxy `_ -for your system. +After something connects to port ``5760``, SITL will then wait for additional connections on port ``5763`` +(and subsequently ``5766``, ``5769`` etc.) -Then in a second terminal you spawn an instance of *MAVProxy* to forward messages from -TCP ``127.0.0.1:5760`` to UDP ports ``127.0.0.1:14550`` and ``127.0.0.1:14551`` (this is what **sim_vehicle.sh** does -if you build SITL from source): +.. note:: -.. code-block:: bash + While you can connect to these additional ports, some users have reported problems when + viewing the running examples with *Mission Planner*. If you need to connect a ground station + and DroneKit at the same time we recommend you use *MAVProxy* (see :ref:`viewing_uav_on_map`). - mavproxy.py --master tcp:127.0.0.1:5760 --sitl 127.0.0.1:5501 --out 127.0.0.1:14550 --out 127.0.0.1:14551 -You can then connect to a ground station using one UDP address, and DroneKit-Python using the other. -For example: -.. code-block:: python +.. _dronekit_sitl_api: + +DroneKit-SITL Python API +------------------------ + +DroneKit-SITL `exposes a Python API `_, which you can use to start and control simulation from within your scripts. This is particularly useful for test code and :ref:`examples `. - vehicle = connect('127.0.0.1:14550', wait_ready=True) @@ -117,7 +115,14 @@ Building from source is useful if you want to need to test the latest changes (o a version for which DroneKit-SITL does not have pre-built binaries). It can also be useful if you have problems getting DroneKit-SITL to work. -The following topics from the ArduPilot wiki explain how: +SITL built from source has a few differences from DroneKit-SITL: + +* MAVProxy is included and started by default. You can use MAVProxy terminal to control the autopilot. +* You connect to SITL via UDP on ``127.0.0.1:14550``. You can use MAVProxy's ``output add`` command to add additional ports if needed. +* You may need to disable arming checks and load autotest parameters to run examples. +* It is easier to `add a virtual rangefinder `_ and `add a virtual gimbal `_ for testing. + +The following topics from the ArduPilot wiki explain how to set up Native SITL builds: * `Setting up SITL on Linux `_ * `Setting up SITL on Windows `_ @@ -129,24 +134,38 @@ The following topics from the ArduPilot wiki explain how: Connecting an additional Ground Station ======================================= -You can connect a ground station to an unused port to which messages -are being forwarded. You can forward messages to additional ports -when you start *MAVProxy* using the using ``-out`` -parameter (as shown :ref:`above `). +You can connect a ground station to an unused port to which messages are being forwarded. -Alternatively, once *MAVProxy* is started you can add new output ports in the *MAVProxy* console using: ``output add``: +The most reliable way to add new ports is to use *MAVProxy*: -.. code:: bash +* If you're using SITL built from source you will already have *MAVProxy* running. + You can add new ports in the MAVProxy console using ``output add``: - output add 127.0.0.1:14552 + .. code:: bash -.. note:: + output add 127.0.0.1:14552 - Instead of the loopback address you can also specify the network IP address of your computer - (On Windows you can get this by running *ipconfig* in the *Windows Command Prompt*). +* If you're using Dronekit-SITL you can: + * `Install MAVProxy `_ + for your system. + * In a second terminal spawn an instance of *MAVProxy* to forward messages from + TCP ``127.0.0.1:5760`` to other UDP ports like ``127.0.0.1:14550`` and ``127.0.0.1:14551``: -Then connect Mission Planner to this UDP port: + .. code-block:: bash + + mavproxy.py --master tcp:127.0.0.1:5760 --sitl 127.0.0.1:5501 --out 127.0.0.1:14550 --out 127.0.0.1:14551 + +Once you have available ports you can connect to a ground station using one UDP address, and DroneKit-Python using the other. + +For example, first connect the script: + +.. code-block:: python + + vehicle = connect('127.0.0.1:14550', wait_ready=True) + + +Then connect Mission Planner to the second UDP port: * `Download and install Mission Planner `_ * Ensure the selection list at the top right of the Mission Planner screen says *UDP* and then select the **Connect** button next to it. @@ -159,3 +178,12 @@ Then connect Mission Planner to this UDP port: After connecting, vehicle parameters will be loaded into *Mission Planner* and the vehicle is displayed on the map. +.. tip:: + + If you're using the :ref:`dronekit_sitl_api` then you will instead have to + connect to SITLs TCP port (as there is no way to set up MAVProxy in this case). + So if DroneKit is connecting to TCP port 5760, you would connect your GCS to 5763. + + Note that a few examples may not behave perfectly using this approach. If you need to + observe them in a GCS you should run SITL externally and use MAVProxy to connect to it. + diff --git a/docs/examples/running_examples.rst b/docs/examples/running_examples.rst index 2989bb3b4..4fd710a46 100644 --- a/docs/examples/running_examples.rst +++ b/docs/examples/running_examples.rst @@ -4,14 +4,20 @@ Running the Examples ==================== -General instructions for running the `example source code `_ are given below. +General instructions for running the `example source code `_ are given below. More explicit instructions are provided within the documentation for each example (and within the examples themselves by passing the ``-h`` (help) command line argument). .. tip:: - More explicit instructions may be provided within the documentation for each example, and on the command line using the ``-h`` (help) parameter. + The examples all launch the :ref:`dronekit-sitl ` simulator and connect to it by default. The ``--connect`` argument is used to instead specify the :ref:`connection string ` for a target vehicle or an externally managed SITL instance. + +To run the examples: + +#. :ref:`Install DroneKit-Python ` if you have not already done so! Install :ref:`dronekit-sitl ` if you want to test against simulated vehicles. #. Get the DroneKit-Python example source code onto your local machine. The easiest way to do this - is to clone the **dronekit-python** repository from Github. On the command prompt enter: + is to clone the **dronekit-python** repository from Github. + + On the command prompt enter: .. code-block:: bash @@ -22,24 +28,28 @@ General instructions for running the `example source code ` example, you would navigate as shown: + For example, to run the :ref:`vehicle_state ` example, you would navigate as shown: .. code-block:: bash cd dronekit-python\examples\vehicle_state\ -#. Start the example, passing the :ref:`connection string ` you wish to use in the ``--connect`` parameter: +#. Start the example as shown: - .. code-block:: bash + * To connect to a simulator started/managed by the script: + + .. code-block:: bash - python vehicle_state.py --connect 127.0.0.1:14550 + python vehicle_state.py - .. note:: + * To connect to a specific vehicle, pass its :ref:`connection string ` via the ``connect`` argument. + For example, to run the example on Solo you would use the following command: - The examples all use the ``--connect`` parameter to pass the :ref:`connection string ` into the script. - The command above would be used to connect to :ref:`SITL ` running on the local machine via UDP port 14550. - + .. code-block:: bash + + python vehicle_state.py --connect udpin:0.0.0.0:14550 + .. warning:: From 0688be2fde231f2514c637d27cea095b5d11a845 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 12 Feb 2016 11:17:37 +1100 Subject: [PATCH 306/475] Clarify platforms for which SITL binaries provided --- docs/develop/sitl_setup.rst | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/develop/sitl_setup.rst b/docs/develop/sitl_setup.rst index d308d7881..d9131a284 100644 --- a/docs/develop/sitl_setup.rst +++ b/docs/develop/sitl_setup.rst @@ -8,7 +8,7 @@ The `SITL (Software In The Loop) `_. .. note:: - DroneKit-SITL is still relatively experimental. There are only a few pre-built vehicles and - they have not been as well tested as the native builds. + DroneKit-SITL is still relatively experimental and there are only a few pre-built vehicles. + + The binaries are built and tested on Windows 10, Ubuntu Linux, and Mac OS X + "El Capitan". Binaries are only available for x86 architectures. ARM builds + (e.g. for RPi) are not supported. + Please report any issues on `Github here `_. Installation From 17bb5a4652a28458d40688a5c2759c823b03f4e8 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 10 Feb 2016 15:19:33 +1100 Subject: [PATCH 307/475] Rejig flight replay example to use a telemetry log --- examples/flight_replay/flight.tlog | Bin 0 -> 2723840 bytes examples/flight_replay/flight_replay.py | 260 +++++++++++++++--------- 2 files changed, 169 insertions(+), 91 deletions(-) create mode 100644 examples/flight_replay/flight.tlog diff --git a/examples/flight_replay/flight.tlog b/examples/flight_replay/flight.tlog new file mode 100644 index 0000000000000000000000000000000000000000..d2c7563d7cf5f5b9121f0f28b32fb22f1fb68c4d GIT binary patch literal 2723840 zcmb5X2Urxz_W#{83^=2RsKY?x2$&TEVg?443`!DELES|K!x~XBqvDz~yJpvbIV&nA zK)|quHD^#%RE(fvb`^^ERGsc-hMoKK{m*?^?=$`BQ`Ob=J$0(;bPs20YjyXlZ9Ssm z$~g8hQ*xZi#z!1GpiLlrkW8kbM+#-;vVh?5Xb&&1)*-&W;n9&Cr>dNcV1pUNR940< zE`yKEvlf2Y^b+BNrL(IVo*e~eSG7X0MPtH;NT7uw*bBg14+Nd^2p`J8WRF5wH3s@c zg@r`>1_Va^zY27B~~4iEM5 z@n+4T8hReVcFPDK&cN?pg|Zp~80O&}&^?@zDqRx{b&&-4??4kczevz`&4z2&|~8b0C5pj}g8n1J8RF$}|E9H_Rsx zFDCyIf}K|pK2id$^}%RpZ%%cv1VPV4!bdTXHjj;d(OrDPx^k-SQ3!g^C8}OB87oF^ z(#^zV{2e^t|B;x<%Q#O32M1*vZ{W9m&k(*h+J$T9_3Z|EM0#+lS`844NhN$AtSQ`a zTLUm47{Ir=Fc?kaI zK=^3MVr`j6gjaNUpij@}D36|$R9(M|;1IY!eJNOc!?#do$3WKT(NWQGHJoa?0>NQw z!uMkq6FU{k>=_v55#bZ<>l^J8?BOZze-**upu7GQ%(>%ND09%W7={-23d$MriSRKJ zSVs>GMR3q#v=|4yGL{w1buN_Em4$|TQ6)!5MlnTjs*m;vj_yqO0SJQR>&e2yT0$fC zj1Kn+X8m08cs_#h3c?SR!1@gIiG(g0;SoWbN1=^FaO^F@50bzJXwfU$%ijY!IRzI8 zPGtNt!Vi|fhEma95n-(VD#o=$iwR1?|0aQr7#JE79uN@_!b~b$4`- z#99%qdfy_nII{!cM=&rE?o2ZPoedj&rqFw4!&Q%zz~&4zXz+kxXmL&f;o~H*1zOZ^ z@EbV@&I5ljN&=mvqNN6RZjImq@E4;cuq6Wx8oc3n1Q&t0#z>&ESjX}P&mDr`61X$* z64LjpCo}Dq@tw;w;%|v z1-VX^Ko1`WPyA%Z)h z9erH@Iz61dkLE zejWqqIO8Yt@DB@*_6vnSj{xc*RR!k|JPvnez6AQ0gWbc~U?|_}LD7o={9sYltxy(-U_@9z5Dh?S(X0MJ@C<-U0Brw{3hEf72STh#!FA&hJPS@L zNh&&652UdVfHwpco}WqhKO`^&!H}>3pI{i{V62gE`vooj6G>Em>PJ6Yh4|?*$a5)J zz;+8o3tk~Xq0yc`5gt&~AR*4Vo<&q9`XTs+K4|(T^tWZK4%sj~bVCdDUIsxh?hz3# z@1#QT4m9X;26hH8OcoRz5$)~c8yFEC6ygncQywpL^_)1uuaK@PoPl9J5n&!)5v)m7 zO}3)NhtQxaB{0GOq)n^?Rr#;nzz=_bvxRF?f={&p?YY&`mZl zkam+k3=H#%4hR;?mj8`o)%VF@F`0sWkNsUJ`-OoX!G6%2C<$>%K`*p;A(HSLnZ-#y zg|c5I&?8a+drw6$4~EH249th3qxFi$tC7!pg5W0*!)6NR?}noLN*1ALAff2Qe;N3r zR|mpxpWDk=m8Au5*`uY)fFaXFn5&S>xbY(=(sy2 za3BK%eLTFQ!&sl-R4q~vOj=0zT@pB`91M-{@`p~LYLScJ7IVVyW+3fmgBchR6^hdr z+IzN*M({&C;rB=ue`6p_-J`pJYoN|kJiUjm0oAe(d0q8HmCxHpIJDH1r`0AxiUz(BCf8Y~`=z!3%@EBY2*byOBPEb66wpNr$Dyp~GT)YjKO}*1h9H!!8i%obS<+m>r%K=`LlDYVwRJ;_+bYRRc)eMT@nlJG|umF|ad$V-fV~9u_8oGh-3#xt8$90bH}X4#dgh z^ehH-r_M*!mc>pv+}87iPXjQ;BniOr2ztQK73vd4YoLl|VOtJ&B8BkjSVyiq_TX_(NERnCu$5l>$hk-a zTdg8|CW3I)lLfH6edKE=AlL;gW-*X9Pl5oJw~w4>bITmrX>d~60Alk@(YMIjN7e8K zT0Fal@F$tYxzIdQ1+ct*RD^l69Fy*Ogg=FKgyxy12V(oE@=TdUli|=GPgAgSFf>o1 zSVyUS%xY{waF&wrXP8CWd#1}g!@Q$Idj>^&g>(;Q!^e>N2wsJ$&fi!xfWI>^+=osu zBf`BR!a4cOKM;HlMW24-_ zguf&eJr6B{w1j@k$(>omm}5E|+VL_2smGl!qw$x4$E}};7H2^>yCPX!Ab~>6&&hkU zd0UR@s)dBViXhZ+Ap>FMQCPZX2F>%i99a?E}Q9pA#DP8G_Mq@sKReR{B>e4Nn2%$mehAubF5I|sj9eU0$9+1Ugt z`Ug8ZAh?SUgr5;1w4$-E5j+Yv{0;*XPZ!Gm6e=1T9T?&l{2>WJWmV#4P!&;il1^bCio=@OZ#X`@?eVYQeO$cFL)4VsBJ#wIuvQ26Av!YXmUJBg~JDMlfWu z8G4Q~;|$>+AqcnRFBwGNfl+XOBRtqr9w(nalhsL8c?;q50bH|sb;m;4S^*3U2!hq^ zt{{I^AN1fVyT*in%q%X1%U>r83Zcv2(7`>zg6LwsqUJCg-SjcP9K(tRvjZ4GfI%508lUi43J3Q8g6ZsOl7W@B#o^w;lsvayf_% zLt#-i^j2>%Q%!c}i92Vs1tcS-dR3ubaE*AFH9a|zs30SpLMC9}1YoXT#ggnuD{ zn;FPPEwSjBd#vcn;pT*Y2_Viiw+I$txi}z_P8B)T<>d&j2k;fMNPXE>S(sOlN2oYM zp&Ib+f#3mu!oS9%;a+bOz)(&775B|&0%5sfF9U--{K~=2tq_d8M)(h`j)%bFJ_h=LyOk`qL2p?#A%*ZC znMJzDvY&x$MI=bq0X;@JYie`0myz+#FX81Cf(Ev}l*Rxop_J_J|)8Nel{#_9@X z2N=l0V9{br96YLizC`#h%wi&_@E`+es4j4vs)w2tZ7~uw^A*4o?Ps?wlpR8go&j(< zh^nUNBRIPm;lBZBeY9JLLRl(W)CWJYC_KmF9XNo00SpUR=Tay;%s^;IAF*uJ-EPcc zHIoR!f0w``BIqfBS25tKX1k2=KLF&oKHvb3G7x$X`1wE&8fGf0u0)Hm(2gY%c#MJ2 zDayf7W(Xz>CVVLa={)l|1NCD7xd&T=%Bi+Ahwy}f$bdSo-uFOWJ4 zy2s=bsBmP94>^_}p&d;TgsVQO55iyr7OS$whn(t_VdytwART8;AqerFA03lm`Au%# zoE2T&E{^b(u#V7iPczUrFr=rbF4Zp&5S-bD@Ja^K<~dUi3YRUNq8Hn zj<+Px2ggiKQ9A%ZdS^h`;LT{KxGjPZ^uQvx7qsKU+X&vOL`==ZVEgDJ{PGpt1zV|@ zJL1`)J;UI}(JR~)$UsexZ-lSKK-%r^iXcp~U>n^7QY#w1M6h=iqN=1H8aLdJ2S)f4 zUMm%qBUor9bq#qJbi10_(3rLHilB{hB~a`das{qHXs#9$-j0E^XWWxOv1_Q-SzysG zpw;cAqVG$f*fmtWG1%6SYlL@@z&r^QyM}z!EoRX=0Q_?u2GXAKKmx_Cp*X~r-E*w_ zLKmvbK-x1NmV-jqP;645#du4?*JB{<8IL4T>>Bc>;}M+G7v>&9_!vjm3 zu>&l8X9sLqZc2{LR2XaPOIMX&Zd&L}itp&#Y-Yt0RRjGQ-7?gm&AL8>Z-|wHPWD)` zAoeo(6d9|7P3k4WH)0^|CQl?#>?iVv*uQN)!r;+ZviMX6={aGr`y@@3q%P{2jJbJSb)e3XlaKu!!I>=y-&6vhBj_8+ zVk5e`rs#v=I=>RGx|syN5WuK%aJEqNz7oPWm%x_@;zkh522qq&!lFyzCbwWqO3-Viu(p!J?=i&ipOZAz_vJi`0#=8O}e$|cyFZBz1zeQSs!oJ#s}PFnbbf0Mb-PHkz?(kI5k z4~-pLNX**EWK#mwE3Hg8bBt|lvvow#Rwi4;arwcw&@bA4bRhC}GMS@{JJ*1nTgze< zv1>1r*@#wKtBYQzJ$M<};)jx})~Jkm7#SCn%4jWgP}>eNSx1q696K#b{Qoss+R=4f z{n2j8CQ28XY?FAj06U~MyA9F0%4Buug^QnuCLBlqiXm;ygqtw5^+#5kokJ|Ka+AsG z50Bj|KW~EnqvzzA%FMV8*j9F}&k&7HCaXsczBGMrdfsHeX^Cl;X`bmhFuC9ZGi858 zM;zT{G7n?aYg5DjJvVu7QiJpIz%yTY6KzMC%x)amFK!a4*+QF_orQP?iaH<$7s4qU@%ptSQ5>ypmL+4FhG-3l~2x zK?3xz7<8=Qh7G+^m9h0L)x;_slr=T(n1Qk$Qf2-41)+M!h$aG*MGd|Xl=Z_j+w=iw z43Y>j{;t1h8FB0m$}&b7>gu&AD(n3VX1~GCn?$9AiqQ|tcRhuR{|)OU6KxNWTo))f zuXl)!3w!M1`us%J_qwqekyT6Fntk8wS_%DE!v+h8sY(pDhK^>I8@4MTHa$UyQzGkh zxSRK{TY>s=*4@o zd}Hdbk`C{AoYiek@^^Qdg7#L;B__QD zz_erTM?+c|=pFwgr`gRwVmlrLw58PzCLnw6L78RAyE4fA=iZjB5fLmEF+2pK|q)%lGA*0GXfJ68dQ4Wu-W|2 zd}25CrviG6Q;!zPNMbupPe7Ne&Bzj)3k77?ik04?=3Jso)DzIhmH2(r4n#X01oQ+h zT>O-Pc<3J$kb>(rv^kDCEf#Ua>UR)ON$VRG1Oyx3^}nFOEvtxT1_+26d?^Ts29+qF z^IefTT|^vbf`E)s#s!pX&dzi)7SAfPXB0}3SpO@GFYIycu5%|byyhhE3JEbGYY4y^x|$zm%v2_2-f z|6t;<2n2MyEefLJyZY|!mo{)uvduFPQ06_f8vc!_7V8gYJKEuaO)ZJ-5>VFR=lM)o zbwOEGONz@>EU2W)`hhcP=ff#PlLX4znn9;)&&$k8IF3F(gG1BK614aCGGg%uD2r0$ z(Fj;0Ek5y^(i=C=S~+zl_J3AT)@Cl%$yMx&?BAGA82z_$h3VQ-P*z(uG(EY_ifH8- zN)*ckWt|Jh?|eHD`EsVL_Ji@8emjWWik~WL5iV7<+S8cWuGCZ3=l-)RC~Ff&ajlLf z5alX8Wp%~E5YKUCfpo|FqcS}8ixlh#Qz{rd+J8{0*rnomzR|Q6Hgc%rtc8c#3wFNLH zMwmGmptN}(PSn+afhThQQ=f0|(9Zj-L~RL-sS#$~Mr1y8CF<(Hm>FThu=}?8aE_>J z00VQX|CDv;9NPKViKuG=qcp;t_#`mtM6Ct}Wb_|9DLA=oD{n@$>%g^bqc?ba7af=L zhwJjInOSRX=4SYOu+uqrTj!dDouMtijM%IP*A^IdHckCVsZ&Q>$vS2?OLA@9Y*@K% z1O175gPv=n42{#NYg><6X&aM4w8`Mw{A&zwt+e;z@u*R-U?+U0J%6He@U83qPj$36 zG?tib1lQJ9&23Dm~Ybacl4TkHsJ{csl;M4_`8=-##71P z1!Dx(_M1P^Y!UpOQ_tQmsg2Uye8!Xt{?2L|v(e5ZzrJB*NAzQIP!UI{c4!LG1E9Su7- zoGPmYv*=o-v6x{=mqRNVfZn~}Vt&K0)wS*({R~T`2tv`G{_Lv9|H~}8J%F9B6jtT1I<%bZ1v%Hb~1r&)?L<_5h4sx78nns4%~*ddXLqR>8npwhG3s?Dt3} z%p{tFFm_cr$#J$Yt+FmLg=v+X!>I5mMx~w$Es4b;7`rGn7NWvqc8^btQr7r`+3>E` zhuEi97`wRG4^B?3g~k8G_+t)+wCD04tN%>G>YhYuy*F{pgptk|WqhRDy&lgz+=pnhz|qn( z_Yq%R;-gKjZtb$N-Z*J9;$MAqOKq6ra$k*XHq7Cbf`2%CIJSA4XUk|S-o$LG;Le3nlb)q z`9ymPTys>*ajwIzJUZUI~ECa1wQw^DO&u_yW8P!RJo zdR~}b@SHhl`tccJ@wecG-$`D$CN^%DUY102R`9|jZ}oENvA(iyP7{?dZL`KHb(eT= z;&2YU@Fg1*9N&z0ue-$3y~C;$gQ%0kt+y_xl|*%3-wW?T#}?MG1F^jT$~BY8Vd4Q@ zhkH_{EqPm38UB9}Q?4zJHeoJviRK?ruHD~Mxi8D=meA!8!lKUMrHe5F4+~Hdi;JLK zd!Py->Kr)m!-T8bem9nwT?W_LMZF#-)FH0;?V}DvaYb;Q9NyW8ww;Om zD)W&0(T7L0hfU>rqQ^Rp(P2a=%muFf)NKyN#gB-=mc;hDp4+T+r=r{3f{}8>NZ7i$ zq31RmZ)H`DNQ24aP4JMkJBlCCL%xNTcoWWH=$%4jFP|q?x4=XC%H_hw4P7(lxCeAD zP&^f(XQ4!M8$2X6_*!q4jdKAnOGb6?U7tAK0S{@6GVURRQP|x_!HW1@@R0P(2~Typ z{L(9~3)W<1xsF?!(YtDE-Q}mhxwc1t*F75?p-S+Odk;l5Y4z?q7JsQFJHR|7JFs{z zI}kYsR(A9B+!8Hi>McCB61MjqfLnSGm;6$4OMy7TNA5}_numg0`r~m=mzd|rUBetq z1hgYvF$HL>2cri`E#pB@J$>N7XDLs(gL7G|rh-CaUQ& zF=dkmW|f7=!x=KRLn1=FLIUL{u*4{@zGBK|EQBakBv1-bdZMF?>M>YM*`yZD1+Z1Q z#TXuo9u7OU1uW>H7OP62WYOmhg0Lknq-@eG9t#0%U2ZW2hu&VAYhuc#4Opxufs#eb z5@xYi^BrQ!CbeiOfNjbxj=@m9*HUjx+2lBCvAP6G7FV=Ki@S=&luf$xU4x5&MC%|a zOAW%&^hOAtYAK~`0$7uSz!tJj=p&VoE)5@rI)Z_HV`1eBV(MD`(k+=f>T!?RfT02i z2aFiJhkYkcAetf=Fbd9doE;1pbxKHCDg2KvQw%SChXHfnIX1-N4Gb8R5(kXwN~fz> z+NW#8{%r++#l;pnwV-v9J~5YZcK0J=c^TyQo4$cWD-u-Y#xFM6qS8)xF~j6&%D ztUfU*g%~YX&Amv#(?6vUbE4-A>2(b{!j8poam1nwoZ$z!Gv!O`(~slPdO5IQBRJmO z`(v9qjh=`HoM5L44lu{d4%Do|4h&GhumQs|i_?$a4sl5svDz(ue3>w}&PTsJpb`w3 z4a6aHD9$|w*ux4vDByi?CJJthYi;-RR~q-Xx91!9RL`zhR8x5NLay&q_v~Q@;%b9( zO+dMR!|a)I8$dotEm&Zrq24>Tbg$ilWXl~yqX6Y@yTox??lt6tz#WG>KqqO#O55W~ zKwRgR#KIJmyB(-a5bD{@`f*~m@-OW6ar;^ld$S74J;=SRs9c{^Eb?$5F{{KP4Z3uH zAsW9ukw6qmLAkpd<9BCrh+M^#I}vxS4l4*zMxwAN0n>Jl?`#i+K$>^Osp(Gx#Nf1 z8z}byRjvc>5sW(5muRYia;d@pE-((pZPQWDzY#}EP_8k`xN_I;W)&W-fyBFp`U)Bo zj|Z$FtZW1!quNNwc&NF+{2=Paz*re!2G&Q$2EyDXz|cM}wut!ePSnO|8whh9fw4Bi z_keJW)XV@a!ODRzUcx1`m1BeyQu7gQ_%-RZArg+1}%|uEm2BI>-0O!uvo> ztiVHdQFA*7<5xQih`C13L(=MpWAron_)KD9EqKV!Qn;9dL++TmFNvy(=ppy@YSHG6 zBQrUsMG-rI9+Dnd7|9OApY$dg8^J?%f9&USpKIxM*!8mDA+2z2KmPPcV(Kh<$gKnL z)VyWHfd>!Sb|gBsO`A3Ddybg7*E{~Jfrp%f<3{|;P@=Nc_mDQrnW1rm)nXkW^6+QXRK3UkG5#0Gw{&12 z4S0D9(x6T(nUnj;S<&Oi))y02>HEoSIr?~lzc*wZ`-OyfgH6SHoIH-7n<6HxQj4`X z`iy{N4nTSTHE8iF1e5ioI%>J_?(pDmba+5esPL$p<7@<<$LXh^))pHamOz8qlLCr= zP>2bKlZb5t7`tv3HWS9K$7MDppV_waD>imz1~Zch=W~drA&gzMu5p|-_mJf>{(w!i z`jBxos`Ov%p9wjAiA5tAyC}5}#;(cg?1XTM-JrUZ8&j*Vrq6%8HwbaWpp;}$6) zw(T9}ZrApsZvM3X=~0U{y81QiWTrRxJ98r}g6OzC+we?S2(@ogVbtru$y>G)yAb;~ z<`7n6N?bNEbA(aPmt{eoK8HpoOdyJ;!l<_#w{WIxPbTtaY}AWFe>x@e6R~Ul(@`%# zjW+MV;NL=T)EnM@d4*ALT|*=v=Mklo-l%u)I{SWVXB(nz38S7CnoRu6g%OYby@kQW zlq()m#Ru8&NMhv-qu$mx%?w7pJUZ%GzCvi=HKJ(+qaHQ*-%(F^mTYQHEOBfNqnKr!{*4x()XPM4nfuwQ!}*JZ2gxxLw0oxgUomDuTD5zuF4N44iA`H@ zx(y45q+936bv^S8o$fOnFsHdd_EkGQr~7!)GRf&)?2NX$L268UaJtv~t#QpSs-9-M zZIdrbQMJlMdi?ebrnFjuq2llZm;Dp3|k(ckw{e58Dt6*Z+j2 ziRf&my-y$-H^GID>($And5imQjnd48Ir?K;W+Sm`ed3@4Z#nNBN{Nh7yN}&f#XZqt zw1KzmV}pFOKT)~sdrJqr&gqlK5LGMvsG@c^cE<1X6+~q&IRAYqu}xc@$4>bB@;&ST zbN=kW&VlTV`IjJ*up`LZeTb_Rn${IUQ%qGJf$I?SuTCSTt;GSL5WU0vM@2-_2{gat zCfyMKP*xk_Rhs2om%9mBmMRRS=f8v9{?4FzN^JzqtM~mlu~b?7j8$Rbh!kS)Q9-#G z+?I-|CYJjczQ{yP%sfH4^_g;WP`QgLLzbnNpj^{INY;RrF>j{amL~X3^E_hb^Hb%X zo{6+i8)ECLr`$S|msL>i9*mY31->LoKRxAo;h4K?;h*bb6cfwFt1LZ!V%Dw#utI}dEY!h?=JCcbyxPo%&ek=`_@+Kiu*qCTTK)GXVH@Utout}S=bFHM@-Fx5Y zyicvuEgFmLM@TgZ1?ARPa~t-uua?Lc67z0)%B9uc-xQD4fNYE~Q0`l}0k5QRsr^el zx^xfGgbT_&ys?8zqnnv-ubzuruOkKf`@Ru}2vF{r;i!_zJ1e=X232#9+dthvx%1Yd z)wE=y>aMTcr2*_f(w&|})ka^raoB^B?p`G7wh+tO8Hr{4WZ}s0Vc&b_J%M5$2bnXy+az z6Sx6W-w0E;5Sja4M6Cm+ff2?DH)oRWXA!kKFb$0``Pk}7c|D1`BQTAOFtY8etUp(S zPpv9=$gO*OHEdmf0Up?Lo*iHwk{$5*mmOFZ0wGlojOMc7O`%*^czA&DeikNad6Evn zfeP_Wu5=C29>FkpPm>QyU-g?3!6`GvH@R{EI&eKh=>sXzo<9B_Jp$leGV;6K5j-C% zzRC45M8$Pjkj7pi8xashjhg*}izdq+ts;CcR!4tWm8{DJdcfm-8*Tms))r~~3heu#{){=^a zfz0BHMc|+N!q{cL-B%jB>Xf{PkP{a~HW zu`o<^RMTaZtHt=Oh4Mcs#Vf6@RY)mbIZW~YkW##IMyz2<@$3dGDhyLa7$dJ-qBNRP zyxO8ArWDf)7e9YOa7q7gujc*`xAW`@R@a$;DaElneE&O4nIs{!fy0zyYVegQK4wFQ zse3GMYaaTK)u$F>O0hA@_%Nl;MfVby{vmOOBmS zdSlm;Q_IyKUEsc!{p1P(rUz%zvbER+*uOC@*m*ZsjU#3Wpxh=*x$iNi+HAFuD5eMj=9E-c z?B?3$L_U=Tn9Xqv*xaWxv77eO05b>2oXulC5!*z)0P~-c)fJT6@dlPOtpia`*9$Oz z{gZvaMG4DHze9jYFI@bjfNJRu3xyk*}e)=tf7zaW7`~v#X<-$pTZ3&7pXS}c3Y2U6U`zaz`XFOiHq-%MQ$$_ z76~Fr=TF(%v<69$EP9gU+a7^5UKFM+7@<<%iN^2L_e`-mcL#ea{@kgx}Ll5WKdr&W)C`vJ&P2W$J~SEf~g*0 z5zAn~WtpHVA&+^_T9~#iXQ~qNnD?ZDs#g3|RYD%~o+sA~^O!|l(0{ATdeOUtVf~)B z@PxoBJymtZwa&d}{+P#1FI@aw0Y%ZjchF3x+_@of7^Cf-4Y><1eQBI4%28;C#AYNTx^;9vja0` zCr(3^I6m}oFB%!*J}NxhpqD0GM1G_VX3UyGnR1gT6BBDwJn)w_QF+3+Lq9A}+_oPc zSQ|~$UNGfo%n2hVGVH&u69nc3QF{Z^#0b+q44HL9iP{GkM5aSgKZOEV450X z_%>)~J#3r!0n^L~GcZ+Ppg#V_$l(s=ZcBSw0W*lE%Wk#9O*QifS159cnXIOj)MMyG;5E(k?R!%EFZaf7cjy94+jg-@Rz84DMNoS7P#%L5!9)2;V#;z$*m`Itf>K-} zKX(R;{#c}+vfNw*+lY0P+oCQ~J9ZFLmgyX{g$TBlKx+(gQoAn{Qt(XC^#)nZo*+@fw5_B}Axzt3Ll||q zH|&QUf?VL#AP1dgQlIOhR@F9AGd^J)$XgCAa}`Bq0xzkg37)VM=_4`v->8 zN8YAl60$MM_%QXMj9ti46{Of@LGVYuZNci`3;Q#p*q_F88gqZtQIm|X7Wt!OXmgO*8 zjYQIK7|~n=DWAxvDQQLUjDj3yaWw0hzUahGu-6kd3NC?^DHR1$F6>q#bEoo4G1@q3 zL+me$^Eg4uDcq}yPam9Wiuk2v#Ow;p<3d=(c^CUj)~ytxxGF@Pr8v>Z%BxT0*I2~) zCr0gAA9IM^^`AzZ-LA5dvV(QR_J-a(PQUR{%2vCO><$lg-_(mZXC>qJad||03#3dh zT>LzNXp{cEg@{wZr4C69M>b(DQCSLO;hHtE4cacnu`qkCmK|VYAv^E^$HJ2ZHpJ>S z#HfEf8*U(e_N<*1dWe%>A!+aq%=~B-=o1K475ibeMihTdT>d#V7dB|`LX2vRGA@2g z46aUXjwIR~5Pv4vkC(gXu4$UMnV6o+`n$`o8C?<`b*iw~w2w8|C7wERjo9SE%&+xb zzw`!GirvO;zme5v$tEdA4J<##>fmbaGSJt{)qR$-BQ1O@ck3fk8v}_$KFs`Xyg&(! zcZ+r(#{0Uv6>KsPe?3dapIwWh&-jDM>4#eykNY0s!o_}L-dp@WQQ9KtU_YsGh^V?yP_ku|-8`B5QXTBtM zFMldI*stst5!$VbZt?0)j>42#6Y_yXw^p1XPUi z)P?i6h~rxjkTJ@*fZm~(x$qQ{-`;_M=$Yd_w%27___#&1JC(I6w_8SLNNZi#lC8&d z<5*oTj(|naVi3?TkJ_dmcmCk^^u>)V_sT0J0ab%ZEWCmK;`9Qde*ZrN)XWB%b;(5g z0R(hy=4n@pjk>fy9a1C#g(g1Jo%vU*dxInG#q)iM$wv^7GrZFTW2cLE;XMkU^aMn! zzb6k(KaC(3pFuz`;Rbw?);A-Bi}+zfG+zV(6{o9RylXvhOFmv8jGn)~VKy#lIuM7i zAfUquD2U%*n7dzXT+O|TN3hf*=>6R(@H61)rf)FHQT4D%-k8M&qh8)44juHF@&?L-|8OdBK2 zu})~m7p8R)z_c~O9LD+e6~CH9-5r>AMwm(1`L6h_B1g{x^-{9zZZComn1 zFv~k*ef+<|t8jpEF~W2XKqlZcQAYveYJ^#W!TFUgGl;quFm6Ve5l+m`waT}M?Z4pg za;r^~99}J9sjCnYkk*w>KZIn}4aBs!7}S{K>fALuCDD8bFIe{(eGk;@GFw>c`T?n; z_=dG;Y~X9nw-AdT-~}nw8FRnUVfR2O*Kewql~*J_jjxkcP7Il)s?_K(KCllZ>!_p`?*CAJe5`QEh^(iTYFvl!(PV<(M{a_ z*n!w6!99%%bWFE?_QLIJ!<+ERr6kEc{Z__o=9npoT4lsNS;F>9&C|#XhRv(W;GQm@ zKJQx4#xrf+gM*TL(yV!@vumf;X$8ltwPW?TYOimB`k2X=e+#eM~8$)NY#{AjzZA+llZRIL|C`z0AL40 zkYMxNn|w=rS1Y}07XV!h!A}?`-CGLl7BlW)vKVrah->n(Z)B>Ml@`C!DqB0(QjtsJ* z>Tx$?{nuNFU7epsUIPNy`FVUE zv8}7;+KzP@D0O6XZ4-7Q*&voE>*={Rv)A~&?h?_~2iHa~T>OZx4I{60L(XD&oOdFd zSTz9G_ImJa1J{;Mv!Yh)M1$8mv&_?a)S$j=!x!+3$5=M+Qyy__1g^~(W!$xmIl}Be zXa$>Ajls3iGc6yq(j^rPcbhlsRMzS6oPcum=`2nt{)Q1&swTw}+_j!LdHXyt$swqu1551dp9NMl4!@ z&jUBe6-go4ecW<>a1$PJsUeJn>zBvYX*+H$p7zLr9bh9NJ7E2m9eB7ag=m}vFWIGX zO_z<^{&D@I_z~+eTe(rrNd28p99n{xd^H5M^~t)b`|eMc?uq-trOrjWN@t8)A6}0q zDrfy5t}Bjmk7_~hYy~2HpS6gI6rZXVS0q-z;-Wp~5IkxPYcs7uq|YGuq*AU4BK^wV z<#Qb#wXw$A^r&M7v1kJ#rIeTxa#U%%fmQp_hqc7MZ3U4Y;@(zFU0iqr@z0QA@QWCr zJoLaXzqcV~?LfJXY?)%d8T&S0ZcY@C%DRfakF^DM!+cdXk#}IqeZCo~I>U&a%TJZ- zj#|o(w;{H!ddj`);w?2UDmT*=?M~AYrJJ5|GuPqwD`1S*fpTeUh#y1cE+29a2fqAW z5R|xsa&xm6{a3lSLeb!D*ocJm(|XjPzH%`rvBEW*{7-XT&er;52m z+ZmKg&)ib8l`engNH?>Cr?M8?_08z7cGRVwt#fQLPD!6y=MftZQ0~X*+Ub6sp1Pe# zx@oZDxC`Ca)25Km==ndCyYf4hJKBfQ~lrCaKN z>?8#-@dkl9s=3KH7k)Yu-pA^rC(!3meR2}2B+!*}@n{wVC4Pe3 zR!*~Y>3L_X+o$9Ug4_Zek-FcRIQWCyf=;7Ks`Y!TyBPUZmlEGx>Jjw*F2Q+yL8OA% z27s#at(P-Z(RDr^vV^MuQwT#}a;dPtUoiU&OHhqJ`Cx(+!6cFw7h#t8D@gAi+<>o=^y=X9 z^oxfDL=!DYuk#8Em-!Y)-F)X^{>E0W$PJ4meThR~kX~Rdlu~QEVD}NnH16Lzb}^7% z_&mlJjXXnC{qz^*>!jd;+4;n_KWOsf*tJZPbwO>mB_D)`N>{;1C$~j%4QMh3M!KCv z^r2GJB%K1|TkB#UBDD*$Jz_zVl)4Jx=&8?@Gc%Puj&w!0eh}5K`k{z526;tyVu(5# zrtmr=Q~1(MG<^qluKNPxZiM+Z4Vk;J1Ktmqjz*aFI1Uuug`MmEz;rUg+~Ltq4lI?# z0MpqBV~OssDCa3r#{%PFgsIJ;om{xC0l;_~VQ%~)Ft7tY5Ew5bOl#C_(LLA!9|VlI z5hn0C+PMci;DdqjF~Y3I>Ghi`=ZXD*3a%|Nrl8{H$CGBvvZQwv~ZJn5FYy1ko zwTG41L4s=&=EQFr-XikB%(XSSj#S5NV)xrmUE4$S5O0RBBDO>RPuKPoN0B!Z;CcL^ zdakV#hRko0`Vj3faBZ~biJu(U_@IAp;2|#)ZtjpCfmpZqkeygl3_w@(YTCwgJRT^8 zCtTnF2B7pnJVM2hrByDgP6ji!(#d}N7>dT%;dYXFNtOZ zct~0=>LD#*LAN|>=eZK8=PAT-BzQ<;lyMJv700>a#tB3l2Oe@4*iSBKu1h)-?{%{Awq>*K@3%hosf7r^RE(lZnMRAvh`bkRC(W(GRekqZu!FNV^Pkmluy? z-OL)K3c<;hWTfgO5r+xjAxBI^$9APfRrlF`M7QaWjs_lb!z1K7Y$5zaX#%gK6ZlpJ z6ZlG(5DbhY{3Hg_A2D?2;791-$10-X_XLHX>IugN`fwSN-zQTrc_I9$XGacl_yc_~ zL7w$bMGG9PKNLg|K7m=JdH0<-`1NLAANbX(uu$yB@}N&xbV(B7r(hjnA*3@G>L2JG z?HT6L)dzoRR`Kmu27dIdPxz@6Omu^yJ@i3V3&rP-2>t>~E7O=ox(4HkDgR+U@Kaa; z>{kfoPjP|kWBg0PCrY3fO{b?n%_jX=p}gNHw3uZ{_~`)RqqW{52ub=r;r?(vs-<{? zKHiy0_}`hu(XdYB16S>AnDXx^)bTZhjWb|~YJY1p8=~lBjE0Ss!CDdgsLqDc(REna zpN7KT$xIlc7Q$0Hbzqeie&P#OX>qS=WT_W6&ZkKU#9|fyD!A!G3gVF+s~}d3!QU;vz1hIuvFFGJql^FiWDn6S0oO(i(o7F@ZQ^Ec z4p!%j9A2!N1g^~(W!$wTRcDp>G7^HYKftvu0{cbpTj-K*$Gg33d^&6Nnb{d3pPh8g z1A<*^M<6>pf!O>BuFd+CMf&e8uDYf0x3XxSy?CKNx*)d((tMZdxi-2XOfx;GYb&UV zOx{eQT?VeL`Pql?lBB4#?rsl``# zme^r6xHjJ$6vP)^?Owg|H{F{uI|J9|;l-?e4~NlijehXA6+P+qHU7l*FHqLaR=b(9 z8bbm-&w{_QvN!Ch?8mrAUDDc#sD|hVZf7w)qQozUXx4({Mi$ez$`zM6!22M-mzBU< z!mq;m#|d0oD}i60wpa&}qg3ewnptm?d0M#?Cr~A$At+g2L2`$<948O)-m!mUDm$~w zDVfxlm~8;b;Y-b$H^*<`Wm<}4L2^rC@w@XAhI1u;TS0R4!o?4~T9>|F7bK?u$xRwE3Rl=mqhP+Z z4J4P*dbfe(*dpcFdT4MMwD)$995q-jIq{j8F4&@_5F@G7LVUAyeQYz=4Yx^^zBjj{e@1~9VOddeL*aGRvuux7~A2j%Vo<$BpYbv?Z1mo%%uEJ?Y=hwkZ?1a;Pp^G3E= zV`8!wlndK9)7S(%m-B*WxA*BOmsbCee-RId_p9yy&x*<7C_Fj{f|3+Lxhan-xtx4f z+3m)4c)%GxTe+ibwwx<#F@ZQ70Oe-2MZpbhIKX}W(82D*7Zw{Rx5GhZRX$rwY!8A! zo#!270>#XzcWlMv4GewjOB=EYUaoxg1fn?vIt+z39@)YGsV?ETe4kbCMRWs<6K3f z3}SW!bl6e79EQFw_N>YZr$nMSD(LXv(fD0^Zz4a&boiqIezO>!O*{Tm9o~;ddTSi9 zP1DoivYcI6qME4RhF_duTY|ZYz2-!juBSt7Z)U;N#DQotK!^0g#ZN2HApN5{H09!l zyk^64uBm1%u{r@dJU;(m1s%e=M-ua?xu%Y*h$a(sNDYcQq|c_|x<@Uhja<{Corz-> zsLB{+TvY=yu)RUL*4#<=AJ;M&%(d|NC}MZeU5p zhdam2LVUD8zMT^v?i}zNemfN&?z|!h2;a_`TX{OnuCFoy;oCWLE9Wfx|NkP++{*9b z4PV4rdwN9yg|U6i+{&ewjJ=36w@T0id=V$TaPgxrAO$yaNNFm&f+~Ge@kN|bKaLp) zh{cXJ0SHZq#TRi>gW|N9zLXz#+fvv%Om3A)Pl;+6+y(k!k4)@F2T~=$kEn;kVuvpW zflY-^+GZ>w0iI$X0gRs!ruQmjrodC|BZ2WZ!gObgQ@K^9z*FpTzyug!TH>v*GPNsF zj{>HP5vGjoqvlqbdJ$&Tz;rdj*v-KDOoQth15BV1rXP0ID${-tbv!UZMwnqu&`#n~ zq8tkO4ZKkBAlamyf6(~ND18_NE|DcXISRT`ezUvteE0K6)^_ zhxpZ92m$i+JlI#L{i142F5Ru_>aHbS6+9Tn zV#?gA;|qw&N?dwc-K%Nq`)pd8TXjYxJAg}1^gtTMG}Rgo!>^KeBQkw#t-S z?H^dBC}1l9#juKM5DfdkDmFDW0hiAZksHO0jK)qmopTNQuUFI$Jkw#5^(*AOq^%c35j1FF8S zGf@-@?!FG2ROMDb!V!59bN8Md@Z8HO#O}>cdTb^6P6BhN~>cvajlXq5#myWey zc54I&66HI+c&Q2Yp&A2~L|Y8;61{No(->kU`u7&%B@=GYke+O^kz4a@1hIM#@sdeg z)_>i7Ax54xbJr5h2Z)!bLHhGxbg7`+-G6V$s$(@Ce%Jf67(RzW|3 zx1nd=snSH}@Vt-Prp(h>HdQ8Md~$4|v${Dwtq$9U%e6KeOl&@bx7ps$GW}quU2fX6 zTUlQkua)8@uQ+DYnm3C7*llkU9k+<-3_skn~WlA&f2FEe@w@EG#e(s)mgFuv|zBf2$gBDX^akGqRm##1d zG0?ypSYW7TbMXwJuY}aVkNki)2xg#xH&DD{7I{rG@#pU8!eI!2tqr}wXB<`d<{89R z4&EU7{@=_SIIxAo_d@VTe=M*STZ_!)JrqP^0^Y#$E5~Wz;auwy1?)Fd&u|m=oA0c} zf@i=CPyyb6QsQ$Zmz8t+;?ec+h?r>wZ?K0u{LJX2LB&rUjkNB_x*nx6-l_Ia#aY)5HeKf zTw~@b^Z1$yl_}&klR0CVLx@5M@rJrmhExcNkg<$W<`8Q4Uwf}}Zs%V2`}qCO^LTro zb3SLEz0Wc>6jSD0S zGf)HCaPg2De+II#{z>@N+FpQFK69iN+Z7pWhHY9Av8)U-@#FCoEt!B})l2;TY@dNF zn}bZyCy6pqVkBCH*FLeLYI;HRdlirgT`1i$(VjVGb81d3Bnk_ViB3?y$G`RY0FN2m zKTj?vH##ss(P6p=KWN&^gtgd`nu{kB>#86VuR{&aHQjKWdwNIHD7keNYjg1e>~tiN z2|BD2Wx{qaVxD*sMRkygYL~xyyu2EqGWAPU%fukdJN(xZr+5Po#J+^(BXaahSm7sM z^Am(xSxRJrR(}BYq6*J^Vs0f2t3IixlY_3Y!W4tuh*b?iCZ=~GZVroLx%ZPY1(`UG z9gbppIB~EBnW*v%ney7aj`DL<4lkeSrXdrjys*@T;6}2MS`+ng6sI^_jM0s&x@QO- za31W>iN5**a9Hdvy@P_SxURtHMi{xvYQy$|6-!JYaLSNPCr>FI#O5?}6c1tBU+I(myuGUtYV{O9BKw^R%^*qIk5{}O$@+1J?O4`haMU&ef)1Sf!(;Q8Kox%@O-<0{ zvTS~W_dULg60xr)V=N>rPnm({jeSwHW-KJFeh%|F=QzmHF&6S6{3^fI1pPFX73Q!o zx;(P6b;3`#AM5+@M|wOJ2x_zhQ5Q@wvhiClAB796I)g)zPg5R^9o{n&CJogXp(mtg5EMGt(iSn@!i(1a`v z0_7S(4_Am)syC#NSSg{0qXqs+px`7dYJM-`+!hF=3#FStZ?X5NcRrLT+5v&+otK6< z^11UDa4qF2$!(5@Ca(V6iQjkavPW}tPu9!KC)VwOK)D4MRNj{RxXwhghZ})juX-)~@%fu2`Y;tR_gnZq}G^@#6&jJ2+Q(*?w! z6ZCLEpo>V7`fa-rGfznmw*jhuIuqf&9}x4-(8E1|@=DYMibT(Q{hR5;s*BLWMJ4`l z+rR8QXJC^g5a@s_mhlc2NOpxDZvQzXL|W1iWnj%N%8*GI)hJfA5B^LI^Vbp6Zqgnu zu#^?#EVIBM#_3Ku0<-9bOXyLgJ=~sBFK{Qre1)_A4`Mn`Y6(>piZF~M^7-I*@d9&K ze6IL+tpna{)P~3x0H&V~%*u)a2G&n41WbP&nC@sDI2*(IvPFOypaT<)4sYiQ21LFX zFavd9?ib>-D*Q*}L4X;g1G5i1e`ga2npy&w!8$Ngdty1JRfv2kV20?xgy6W#*%W+N z%K$S}2WAO+Zk#JZIm-bvOb2G2A3m!(NNW$U>Rn+j!~qtq+JlMl6ZW*D`H7~MK1W4y z9v_BLq!cAu_4iDK{>~Ya%h>nQlD24>RWq%<>c-%x%sF@{G42i0){-q<{Rh?4Invi7~txE7ip*m)MM<<8|gL@M6Po4Oc-e996os16RRV3cNrahy8H8 zE_D^SqUO2`SwL*Ysa*yA8BoJjaB&_!dS4N-@m9ME1~8z8tAIOH z0Bou0Dp+UQQDZDINWXC3?i#0 zvN}?~#}Ee8XiO0He9gN-9eo+l0iwT#GN49d6m#&=BVehXAFJbjc=Rv;w$f~jQ62*C z!XV5aj6aXCXRM2=50hTCzzd3T_S+!Nz8?OD&GUna)g(~JoKouRcnit)jbz`|8BOot z%W3{2g_utU8*&kktcOHl!_EWXA zRp$N2blK7bg#UOzjHiLNwq?PnsW>C(S_bpY0fM%kKxE4b;6I(tv^A$5ySJr1#C^>8 ztG3>Fgy`0=#AT*LTi?oJl0}8Y`Q}Ic5IGFe0t8C5HRU><4~Qj-S)i@-m5B!rzEk>- zhFa;%dixLhhFFNnu>2Ra_1KPQe`@Rc@d)}187yamw$cKrwpL^QQ&C%|uVkoJ@)F`a z2eefeO1HM&#cssD{T?`Ba9d<1Z{=+=JRMLw>E$c@fJz6l~#Y+d&H6yl5fqI=Pz5c^G{J>Us*4)NQZsP<28_R%tV0eLX@)>MM zLs=30KMkj!R{C~1qFP!L^W{K2in<7aQx)&mOnPMU0*%Br`z{ds71{*yxu`wgJo*I| zb~uU{uVgOA?J(|YgMQaGr@=T`B@k#J3T&JBe4-!B2z2r*-g`Hk*scC6f#%g^Xg9kp z#CDB@Kz#?FNETle66o`HL^cF(###x1Cdc9V4pBt04hRG`r~2>$^3Z?On_(d9;(ur$ z!@7^!OH5Y^I5tUK4UJ#-eangEdSKR4v)3BTdPWCiyME){r!9!p24EI_(x1#K#nCA@ z(1bXL0JC(VbTexWj&`|8jfo-@m__e2zwO9(yA#Y!oSl-~dDgl_ue%(7FY~DTVC)OH z+>yk3BQWdhWPjDM=p9^|GCTQ3Moc^L6)bAY>dbx2Ao5KTX3du$SGyeN<76dYDU2vK z1G7@v7;-%)EmO_Ea8u1JhlFeV_Lh(N`A1lJe6?s|umxR?MRo9$^B7{bRl+P;DrTV>;kiV*o9tC*@d-fw>e_Dug^fF&Q-zuR6i7Vz(A^x67Wnc!<9= z`|EuJM~v;7c@g71Y*-Nv%pLX<3*pj<;a-8c6@TG5Zy%x`!I=BB51v^B8FBXgmAT7a zA$l8lO!iBd+kT=pbA#Oxxi6ELL`s+&h2~xdAe|x#m`fWj9>amP^dI$@7|7cD`<`QE zbO7zKJOBi>SWx&UL7RCXC>_k#gFsMPph(aXqa-0xBp&VJj_wzT^C2LpE|hM9?m?Gh z$3Zfphz5ezhw`n$?f9_3jhs(dO7e+n^Adj?X~oC(Xz3BSg4Ly?Zwj$K3He5WW0(s~^?E2jO(=lAD%OC|NWHfsFMTI7THhMa{lmda0fIzxXx(P&(pj|DYhf4+m(K{W++w;-wcXI9*p@$p1Eiq_a2Y#z@ zu*afttS()h5-}lTwGXRQwI=T1dd|pB4!Lw%-NSK0nIk+k6EdzSILQb^U*WE~Sk?@f z@wfy8da}}l>w9{YYSE+HY63kUkk0SfUdF!^o;%MC6EeaY&EY)WzEW$CcUt|I@p$bk zERVhd1cDrmvaf0a%{5|IyHzYMPsn(<@>{pM0h_t_rYfO_b3cKoIzE_?amza-#Kzh( zrTp3(eqp%127x;1BfhDL&OP39x*e`bOoM?R^kDXl;tbw#1RQ0n!3j28hZAhJF=CF| z6ZsmzjL?DEh7%gyj_xAzwSXC^1M~JgmJ?Hx$kzepA03#NIEm6NW;>Cu2h1oPm`2yI zoMRAlwgE7sbzrW27BC@19s-y#Ixx4fOTsti1_*x?02$*p?F!S-l z=ysw4m{Nf8)`8hM49mF&Ia{uRv~3vtQ*9g66lPPXRlmFRo>23rW*9{pV5lc+AbSRZ z1jdk{Qp^*jkErfFgJAkp^!gkh*|618G@ZH+>BTOf*N0wsfsTysUmIiGDJ}Ojh~dZ( zMbZnCJ!!0dJu2#qJB@Yeh~JFxU+>lj5NE|IoHN=q3zgRbC&FtB3GRB?K0?Wlv4BQ@tzLuV`5QuaS#84MXw-~yj z`PwrB!Vm9*7}7g$PF3*5v-fa29;YNbI;=~Ko7#$>upq_ba0u4r8Eh5$0IZ3Xi`S}t zP20+KSdyJgO?k1QP0(rHt6DeBu*dt6v1&1Fg%(Gzh9HIyK@9tEsmOJYSgor3GfORo zT|LtI`;+P@AE4W(SMy#N_6W-{4_snZ>7}&R411*24?&9b-uDT^9`8WCh*}K4c4l|> zjw>k-dt7k)wVUVauU!2WQGyt5S&yi*k;G`TXpBeWXt_^6P{?OsV#EwXUZu)?l;fTS zDZdQ;rJ<0IaIUhCFZk4QnFow|>4q~8n1+|`^cMECK8rKO?dN|1a0I%_q+U9E9AEdj zQ~ zEvJMRsGqQv0sC^0C+igh(mYwC0oYp8oo7-3f&F18qu1(Ik6}QKRvXwM&>wP;zhNcP zR*%IJrL8_}&VXLW!HJo#uH!fc)M#}T9O!vn`6S(b-kSk6THWUtmiS~Ov3&;$8Ql<^ zTW~nCm1G~v%;5hE%XYx%X%UW#ygof3Rs}G6`e39ds|B%y*04sC8h?(mn_&F4!@jWJ z1W#gK2%{&8>Iw7BuCCRSUYpFup+~=k>xlh(tWr`1{00PgT)K=y$&vvHSej(bJeQc>hP3cK;&LyP|{T zqbD@}pdY7`gZ+NR5|ghIy{l)*&iC)9U~!DKX~V^%eDq`lj>G2uE@%Vy_wgl`-(d9g z)45Db@4)yAoP-6=26}#n(GxAOT<%IOBEM$qVBJ52qIZE&~4orgS zJout(4l6Y@q?c>6g(`(?^n{C?AMe4EZ-){qeIU@J3VN_m zvhXG520$Q+>JJ3Ekx?xv-(>$_yxIsdP8n(uXoBpP_DZh{_^}RhwI;?!K%fq6FC)LD zSO{lG42=Z>EkZZpppG!BS%DE~=ww8#7)tC+{z{+&LYd)l#MV?opceaMlf}1%1Tubx z_ZzZ$+(9t_n?p6Ta=_!F>1!y3FP^k8cxGJM&E z;Z{+^)&@v=F|#5o$eH;F3!stNDMj4`t6o{LX3|@eYe>@JMG&i~&?0Gs?1*-(qQxyNtPFBD)&i2& zVxb3zKC!bSDr68tJAtGQ=y)1YC6wsfGm_b2}zqJ zX}dU_|G}qE??z1ONJx70Bc4xhNfdQ~q_pAUA-XsU8A%=eFLy%hqoKso5lEVTyP^h3 znG;_ggrE z?x`}a8_F#{qv_cvWASD;2qtbQVXoBg;q?JAi^mX!Gcea~i3PWORjBIU?E7lwdRboQ z8#j2(-`a=RrNzXc5iqxwTvoFUp4wDG%oiRl7xw(IJs^8b3t$yRy@KiL9XlE(6_`xl#;%UL5=ZP^wOExZJMH2oeuwO@_ha;G zj=KSQ6M>T~9^X0R?tUVMtprxxZGr_qE++b|8LQIju`}K+UJ|=De`S?-9HM&+ zB(`o6R;_V8t=0AI8IH()FlXj2Vbx1)ns+of4n2TXwBh2h6voN)UtyUsbbYn_3vsOA zeQq7GE+I|5Z^0ZX53HgEzJLulU4T_3>P61&m$B;jj0_^qN??^P zlx|jeAH+LnMi50?U=_XdakW}}{QXF7kI$9lf@=|p;qANdzrW7&n0b$3$G?js*6n~m zX&HG5leVwnE?vz|{^pd}PHgB#^v#VgO(gR65(4GTi&Kx4H=qM#f_D*7bN~Xa+g6Qh z@M)9EWoC|=K+nu?@SpOF_&h9c!XzJJ&=Ck!PcC!KV^x_j8}{1lBq0#3{`((z4Puhb zJ%K=3P_J?V{WA)$=H?Qs&H{lHJ#yW4Hhs<|Y`7^9XgHe56H1(jLl+=Wje|&t4s&)Z zmw&fWTKv>p@K^mfD|KRZ@Vs{g0*$+G$p}OfS8h9a!F<4G72l}%*EC(gfR``~FynP#9$!RE`x->P127YGV5*~|X<~cu67B@d zL>-tfhp?OuP@i3Z@zsGT!9o7S4&WsW2aKN%%;zL5rz3a?cLT;>2d3={0ke$A_W)*+ z4$QL$0;UYMu>;Ix9heBPE5QDk*l9kIM*wDu4$J}c4oqBcMy$Glf+bd>#ybtTF@aU) z27>WEBm_$e4LBS}>73_lk@s3IFO`Px(n|L;i*!R#?0J`14+hO^ymVv2uYrrXX1BAGl@-sbHO~kQ+{r^=S@aNz=247j z?$^Ze^5leYmPj*lRYN&f^}-g_fUt*Z%`^UanRi&Nr<{a=mXj}95QAZ$d9CEKl~1uM znHPxJaEa#8>es|zr^$~YByohGdFA8f6C2r`Q|vwwtC51{h1YxP)^g1*k7{4;3YzC| z8&MuZiNimjd2=43hD}(vQrXPUOu71gLk*+B9DTi0IzvvQQBoWICU&}0o<<1!e#7@u zpy$I}RvP{{dw+alo;NYtCz@$`=zf{<86peEsGV}-;qEq?PB}VD^pp@2U()q zTVOC!KxywNEbk@A(nOFYigE{8D(L5!^x32?dOW7hjV1QJTC#LW_Dg%X!u4W>1yo*6 zjQv2CdN8NlId42`=|l|u1zD=JAJ5f-RP&RVEOniWXWZ@*yUBl*C4;_*?we0+r$}UJ zzfZiDES+tE$RU%7$yA9f)jx~pXIc}*G>|3QaPf!$NuvKymaP28pJdqS)nkce0LYTJ zSxqfj0>g@1jv&|-)oMBzRLHeh>R|jZjl**A~QWWkmY8y zqjzR5ugQm1jo_5)t|ZUT@=v^*<;u4mwA$l3zVhi12xlD#A~V>0a=hoj>6~?zrpWAB zgmwOJAY_z~h)hAhc(ur!u|>?c45IiK468mxmR!O4ZK~N3kJKVFq*4;^Hi!(QUrLK*x6d$bM$G0&M21%XeFMB^4Nkeaf={7*5+d9hudehYR`UdrQ5}5f zW|gszQ}TI&$T)XE)V?_4FdszbtT_^*QKcD5?xK;BAKgGhWD2bqKCm$aBrjlUK)2xZ zXH3)3k_@!S13N{Fi5aOce-Z%QG-abZb(+Yw6e8t3!R5qqy ziBj1JM!gG+e@twHfaIm^9T>^$!akUG8pdDgV=OXb46#}QB%ffeC$okzR`n9P&$BUv zUC_}}2s#XA)q&Wqr9g6u8VDr6A6X~qi^-w~tc+P*GKljsA*nVE_WknLVBd#0hc#>L z7-GL%OCD6RQ`&QsN)8{CT1<>rfIKv3@?bXt&)$S2Zz~0PINS!$-Q$V=Dkcw|-{F}L zGGZ6}S9$2vl%fCi_9C{cCGxOlt+qU*;Be?){{_TkjYJ+UBIW;G`jwdO2eqUJb5+Up zu;`WGqh3n~WbiJ(TU@%?)%wrURv0H;QqPHG3E=9t)uZGPrYU6>HurbT{W1btQR<#g@e8WnKBc z&-NwMKf<0edouVULqRuO%Ra};I{I=yK{x1NOKj++tB4B!X-Jm&Js4w#96vU+F z62&Iajn64HxYPzaR9o9WQR_y|?{j?ZML+nS7Z7{188LvkM!I7Ws`Bp(U%G8sWBhXPgrxQfsZWDB)<nLlo^m_r zMm%9aDem6dzgsP|@~%`Uje>NDrxB4Qf`oSZPbo_au5tE3P-8v4TO%L7*s zxzvJ~Dg?`O`*xrDtv{fJJZF6@yTB|@b|GXZ-tohSSnZ%A2zY z#tB+ob>swA?mWmYWU^1fMS|VLyrtkx-%m#n^z#yqa>^M&!o|w|TMu9v+h7C{36wLK zTklWG389zsj&);ugx947mUq=+@YH7XEY7zpBF+csct8hAH|17%vP#T%2VcZNpxk-5 zQ*qOZkDs!adwT9la_eCS5?{J@<{jU41U{{$8FK z90AICf)Au0KH_LEVs=zQIa>YdI5o4tXbdrr5hw>{q@aw+IM`ZXokFaR36%3Xm*qC} zb}l#R_#uIEqpq>?7anya4#$CV=jS7Zrj7AZKD}?NG}{`Y(N)W;A^unzF^Uwe`Mx+Q zv+xY;ae6{JNGN@e=$pR8HWmna?SwNUXg!#&MvqBZ*+-V9V8v^q4S;U9VR`hc+KB23ZqrjhH;P&fbZa=$KIyy3bsVrS8VAdx|I?zI%;%+c ztYSSJbS{EveB(HvTMIT|pI03pF=GrdJT1`8;4Plp4M_*iFuFaA#4~Xa?0fdFbX$Q| z)1nMVVjC}^+rm)ouFnWx@1px-h)IHkZe6_C^MW4Bi9!W*qYW1iDcuZYrv7?A5&O}H zSe^sAJ&1MIpxaaGax7}bKuh$&k)H^bF)gs1ZplWEm?NJ<(kuyttz6Cn-E^UJ)9o>O zX_tgV6GalxtvdZZYt-OJ3T+jdT z>eOgrbw!|C<59QVE^gh%JvZJe&@C0eo8|Io;*bh-yZ9dxqV)q;Wxmo}xyeE^Pf%qS zR_gLbFcX#r1X}shg%PL`ORa;!zVBfsY;WlZ{BoAJ1CLia5NKjGJ?O9AKz;#3@OT*k zfvD998za!+^zwOIi1}3@5Jidc9zRWt+T+!&cZvNqEds^JE^7Pi{U#!OcQayq9SGEi z1^cF+!L!kKiD8C7pkHWZFOP{K`ZpMX&vP@-V8 z`rm!?Zk};e!(eFbfu$Y~Af`{Hwt)po;i}XyV*3oFEu~f~!8UjXt7pa8 z6uLpmi^qK`nftS0MFxJ=?KD<$z?1~7Dg{Wh=z{VQvLfjm7VNG8rV)y#5VmLY! z(Gy~b?Hh?0E*Yh5yeBP0reAcl_itu(~&xlyT+Y?vW}mISk4!@9IUYE3lO7%%tAMN|}Uu@JbZ3#FTjC-GZZ zcdmpe-UAouonbju`RI>3xueBblBb{9oVfdCXFj!{x@seiTi1PwAl4s%i}6?gbH7}v zGiL|J`|++9)z-vu^d_t;f+hSXL`(J;&ULLfoE%5Mv0u!V7z8yF9 zeS~Ub>pV3Q}U_cFb-eGh;ZP+*mH;bO-<-sJN0fgDrVi5^6dlFp>81Wm6jLOG- zp{rTyfgkNP%Nk9fwPWdci`@I1oc3NWd}tMMKU*^nMwWfLG`&49SiqcF=WMi|^W1 zUieP+B!6hr-zKsu4REBUC!2!rE7UNE#U!d-94(KZOBU~h;T{|r=;#WyFwwRBbWUgk zSO#xEhX>Gb@rVPbIsHcoZ73`CTYj0fD>M#v95Dn!kLu^4LFimc=*}4kN`t<@hz<{+ zz-Ma5xfsp5cmty7W=h6%c%TENo6t|u)4#Fd7~FokI@~#DYc)QoXft=NMrv};UV9UN z+w|w#xb62Kx7kxRw%>x=Pv_(qd${Da;0C?WT*~xsAH;bDYHmN>HBZI%EugQk)eyvN zgA^kb>G0r^16QkVq^f@`q^A*%g~Jm0hAkT?<0c_?4@4wX!r?)OL_Bqb*W7-ZR(};5 zgc}nejc8@yZZ;HG&fOO%#hcnf&K7flyYhzD-3I87;ufe*3Y}}1B`bf^@Ic&tdh!4y z#E;J^rS-#`O1pW_G&uxcxNshffElxoi5vTcLAs(;WzcuSzM&l8DS;Kn;KR zf7rQfdKW5gKTZANGqFUeKfDZmZ<|{|{C#z`8U!++hHPv^OMi1OSWF;S17|UyhHU&A z%^JViXSuljG}V`X8Bjwuk~bpoMvS=qG;Q^40K#U`usM|YLmD~?kIs`3+ZteEbX(Gn z>5DzMA1nnE<2?jyM3mk`3T`eQO02BG#F$`(KKp90p6C~IKhU+tQTN${w{S3evH=r= zqT;~BxF6X#snp~Y`s}w1X-4dAwe%%UmZ!beIDQ)zHp+q+*93j($bxX{ zVlaGu$x7H-+nboiN(VbNobkeJSX*104y)jeh(|hz4*iG1^UJRQo3?c=gwfXl;iryAYJBml9o(lzsmbyFTM{?V>dgBT=y}{4ir7vT#JWCM65$5c9xgvxaR**z!+X2X zPHbq}D#Q&3qoIMsXow0puNI!Lafq1?FUkpoXGv5YF0U|3)#cw8YT-#A8PBhabXD$J zf!MiW#GoMvPe-|I7up=#NG>sRmKY7R`rWZp*lxa@m^TuvdVRIg;2g^e+g`_zSTz=e z=gHD*ZWTTZRAzDx=SsKd@x;D`7Ug8#*R|v8SIxs( z7hWL7u0T0wM!9>f@odpLV%SokT*EPVu6Q!hZ^bBgcs)B4RwJI6+6h+uema9NB^58! zg#iv+U{*c5V1@xfVf!E#PV2vtba(DO&B3;5~DEsEOLxI@&kW1VHxR{vW`6m}&%T*vV>7*)Xo-QwJ3p$=b`*w`{caI*)VQvm(*nQ%BvF7 z7I)#hRkZS`xQtIP}&T{!^NVvLSk5!t19HgATw&XSvKa2XAj3K+HNyxJau% z0N-o48%K;zii3&)I5G|I0wdE-K+wDNS5Xu6C3^V7!ySl~r$A88$yePX$3Nj}lpYoc z`pN_!dNznSbOwSxJ%_wH7FM9lsk}nz`EkC6Ww0IxGT}ENCZ!ATu=kN1i6Q3QfQJ;- z6?hmGP&Y}>R1fL0duBAT@2`$0zM#dbqu~s>#~`1W z^p&uxQ3X8T1>8Vh)U<|%i^pT=-RM8;;lB8}Jwxm;m|N}#tm^o&yB4e9eOAX`a?cd- zTlJ@=H5B;O=&eyz<71Kx{Yn(|h$)aIU;s6(b)a;!Dj=OzA|e>(mInf>=$&4%)%oD2 zd%4YnQ~m5s{J!)}ZV*Ad3b(kublICR=q8G?NW zOISsFL2+)m_#al*K1YzBA;7Aqp7ptVbD~u*2E0eh9o7>|j^J6^zrcyMdO(`bFu|n<7}#Z%5$HC?1@1oqW7E+ITVWxPD7J+0FVq7@!lVg9q4RIW@KMV3@j|Bp?l^=we;&*7T?0*VDUE>4-T|~O< z|9pYydouzZJ;WXrY3fVteEv$H>-7=s0Nv7f34tc)U(_Pdj-QC!2|-;GBn0Y%4#UXP zQA9Bj2;>V57Y|JWee|1f7t2U5B$mEFpxzDo{z;(5I3A3A3_~eDAP_BZs!_g?Nd>ya zg&5S;4tw9Ijse8k9|)uirJF$EII@Wv1{IzJ1fq8qPOi>h$lAr#o1B__vt)OoTf`LJ ze&9xr8u-;ljgKUzr^>KdY!=`$4i%y%Lh$u};K7~)ZUC{>;@`74s}befiOAysGgk*j zwSc{mDBm<9KMk09Ixw?pBgPNPIRlvaIxt&o1xzxLp9RbU9hd_ArK0>fB98~mLLHd4 zXklRbASobfmwJMF_Rk+c_Ltz=)eS^ zT@W=L_GFt33RY#z43C_tHry_74oJOyGtiq86`TqCSp5$LTd2b4?FAcsDkxZY7bot+ zz$2=ETwbdc?CY2R_(w%8l~v3Udk9wQO#=mk9C=63REWA)L`>~Pzwho*4c&6$5&PVW zT|mDty%3N74MQvu6d>Stb?E9iPa22^SraJxV2Db za@Y5XD}=ruWe+}7IhZ)i1kJ145H-vpu}|Alo9b<=%~z?NP4uJeQiS+!*2FYWYSpK1 z!V9Be<-;rx!%d?GGBI?ARkJvdE-Ry}W+O@;yhY?p5aWNrs!yt^Cu;#)1DiqMeHj>^ zXw|QZLex?a!`UE)6cqv1#EODiNyetWb@1v*NVhjfOAJ%MQP)Bw5c}(W=MKWp^Tc>A zh+$)9)o(-oA4(}EhVuk5+>2e*q4Wnte?Ak#4d~~Jehmxq7W`EVH=~UZT^dhp7fQs? zrN<>LG5ms)fQL;3h{+;}7=A~4j}g7MT&nN+9SyCuh!T zM2u?L;5X$2J$js9*0P=QlZOoJf#A=N|H+kx1w~oQy{J|Zk1QR0+#}zTFVGz9*=oT~vI=kR_l2x))D$iX!G=pm!7{Iu0wC zE*#IEc49&pao!;W`?}52lU0Ct;ldI9m3FPZ@@p24J2z~D74KNRcG9_eSCaODQ<9hc zi+13NjS#T0Q%fmNLe_Mx1Ra|v;e&QBAjZ2uDKR0@{A@gXz=s%y3rbnJF`hdH{*T>E zDIc9-XJT7;61zQrRm#pNOR?Ppi0xj9Qo7gGHXGlZz;Xwc5R(XrQVzgQ;AG|}qSyyY zSsh-Pc!*{rDrLUkZFC5qd{aU!_k&Wl**r{3DIwx1b1r+(scI96aZ;JAqaiiU_0}}U zv*W=%774~AeN3KF0qAF(#F%{Vim2cy;v5C~sSBlBKaZi^acXZO+nCyp-kI4|&PQ*J z;0}kTCO2rfF0r(3KfWk>0N2C}pK@;wu|5d;=~Z#HN7_qs?ozgf4@}9g#>St^Qezk@|1cCt`jSq>?VZERP~E`hj=O2qIQ7f>bUaldKh?piz?dGqi@xsS2;&2Q!w8~awUX=~=+WI`{*EZlww1$TIa^u?PwIiYnBa>`WtD0)U?tH*AX=cLL_48 zFbz;*Sbjy*R>^oZ021Py)Z$ypp9ygWT|xL92V#5*_~ywhlVYLDi}Q)$e*)hWy%D)8 zmgvVZzKz|2XEys1QwPDC+#BiBu*Eo3K>;khU*#$^TLfvVny%ogn^j{hJLm$!e zS`ync5{9N7O4hPv)}d8+dPO=hIV)l41?&`0KbcGv@pNDZuSz_!z>cB+kfE>q7Ukm8 zJ_QrY1Yqc_)KOXt1*2zw0t1~f0N=lg4(y=7JflM3;wcFiE1@sq%(@8Te2xz6bf9!| zu>yXYXCfgsFp&=I;7-pmR{WTO`?#%9smT`i_9bphQSuj5b{^~7vbw~#=tiv10~fD3 zs65iPnQ^JtH2sYU_+!R*2H$^@go`vkw`jJUn}ubK*~0QRMqaDllv~guR^?*yR&BO? zntGfsDN-ueUPbI$;Nk_~B7^|vp|KplvyhlwlyH$&zei7mAA}jHO9B_asXZg6et0!$ z3$eN^aIxz4M7OoP8SlO(OyJ_+b_|tZ0a5oUK)JE$NTIlPCT+L1d89mE(Mp4I*U*eg zsCk!|UXhLxcG_S;t|`Pe6}YJS>CL$41hG1{;4-24@G&##Of+p15_C*ETBiY^fE3@9CcB-a8f`OY7 zX3a_0_Bs0C2d|nFPfTt}n6>&M*5I6sC^CUr=b_=^A@+UfbIkMGvJSBjVr_XFm^I|L zw+6GG(dm577eSddh|vYn;?7UOlX>9Y&jPy9r@Z)sZj;afajq*kBJTj*bfI+9Edqb! z#HZjny$f`scg7E{#s}Oxz`3bXleaC2Ol&)?BR{tB@`NKeT1)%}SqHL#ZiP2*gb>0i!-hCJ)oIB^jwZ3&y6?C% z`3&%+KN9HXHYL%mQiB1X<#KWUKPp$`IuZ`$$GivB@*h z-F5yq#LzzhR&{9XC$Ne}$A2uV3_x66+GaRwOj2Mv%Mch?wKh%p_7c{hnt~_4f~+3Q zs7)yiL{=qzh8eYIz$%LR%~<7>WNzyIot2SX*^JodYOyL(R;!uT*xPCs!sQSrm&Yv1 zo#2SPA{3(VB8JZeR#~AqBs*FV{TGZ?XYfTNPlQSAmw#ndlQsCH`LJZ=m4sDGXKP!O zvv3fUyaFuB*AiA0j$|cVs04fMz5!OzhKq+d_AUUE-B9+-@8nU$+IbPnd|*}ACVpD1 zg8r%_+D#Xl=Mt;8Kpj$k_YwjfmkhI83`C5=i6}k*fhrzs&JEf3pDKRgJ9U4RV)-9W8gy3f60mhMiNQy- z9lyHc?XC}q*(V8sszLQzzrt&)LDD}1fgVG>%KNLXsD~FLfIwda0$p69a{JPI8~?t= z4xzv5v4oXzxzaLXdQoaS{_?>KW^ai668H<3%Jj;AVc`W-z<&L5Wr#k$447p)Fc#>? zxLg^cm{S0=TnAEe;DCY`bR_MTtLr?oA>{D z?%;A2XjeL5f^}em(y<&1Zz8`6nAJKk+kXp~XGDGtFl%&Rjvq%%)e%H~9WZNkU=nsC zrt3Q5@D&v7j0-9fUn@wN*U?@1?~k?`3ihrT@uPByZ4oHg#IaMEg7ud@Dl7g?7co%p zAx-D?tu-QNWD=`yU>8iN1K|yzU`4-;;rBBT!u--v3N9am`PA>AU=;P=Bbv5@2L-Fr z9m`1fA@)DC6ifzlky>No8t59kd?%k67poQQ+*B;&5iEfHDJWQ9oV2?9Yzxu<#T2Xy zj+|5K@Wk%-Ulr_ObyjAIJFMj>kto>qX(?)p8x~T+F$ur$ln!7Qlu8sVvL2RjDx8?s z7RCez4-a>09kLKFBz0pK*qDG__<(-MRG)Q3K|u2+!mARGUtpipf7FsNl0EcOwP1y$ z&S^$0%RuuY#!c1GJhtqCpuL+K0;4GSH0sgPY~+@8wVSJ=Dl)m#2r-J z_2?T-*A3lPYu>@-h#LiIeGMg=M-7XNj9yCm(w8qn%v@NnWCWTQ66MN;Wt~<{cwV5^ zJg?@l{Ka@q340~dfmYfQUt(a4npb^2o?7on%qmDUk5>OF8mj3*hQ!=Nu+hs`)ZfM- zWjc)WtV{*X+i@bnt)y8m-gUh=d$|O?FX_iKi9M8NUH#cHy23(xAVc zi&eC^7&QKoOBeB5WPiO!)I@lkFEO?NF7}W|f;I815}r+jklU&P7lkmctCu0q<`O-&y1IxaCR z{tnl*NRM0N&z_QTdmyo{33SV_Ys)RKbJkLxaHGQP2lS0jmBA)#Bm-4!+6 zDxPCy-Dr?P6t#eEq3c_5b3)Im&W|Zn(@n2V3?Ex@u+kSzn;SrL13RD_B(S)03vX`+ zS+wmXbfeYx&cSOvWyIV8=yn_GRh}is9YyX&6s&u!Ezs@O`m=7AZf0@sMs5~NjE7cO z#yNgG@g*sVu_%uBu;fl@DdbbD6ftv5Wesn1HJUh)+}i4rgQ zc;w=(U*Mo`pswRe1WLW++jg)LGpj=QzLOfb3V~8D`K!qY90RRxs0IcjP}*us91mp9 z1P49z2hf<+P{-92=&I4`(POd1wQ^$9hyiKZjx`9Bwz@Ws(KEB7iA`e$d=J32LWz=A z4@Y|@vk-{h1oZCqojFYJs)0|UGQ=aA!>?DsY>)j**|TrU+*s1Z!0Pq%WTxOBtOB0= z@9GfXSOGN^=80TD?L3~_WAiF?)9&9LG!Mnm2|g>f|%A3jLRd3eQLY?Zp0pZ*DZxz zV8$i8AZ*uhSJjL-bOMzuy@%X-)!w|_ij4+s=dE3?;W+dzVFhKkg@tRLz{Qa!ix?Lh zfn8AtxJdnjG#r0#Y5rbB_IG6Y8v}jo>&Y5INL5|%WR!w`kfzWHD6NWPp6szH#Jme| zk)p)?GUcX8sCU`n!Nk6+78f_mvRruaBV~WR?^@y`qXUR>H{hZ*^VJt!$FnD3F>`l; zi>;R7xw8;O(1UTY>I!z|UOliqdj6G*yDuY}k0!RgBwW0erOibr9+BNz5|iE%%1t+8 z=kMPKM|K~e9BsIGXi_fQuK^0+{Q_9-(-$Z=$#l`5lq*1c=05QuR$f3kTHv2%Mm~N= z4+3CE;eJ3lT`1j@J2`+=_`zCFqUaBl^Mmr6)wAVePegHDWogOZGgc>hm$c)54{oda zh+g^!dtm3H0YJF|>wetQY+sMu0L@)5V~1jy3Hd}m@PAOQ9U7DmAcs3m0vH+P>CTz0 zJEyu=|AU%xZ%!TK_l@hNOsazAJ%AmB2Lt7-<+A)q>{QMuNM1igLOELfkEwWVN+2;G zDp0OG8^8h_Kjs91D{h!TxsdCp-RhX7aC^U@gYSTBvNM*kv?ejSDcY9RJLAc4N8&IX zShc1SvSe#qc-vO{Uns{ow9sJHx`~Lt2k!V0Qd56-G+y{Hl-Q00x-H3B#^~0BrKLm1 zAx@2zATb~66%(s}z|?=$Ko8vU@4#_LL-EVX93g^nTIot0SU;== zM_Ca>F#+gC8!jH!(7Vxp*u!P{)x)po(Q7%eoCtJ#_i)*tbh9zRD*XgEhcD3WH56D* zH!*^7tS3V~UJR4Yen2-}DBW~>d<5^@2@_8KKsS14GlQD^g_@DvA@j84!E@IqT0R`Y zf3AJ}Z0~Ul`{b7wv7Q8UJMnEOr+2E0N4w#gp7-}p818B12qK>>p_}}8n!1PEh_32q z5iN;g3eaupJdR7xKd*Y9Q%*OlJ5jvP`fTzdQi&p(4?BQ~G$bC5jn6>jU z5@LkiGvz;zHYpvCUDNPe9YI;o9RTxLGl4*NVpcN(Ie}G3qd=;{M^MQ6s|};r%gH?n zKWHEj$h#rks%bu-@3GKhz`tHM**{$$nOFsR0n1yPFm-kfo;gL0kcsDW+V1id1vOs zBokmZ>A*zeOi!ZmFqVl7^ZW_~ z)6ADB*y}iL1@lNlWM()qSs+ocnAdnd-+?F=f`ZX6Pdv&Mj81)I`aQt@=YG>dQ}I#Bvd6Ue)8PwKNYr88e2kyI&bVAF~)V zk5-{v^ThmKn|u&e7bZ)BK=X8=bZg!c90$J|zkn!~fadu?`9UW3yw{5DoQrK*a^u$P z63@SYneVVo3D41+_G&>1v0e(A*KYB2E@<{O_j{c*HP34s)+Q7t_m}+-&ErNO<_k|0 z%R%!FsFa+o_XU;Z;g4z)BWy|(uctpux!@gQe<_H;3eda;a@kNk_1Y+!n5~p(9<9DC zkilPD_9Eu1K=bH|;_}TAFAvA7Gn)~sU_tZ3JWjYdpK|Ahe?BN!^?i^xuQ$XK$T+O` zIq3vym{*g@$`8Q-QiK1r8cd6Hq$h6|3c&DzGYg9cUg!IYXrH@vilfY)$XrQ16X% zF0o&)rFn;8$t-L&B00Q=cEiG2q!Z%}pm{x*js6yC|Hi|O7={R%x5o&PrI|!Olxg0U zFm@*229i~7{Hx~GK_5tdW5`UfNkX}h^H;Tu2EBYNx6LPFvROj8yJ+R-uZ$szEkHTi zaPg=E1_S*^U4e$O48N}Uo#pR%0C7%6Wf45v_O$SbdvyF z8C$fGRp)Je$g!~<2&4<8n?S`lhJ4#Fgcv;(jnO9!u(-D1jt>J?<-tRrUw|yy19oz2 znx!Q-T)8Q6QQL{UVOi6JA?Un$djkA}JAhS9y3gQ(ww!UV*DgDmCa)D+pMoQjx0fK& zcc+9^m%gQ|Es5$C@wrbSd~Fx7YI{OEE?~|j)z%T8)U4Xz9>wQW?WT;Vjo9aRi9tB9 z3jBlJ&;YCigL;*_Rm3(fJFeS76u_p@_lQzU4LLq+m!Rp8a8?%8rTK1V2$WLsg3>>M{))0 zAo<3A=0Xc9)lu{pq8Xw)eeLV+zcoN^mbxeI%l5SxPxNS$(_2$VYItdKN?qXUV}AqJ#Q zxs5`J5~o~O^wk&s`;yp1vpUjNZ$hB7)x|idD7>N|HisFIwt6!HrL8_+#2Qoh0MZs5 zQ3JOiP}=H+s7HmLAZ@`>2K?5kKyNDmM-TAo+}Tt7NDcFku@c`m4I{QOAcSkbY-K`d zCwp8*_aZIdgQ(qjM0SRWl4Br*s~YP;mc(2z{wl#LPdaHyh454-MD+`1TSeERsA0lF z=31s13-IcTZBL=Jw~4QobDOC&VMO#90LrstcuCLhqsGe|!gSj&q=vtimr8e6#u6 zxP+c*$#0F;C+aur%WoaJ)gvFfzE66PrYI5Aa`LlToXq;Q`=nNy0fws`SZzL4?M3A0 z|A$&u!@lj)5by^jfm&vC?#Oiyy`s8N_*t!%qu%c1b6+=6_6WxEMuQEK3~E_TE<0#| zr~F?MvkMZnq}6X=gxBW5y5EbSmUQiMxmvbqidTy#5z|M~p}|fx2|rf=AMPbVM!)Qg zcI!WH5kF~^xL{(=V|M%JIz`0cGRSDcH{@9UmCkL`yU5x$dp=e}MvtI*`*{vH5L1AY ztH*{jPSPCQa^NI&AmV`RX(W~$YR$4S1~zF*jgx0A(f%*yK)eO}g7rr)&F5VghH)4p&7ft#shol zg*zUs^di%d#PSw!F>hS>pImHQ4M7g^#3~cGNUKoJMbVsDg++ZkHE>c0 z3c@$)w8;W4(mPM3DELsnUEJZZX~~_lHYG0o(3*D$3-AzP%YKYCB-VF;iw$j-a(YfR zJnlMYCsY51_-Y2?fbK^iq~^aX;Ue|&(*&gE@D>-pWbOK~Hj||djC`=flY99yO*P=j z7d02R#D(z}3Ysb1a1i-Jl}iln0T*Er;bj~E{YYIv%Q!$Ug_mvD)%t3tpL!jIqAEc1t^;6}IPeIBx z(+xBzmyN@!V#v5_`bcWI2m&?bA(`%iVMaN zt0&MuX1UP7`$EV}3hM?Skbn*prj-7(2`lz~GckHBnx9o};mKdQ#QZ4`l-`;P1YJ?k zFv;HZpL*=-&uSUO{+Sj*kIPPIyBxdVQ0u4NKw_K=1g*!?mG)1;LVO?^KTjZNRebDE zUr1N_oDtMJ2~o?t5xW_&cBnNn8dZG z8}nI#$J|=W5xXORSQh}@Dh^r4$%q@q&H)k z0VCxnx^RbjUQ-=^^;J!`4mGy%zbkcAj(vsYU57QhAAoMK#aO39cDq4ZE|nA_PKx7U*_x!9F*SrY5`_0~uIA){dU{R0SO&(d}b?1_(<5KIh<1p=MY$8#Hti2hGTASdjJ$l>H7)a@%mqf;2LFRV^P>>MO(dpIq$b>t<9LCeN#sw#Gr0}g zBfdfL?}cIk^N7fw0cN`n%>C<#QMM!UT)>3sz+A5=VD=Ju9$7?JW&))qXjF95Sk2jO@*%$l z%pM(>1ZD<5l(oB0N@(eJ186NJaXO1%n#f|W;G*ZGK7(;@QEL{PB3 z_jbEw?|8|@Zd)oSSPAR-9_kNICl02dU~N00BI##-R7M@}P&PW-TtmSUKCn{tCqRC0X~PnB)u0-zj5XJiHra$T+OsL=vk-1` zml#)J#(Ovni!UC;vrZ6sXdy`3w`e@qE12k4Wzsg1Me9B^@bMyc)&44NA#9rGp}_)h zuvV8y+u`Th!{W7UQ1H-T)jDD#mq=TyT3CZ84~S_!!5|OYJKU+ckWyu;s2w5My5Q!|QtRY1EjJ*)DCp@w}ma;w8hvwY>=bq1< zX(sdid;RYB)#LlR_kBM1+&lOEKA-bBpL0%G8G=qn5S#iShMd7FF;sgK7Y9<5sk?}{ z*@77AL+Ka87#}R@8%;!ZAckDYZS`#=-aX>QAxQ z+k+UUrY1l~dO-I17k89JMMWCtea>yft%3o}23lf>VaH_ZyjLb6CIy1Fpu)*r2lo_P z9Jrn{W6W0#7Z)nlN?NWAm&RR2Y+4X8YKYEz-V{8Q1+!)yw7AGsKP`Y>Gdq+;EFJld zbk%wu{hQ;}d~na4crHe6-tKukCtiH>P6W@zRn#LXHG43DI5h$;uE|0Q#czKkWqNd% zMoG@=aIrROgL#W|V%L}kyJEe|4Yo2qzWw@)>=!gLi2n!##|4(tuXpd?@4rI@8izIBy%4?&1?TvR|LTK)97)BW<@z&CfvA zUQ-P)p$Zt(J=iw@fH!FhX{q_`FY2U51}eTCfx-QJy7%tdkE^@kEBsN-%i-3|!Q%FW z1X;Pk4g_``9Mnhsg!f<2Itn^uU{Yh2g9!i=nSMUOT}So{4AeZ~4;tDn74(u|QscFv zB5Aq7&MF|kmYKj6=_v>sMeN-`&(^q|rg|oV4p4nM+mU6R@bx8 z%hlIJdAc6qUtnHVE6}qJG|X2_2V+YGmC?kwHLqt89VxO#bI4|DL-ni%ehf7qLwZHq zKkC`n?X-MNm`-NjPD{_S1B$Bkb!t6BqzX18ZLg(g_vlD=X{`-Fb`MY|?!nbZM;ImH z{?Jv+2oG*TZPeO(hFEt1bvobTbTxH?nf~$b5Og|-*mMMS;tb+EV(m3i?oz+C)Y9bz zaq9%?qz|QEooaof_AR|3F6jyC#FY$mtuJAwZx6AUO;Es|D8>k<&a|g6J6(%-z)>0>jGC&?I(_r}OJd^MSNb2mY)jYx*GK~D1QQ$o!C$I&UDz2ws-;d`^}}da zy0mtq7-A{o)u}3*sXaExwL3sGP0p*+P@j0u9`6>5Z+WNk>QrwBtzPY*7~XhCR z332h4oh)i?ciGFEFsWMWc=sRTV;T^_8*R_CSu4D-2^J^u0a8z^yHs3mu&auKerQE- z(Hen=K(@M2J>hbncUJ+s_oAZ?g4%TucorgNzQEO6@p+W1jUbal9jxF2hkI0~qA1eJ zN=R2@jGWw&3mkrf^*oHAuV4mTErwL6ON|iaIGI>>1+H?aLBQ3g^V%ug1kLmDYUdZk zv0F8+o@Sm`_dP@{5#D7jG4%(ob`fp?-{Vm;Jlh)rFU|N?K7MyttF{jZI&9!n@TSG?+N__#?Yh`0`U-h<#5jcAtyA zR*l`!*w)mY7emYgwb=bgfHlaQKt#QO-Q25EAKt)h?vGm~z=$~(zGV(#Z$KoYH?Z3& zA@6r~X9OYWIpq5E0d{i+e`mL1K1J1Qn?~G%fZh5~`q?eIh9v_l>E6f=Q^0;k^SY7= z7x#-VK7d4m#)tB}^4%mBW9Dby?vL0LPQbDM_4|6_wfPf>x?2!Lx9~ab|8gjHL#N9>^~^&I-r{lyJup*vVOy8A{eUO514Zg4NWR0 z_QQaSeay~NE;>MngWI%^%gBFA1BXLrBXSXB0f#`lS=ZBmv4&8;9b{Dz2yrw4F3wb) zIghCI>BMq4aFIiKLqA}7xv!#y;OgIab;B=W@>cDzbRL2ye?YF{h-w5)V-&4>sy|Tr zZ>S$?sVx&oOh*Di+tIj3GWNx6YvvK-Q9Rwm-Kb&P+C{{0G^LwWES`b&rX9xok#57y z5j_j$dWUM!ZOoeM)#%n3iD|nSb^-{~q8lVMab14fZEJ~WEYOX68|tG6P>uWJ(hdxn zL*aWeDAv9(K2fw{*bO-Uw;}bQ=$J;|%`p>N{>lROT7tHUa3S52c@O zV`^f_8@5Cg4vi^S^7I@lNr^aJJn?gZa=zt(ym{&2lJ8?`dTqc@$NpI{v7HEX8>vhe zGpqM`F5Y`bnUL^6)0pNRqc$5@hY{fX)_Vp^MGx3rU2bwqp(ji@RXl1v6!kwH?I2r5qNF8h*(Yo zx)s9@P(`;p?eXgINMaMg(=D-IoM+N6XGy2RY`!s797j~q3*s~#=(eE-vZO`M5ovDb zc2>;!T80v!MsLM?Pb8&v=o|KhpmpS{`h z-t=LT?2hU*{SxdDH8#s2PAh?ntL7oMa$m$qQ$5|Kwc=fMxcClz$j0>`1hz`M>4W*M zoH#ex3K{vUfusqqZ%~r9fc+?Jq3NpykMn_c86(kQZF2AcCfAJ+L)siPkaa6fAS0ja zGIERKKgGCClWY%6uH#V6!3|A`=%8pNIEenfbF(wQC)Y9KR#opZ#yZi;IkyVJE zuGIN(6eibk53WAcB;}U!Fl3U$ccAz*bqA7e0h0dr=0-J=LYHwrDtuG+mbvnJy>fs4$W*e3yj;)mYjTe&ANoXlE$4t45-^rS6-U(n`6EhM7Id(DZRAHLKbRptHLep2DvT8lD%5C!=V!V%U`eJ!xd<-$%Pn*6=tFY`z z@Es5QkySGmBl=1Pu|KHAs=SHSo4&88dT#e%p35Pvrf;+{T6iBpM2Dg2;~rdn=(1{8 z_y~LrE#|?pQ)$4eBg5|f&Z-~w)L@HskmGR#nm!XSSj8&!nAy`wh&paT+>S!irw^r{ zRgVg>BrIzyItHxbO1e~7NP@=Zh|9!<%E$Fn@}^AdA(^*&1s%htov3^$;DaXPID7^R#|tYHd@vSAWoUUs#YVAB~uHVOEc@&k?uJSt3YTS zja?|dmFq7ec&FWx??(E!YO$XP-^1|L9_IHUz$tC8usaMBegI689?U!=#I)>5gdYL3 zR}ZG336Ft^5T5{(tOrwUg_u?wi11&)r0Bs6*@l?bt%>k6U{dv9dLKqi8yMdE0+@Yz zFgrf*nD0dR6)^ktVAf(EqE*`+MEDIb2lQYf=>THi4UWurqkT#P8 z3dW%r@C%lgcT#u=+E1fbTN}VC-!8nHl(u_l^S0|TG}PMS5xqd&BzoZk4w<%f&!S5% zZf)iiBI^VT)O!3eJN4>mdat%66NqD8HMPuOnpIy;j75^ReF7N<`Jk3^s+N}cdfL8% z6deVxme;+}@Q2C7P)XJDIrh@qnZhD{Xa1;`Kd@nJHv|G(XSLMwpHtP2|eu~A2gT) z!=4vGEjfegjzU#-YAF5|?MhvU+a*v-eJK5ESv-;2Z{O3KhzdY0xssNVmXe@@+2Ww! zLgjJW19@*^heq992Lo7-?<%MzEJgb`ffnyj zhanb4T55R+s(++AUK{g*SYG4R(n!-E7>~V}4zppD@;a}UjPF*@r%x@!wHN%wtK~-g z5;|-wAx<|yEx#2a`C2v-O9im3#))2TI%?S!+u07Vh_awq+q-w@f|Ypz$?7+0G>WH~3erBBvCJ?)O6v#bH zY86oZFySH8Vkg_z#O^+=V;~Hy?L(mU(BXTNJhuLL`z#N`c&BDhI28>W6uOLBLL%&4>xmc0EjKW(}HQH?`A& z5@P=ld`Urv=Tvl?!q)1X=yGvLt~0hv)onPfkf%KaNFRaQ*vFeoT6_g4E+4@N{y#T8 zdOH3Fo~{>&KLMMps#h8sM)x)aC0s|jHi^SSy?Wj?F%mVsZ0=@Sq_ zFPf{kqz|6m>_LpncpL~M%; zV*L*Y;pmRfe;2|vn8)BHhmhkd5JJu%3ZeD_APq4FC6>dKiPs>6`cV3X@X9?}3GpBy z-Tv5tD;d|(LQ--(N9;JRP&qp~HE*&oLQ=U?)_DT*KwRWOY~O+qn%251W(=BUOFP_A zZa8;W(;2g7(B_j1L|CpRg!hw+H4zgFjPZ!S!+k3_AsjbCe6{1V9M^|LBZR6I%OqJY zt)(G#(H_YlM(;ofVTUBsx%8C8#*g7q#%fikOQ6(^odn4*Yms#=Q_un9P4!9U9U{-SSo8Org zo{b<_hr@;dvp9plyBKpk5TyzuZY(fMA4)&7643dUTQfuiey#&o@9zho5-$ z0EC0hcrI>G#Cg`Sc9gW=xt{0ZqM3-gU`(9Mfr}keky{758p?V)?vv*AwbU7H%f5j4 z8|g$KFu<>buJ`xp4873BG@aPj0FrjG{zyrBi1lMW{BmFl*?7oO;r0RCSR0Y{kfl-+ zNV?tEfJtQgF`s{RV3h1}wh`=PF+;Tnd!Suhqlu*jkd#C1gjR08PzEIZiLu)*@vsGM zt!iAH#1vOwb0;ARZ@Fs^F|`CPwxt7WqBVGSUkEX-&2zE)Sv+?X_5rk_TwLXVXD(I{ zhdO`c;)M~{N$(PYU}X){-^HeTjE3e z`LrRncEH84D{D%`MvZf4U%I1g-~P6Si);ki8~|A=_SLw^jbn4Ku*elLC$fmB0dUbS zB2?Vb^;J$cJ0@5C!oDo~OL92GSIUoK`sH{KBN1>B76JK*@6PXXA+czv#YL|Av0^m+ z04Ae30JENhy{h0yS|+{PE%*+xapalhc4mv`h*A4H2jy<$nY9VshHjG~ht3I@HP{vj z@n4v+JUjTI?8%&CI?U=*hE^{_>PRCX(AmGfQ38dr7unEX3bK=3$E30SnKi0(CqzDm z?F$+Mfqc3`QV4sA9rx=7S;fYJ5443Du4>pHQBMXDlb>o|bOL_z-C$!{%O=1ouBbQd zu(wx81TRtD{0BlO+PNC5{FpPg5(k$*vMLS(2L899g>%(n)!CILO7%}&gVJOvz8n9)%ZRy~7OT#m z!y0@8;cfw};vQUmYzM!Q`(s%lW5+a~&<8*0?gJrB-yK+0Yt=U$R%M&CGi7YCRp~wv zSk)3(#Tl$(mD1#qNg*sxa1vdOp5~Fntrf6JA4)%~LYLDD_jIfvqSnAFuH?3#3Td0Y ziTQ#Z#me!6QWckPUd_Mr)JisK0Ae@7;&E+&RU7J@mrlyrm%nrHBPEx0s(w%(bnJSj z>>CSRzXLcX&**UY7L^KhW(}p9JnYaQ`hb9xJPQa?0tC1xoqgTtuY-u60_5Y~Ds@mNU zfAj+p{NnFK2M?Q~%myC+K?I)K4cW|VSmG2c?otVHv_s%uaQD_emh45$X;>si1(?Hn zFk3eA7>H>Sz@+KHi0lxP*_;UBJqVBJ!PIo)F|haz1DKv4U}vllcJi8u0XF&;7oP~y?fOSmT6+YFrk%i z*<}Vh;n%5cFjOT+m$O&5LSiWfY2#4MO1V|T1}LNgGyHCPjR+x*l4{b%gzc}MD%T9V zw!Ok(!AvPgTMrr^{JEb#R8 z?!?|lOWJB$eNd`DIV<`Be$JrC-YsE{Z5J(R8|sDU10a#W7o?4QaP{G5#xUI9Fh&N$ zx-%zwR3bLSg;@K6v=#kVsUvM=Ca`kw+IR#_gVB_(AZ?t%Drr+E-M_{*viIE>;?@nM zO&?0Xw2c~q_A4MG#vi2ZHQ2wIyX84*|Ay?pOLt@!aLAw!q$}74 zfV8E*TP|5*I6ddM+YRM>;d_uRJR;^(n|&I5B*N}m(#Bz=HSWu}S9lO#V4wCbMAQSM zt<%o2;<3&jbNc^hpm7)?N^VF8?HVR+hYm=e&T+)3CrBHt_0e)1-r@ixO1kk5`oSYZ zo45BspRdm`NC$um)Ip~g2KdtweTSD3i$EZ+G_$S{5sw?tY0E!|O=tzKI})eLxI%|3V76BzBNRHLWAddpS`@48J`= zt4}P5T@a09?SX9fLsfAsb*$~)R|I}5BzAo%kV~{b%na-rICAh1b=VN{=Tp(2=vOO? z*!9B@8UWMOKt9q2z`dwY{RVF%cKtOWv?CfI=Fb8!*P7nC-!xdVBUn?%qiP^uLjZ0v zMBvgGVmCkoJVt>-tE$Kd8e$XBA68Mf8wkMd33gD&bV%Lzg~zFa3SRz0E%x6IuV)Yd z+qXXnz~dUA`e_9F|3l#MwZv{Py)_p&JfQ*l@gJptd5*wu@YF*nFaQFFCpADmZpa9( zU|%t~7Q_gLf*9@}X9Nr8GmHgIP!&j2bX`OtETR1vMGm6r8_dAckuL3>Ybs z%=%WYXJ)IK8TDZPW8zh*M-esOg;<7w7*f;&uJ;tCkO@X);nhtrpLuvSF}w!TF{|yp zG71GIcvloL9RXtKMYF16Pok03kHmN+FNO+iKZ1|ICeWj(7+yp_FSw$ZIE?@okNSuKA>{t1 zGJRn_c>Rc;*a8ih8%?aof*5*EFaoCy|HqYiVN%zWd5Xh@1J>>#Hse4HIfGA4-tqgM zs)v@Zqp5+`dx+b35JP<^{bFbuOdokrniUaE05RlB8V>I%buMq7x368Ya+2Vu)a-?e z^3B+O@{*;9J=&a@n5td+OeFQ7^P`AuI4I=QgvQd@8$9!F`5%K+E22@z_#IgIUIh_O z)KW<3PH}<5eD1xF}-uJH;gw=1-&bW7u;B*cPGAK$w`ogG>z9g?|~s+ z?SBCrMsG2+P8>0w&9f@KA)a%En8X~)D%dfb%MBUoT|yk9{>Z912M|5jkJ!)EV%4Z` zRW3#+N|Th&h`bA|ny1C8F2C?Ruvj!7Sj9cK`sfXe;{JS@77&MBGIs`cd4?HB5bJ1Q z)sedb9ab$eX=}=?!{F4g`su`G0kDcQ_`8cCNuswMw%`D9TL`Suhtkigw)R*u?hD=i z*numVT=_`4twOBuOCPE{6Lw$LV3W0M`@8<~U}wZ0FekP#K%k`h52P)>dn>v;n+fy! zDl`O|zZh{4rWG#MB9Lpy2gt3TmCwDxkjsd92yw|J;9}%I9w0vDY?AwWd6kQiOO(=v z^FyTb@MjqYLz+fQfk1tP%w23wLoEIx0y7rhFzu~0Lx(z~PbINfrp2uG@La2o(0hiA zg!x>{fms&tjla@#t2$ygBxI%sv01@0YfgBG*Vc=1;>!={lfcqeK5{;-xE&I<5C zV{nq-0(Fw;g+1uGjr{tW*slVT_VBl&B>j(UCCw^T>?Fp|AfC-)Kd547Qxl^E5Yb!> zOKf8h;Vbyt7q6};B#vvV zk(3#ytRBQqd5ZA$iNtgrkW@|shg(MD*)3Vbcs)x$foDz~AP%vA zBx!>${bXmf# zL9XI9AZfsnWwP(Ht}1RVb5(|Hc%~ug@=j>8Oh|+YS|p8-zUB4=$>&~S3HB$$zQ+;K zb|7h5i$3Cj?lp3q!mC0Y?On5_KNC+&&tFG-tTQp%0VIVyfne+fj)hTLi$pCha@Bu{ zLB+9dFg&&sxOhasFxg+#A&ybgsj;zA$cW#?b8+8&FRxWm>Ecr%7x-50_*z8$0~26& z0~ZJPKtlYpzoV>c**w{fOKWww7@CLp|G;V50|bh;x1j{GVb_z5l`~=1`yTcHyPh>9 zqaIS^xJWBvlLQ1B*vo(+WE0t1nao^fPqXLQTkHeX{CS940%?hRfj}H;Dn#C;HGCA^ z1k-%*>UMMDm|TrOF-%HpZ}lff{|)UBiSSgI@16n#YD8PPZHw^ik!{2{l_yXX## zPst$W2enwW72{#!m%*wDhk#Yw+fW}>tWvxq}T$Z1fwR(F^(SMXk3B6_wtLh9w+}J!K zOs~c&*N_cT?!9K7N6b{{)gK2|9c>&a_H0`-ccF7tuHw3+=hFS_ePrEGKqt(Gjjc`q zs~QOzzhYWE+zeW{lUl6es&9hbf^Zm~w9EijodH&z{;XzI6YPkDM>!LlQ#`B2cw2d8 zuA3~en%;yyL@KingAU=FD~Qu+VAbe`$dU(_=E`EmuaqrZZ=u7g#TZka*a(u>GPPT{ z?x=T@#>c}57>l0*ZKGY#!<{q%f@d`#=#|0z9yq*-?%kyD+C*3rFsJljE@2ONQuufx zv;fR$J(zlZ>D!tV4ne_MfXUQ@F&=}MiI99~379NBm`Z#rlO|3h!rFkz)`KaZ$lEC( zLMy=J=)nx^ftX2-L|6wfxq2{s^m)=GNZ_msm^?k0!cV-N8$?(SF!_2gPcW1}>6ix* zxbrSXZ1N~~Ppg+$I0w=S;R1Cr=!NMR(3*108`BKQwq{YTXmzsD)J0x<27LuG@DQQkLD;V%%q zr#7YyfEo0;)f6(FxmvY5#=~^RrrFSQ~$y2tQjQ zItOCNJ-GT%hZ@b8Tu6_fxaceTvJrzkiS>C9!{#3w=!l`4$qQ4a6dQtwi6zA50=O7= z!C+PIS{-U+P=h1NU~KXth@n1|elc8AhrY6iUok{<3B-^q*>k~7*`+SIin@;Vl^ZQg zWd_TyDW1nh=6hRF?2KXV#I^v$uvN$-nP;U!VISW{S>yh5jToLrX`V4P8g|Ll5<@Q3 z2%Tvu_X^8KQd^OR#zb@(#87g$hqy_!S*~S0aT}s?@`%%Q5W^w=A|d)-nI-ewA0@jUyIMyK>rSBf*-mGO-3=PY;*#_- zG;u6-R89bkj&U8+*`DUat{8yZ6IMZl@f6cPxQq7U7mPsYfWXefh>1|$1|LSvo!tjE zExV~HeVUfmN>^kAU-x0@ggcnn2yq>_O(q3ur2;a7GQK{?Ayx7=tvDCR%wmH2^w)~~ zanVHV`OdzOhl!0~5rEkgs1xz5hds+V?O-W@yVN2V`^#Z`eR_?AHH!WHM+OfG>Iy4{ z6k~j3PWNTniH*4w=r;hC1L@wUH^&{r{*?;=QBGNv+@^B|C)u zsM?Z-CU1gAS_*mxQ`ngi#FGrGyv4dQJ;}f9CibeT|7(hhY7QBP55XhkP)|YcYTWOx z2oUVW{&SSSCvkhkFDcv+lC}fj!>kzAPwLR&vt;$6F}Xw5+en=2HB#g@y{JfnY(@!l z|1H`b6HOc+S5wN_jB}gzYHgwah7MYY@QlgC^lwngcEVW5s7h*pXY(wG@e^Jt!;vF% zI~*W}WmG9kFfKSZ@B(po`bVYwh%Uw4FxZgenU+#!T2=XykPHWhPd2^#+-b4I{JEA= ze(i(j70Za|1t?_;cxCEC1f4PN?-P3trjCtRAi${U+*=H>ehEr>-ldU_QZ_PqY|5O# z$im#0vBc&dP)g3=?@HMbv>~F`pp;xmC*@Vy`r2m| zB`aDflbUYG|1oj7wCMaliYr?Xd*M70SZljLO_$LN^A|yOP)ojP-jW>F!ZQw=p80EF zVkBIkO*6gl)d)*eej&DRKy-8dy(_!OUR9X4?WR2H|5PKobFf8qB|45?ExCm-FE@6em5pIA9&I2@#3eaW1lf%gLgf7 z(M?-SQ42N%5vPwJy4&55l?6}w$bz;`l-24mSVwd#IwBtSu(SUJEG`??jIwwp8A5JU zT9dczSn`C8VxOz#qkFy}{|nvDI&x88m^DX6k-L>mNfA4hyo2ybzUuQMwD$uVj?chi z4z&XMbq>qriXMU$*ezLD4|Wv%QjLpF%+2aMBs7Vo#uhf%MohnIyq0a~k1TAmj2M68 zxj6m-B3rlVjY>KD0L3X3D7J<0xFF1tP4y+`WCP1L0K%ftw)LzTgsdzQdlh~N@ z1PZGC-Se66N=Z;`$#Ofox!b zxpo(>fdVhgfYbv4Fze>#7L-}>k04jE2DFcN`x!9n z$OF<+^@#B&Z`gb6SN4ReK6-mg$|c0ICNPUbHKWYxs^}?LfNuLzBN1`5sK%`6%=_vS zIp?F_ywq|6F|7s6648iBC-j$=+Aze}l4n*128x!t#u3BXlvx>A-K9QZ#KG#1%u=D? zEgk%Y*w@iwR^po~X5j*U=J;bTy?ch3*VSUyLkt5iedkO>^?+IT;K9|0npvrk_G!Y{ zMtwR(U-~izvZ~+DFKgjRl{ay6 z1iHQ1iY)OhJ1X0^?zBu<;jcrtwO1&9g>?Y2cLG+OzS@Se>M)s4PF8j@7|P_6b?jmG zl?w8{IDK2uJdN&+9N8k+fJq<=$-c@F20lyyImW(cvsKA;5j93cEE@x>IMfF4I?sLW z4Xmnx>bhb9jA1va#;QZi`Rc5C(guyKf?l>Wu&OOxr>>O%&&FmD&TILK9O zMpM9vbqiqCt)ezMtZHduX~vv!r8inx zXijY0fmNJAj#b!Rse9S;yHM0BuOQ;q5?G}VrJq$BP)Jq$#?)2}nc8M8^ zhf5bKRsOqWt%qevcb`sGtiv$jstH13+ZtG98e||Z+Fqb=zP%dOsryI6s)hK{S1kgE zuZlz-H)oueNPX1oc^b!!(ljX)b*etL+;Qp)EwApk1x{1^8d$MkbFr39JVUKz_rN zpgX*}L2Jlj28^K|%+s4_r@=8;Efg@&mi}hv+cU(7Aazd!7-(F7!)(T3wACU=H*5$P zXk>rGEWbZZ9O39w2M4%o!&7quOEUk1?3l-5`kG zftR&AaU!ptu0G{;?xloEb%%jQrVaDvUNRn$)>({(owMe>4@J} zM(jI*f;BblNEPfNIZetd*RdzqRAvP`gMF{MI0cdEZHSF0_yvmx7%)dkE~%(YWw)|N zAs;83y{J0&1yQ+q#L^2Cj6CEe zJE=KO{|&8yy0WHi8)7O31?x-Wgl_lfE!KF#qUaJ{!JcDya*a1An3O75SM-F|41zff zvOg-=CVXvcc7+f@E4~-Ea??=P_8;Hi%??)33$zzUFYxOVt@8sPU9P2hXN{g{G_NK7 z`G<+AiFJW61Ib%U^O$yce*9}9@&V1`UX}VN0=?t@_OV{fclOyV9}F6zDPn95yz~=U(B@Z;1H;E>{3(-eOfhvH6i_IsW1*AN{R; ziuCrlK-mQRAvdtFBt&=6yuL!_8+zKYHCGag9$J*+s$YN~Wb9ZN`0ELj+YX*Y|MzOj z4a81K>|7W;4CE=NvT5U$zPC{FSHovKrOcg;|s}>qOVZIwKWLL6pRpBVG8|PdgHhqE4>_7wN zZ`DF@^S2vZX5Jg_Vy{7FfiHF&HvR=cfPO${4kZLS-%swS=q(r}#JlZ%L>&89qjO{C z9xTbEeS}WIKEuXC9>g@5IwZ*u%<^HWkxf?4#CQNt=k*diCrl)U11X)mU|Y7SHMseM z{z&IWy|8?@JYqjsi=5r2S52PiNZA%L6p@L=#C(VrIjzwn-IO6DqM<-e?!ncEdh*0J zb{b5)b)V~?LL0E5y!9|3=lFYK9dg>6v@>I@F`m5X5lnOr0djH%e;)(=dX$>l>|jjX zh66eEq4bk;)@Ll~kwru!fSg>(UC}k=!y>LJ(w2=-ZZ^6g^UMsBnJ(@kpS>Ef963h< zIiot&mhar~L}9sdj*?pxSN)(PKOyccI3%OA$jMEf;HH>!uW%7|1vWo0CZf?CIadx6 zx9C}sbH)CJ#?3z}ye7T0?2WX=9kf@rmKcpehh#mv;c;$Xh()LtIl1b4o}uu#&d`Al z19IL6a@P8wCg&9F-N*F?a*pN68Qjm;Yf@BWiD7yXPtHN@(MEVIaT*8Y>|KI{m=Lu` z7B;d#*4De14mo||5T6D!>BmE?n~UI<8!!gld-op+*|UARb?ZNJFuWf@1b!fK=l2l1 z2>|56yyd_FZQu|N7>x20ci)NFg#(a_1(zEb>Hs0Ph!NaFHpM-dNlY56dnCKicibXn zh}}de?He8iL3$%~>302nVGVGokU-XmR(wl;SlD+G0E0(!(R^cFAXG@;<%~c@5V4yK zz@2Ls1JFbl2o(~1u8F{#0mNHmi$$oQqO z;^|y16&!W?s>VeLq_Vcd4C}Ohu-+ud_?u3c1j)S)^`Txqd=a~uQL*geOW0JzzevO+ z$cjTgIx5)FBoNjq2*(@!fZ);sP(jY%Gfir-+C>q!p{Rt==CJ!2i#Mdbl>Mvl!Vh=M zj?`CNzdWuspe4804#w2LTJp%RE1t)_+rjwBY(EAo9xnlTj4T)?ZgQ8& zZQ1*QMjk_Ke@Q18#z<$Qgm2FT-(@MtBP?g-j6L)1H^Ow2AQwXQ&EMi9Ju$~5$Y|&; z)Y14Z$FL)|{ojj>()`qWTji)F-qC3qzF7x+_# zmZ&OJ#;RUyg26cB_pBxRRb_)eZlXMz*sKDE{u%-!zp5W9162q+-(ZCCch-k3QDy%` zd%Yl}zZw|Iq3Xe2pZ&6$DS`z3uxpvP@&a*Oqr*iXh8ef1`cfbk*oGv=!s^3oX$K=7 zJd!W?`6VVo;Bg(##jss?+udcva6RQ>^kI5tXPwE!VZ$Fil8Rc0b}1tEv07YQEw19? zSW2$G*hSyj2D%FywLFsbh19~XW032(2|N<+!PSSFizC=ou!QB_HBGTq-E|29kDI|G z8Meq@hl`($C1y;EbZT(7?+aoR2VCR~R(T}qH2X&Z9YcNI1G7&tI6xbEhOyiLx9Kox7 z;f3zxJ(4Hqv%L=9vy?QrWXV6o`Y1$Y789pk;E@OyBO%6pQ^{5dZ_C}QIq z50<6%Mfe;iOoGJi#LJPMNek0{OM*VQs~3)jfeN02F&6N{vOi5T8gOBZJ6(<52c@3YtZA^`!9p}j$FxG83ytP&qT^4 zQBPz6<6FwNjt!A@{M1X{4H=U>ZyDx0j$5mebvf2ZS$kBvOnc|>PT1%ruLfT~T@SOk zSNLWUt#NYd9?W+<-+i<=x4u*EkCZG8v+Qe_%hGpll}6*&lzar3bpn_Lvk6b3z$bsM zmhZ?_zX;=NDMqmNMFucyGb|DHPQ$Er_vwvO>O(a56wj<(*|}b?X3ddAe7E75m3kUc z?IJPX(fKnHqT#A|nbYNX+5X|7I?Q^E(ccu0WMa}(?Ql;*S12X?5wXvN_R48gFlE(S zRUML`s$;N`O))sl_99_q$#uNl0+?oy1?`ppa0BLnsxDctY6IE(DFz4GrKBGj+Xhi< z6NzOuu!=*?_b_%ph+|H*_9~ruSe;eJ(Z|}C^M#n^LVJb#;HL3s z&lM8mJifj1c!-8C!R8eCw7nXPZQZ_S6NrQ2kL^`tG%dfs4fu{qEmrM{xu{{48zsqr zctnaH5%V)ztlIkp&kuqj=(EsXaSyIO)U4XXS~InnIaUe`k?kKJNvzL7d(~=munwyZ z84ogJPGO*6|E3AV<~*<}01Rrg3K#X5&7)4;A#N9-z0!x$&#H@qXoU|nflR-P&|YyR zPpoSopEc7_d3caSo+@4|lZC#>zwCZrR#%GH&cLcm&|W=z)^G%oYjL- zVm#$Q7G%7(1k5=-mJ%Q4G z@XyiIO^S@@8dI;fOuE} zS8!e1VJN_!=b>XE#Qp|In``kYs*D+XzMH^P9) zQynF5Rb7~qOk2pni6Aq{tqXXgTVcfVCP*8HY7Wwt5@8L}mi&ueJ?ss0$J_8-i&e{q zw(-nQ#tS{;=mpxfpcfvYcW|VZ3vs-qBZi|HKgOa*Al}GV~R9l*pjl% z?;74I0hWI*(Go-ZrFcGlEfGBcG2~vA`cRAEY1kA>$Q-JZfUWzH3nF4&3SwCI=1?6m z{L6TV8FOG58vFng!ybYdat5`<@G%sD?jUOL(YhrxPtivoO1~J&1l0bqhE_!M7{u^B z*zX$9P=3EjE9JP_J>-)U9!nnQ_LsT4hAR4wM{FBd;plG=!*ltKku0}wKI=cJk#PLSN-Ss+Z;OrgX_gH-x1}NMVwv&7j14Mg}lb^lTA;5CNn8NsKdoQ7KrZ~ zP3->B1hQ)A2C}%&STv69r|0X^{BH;g-q7E>X!_#FjualZ3B z(64JZp8c*IlAYu+hGkC9h^4zx zM{XVkyFRIQshX)SG1~w&o*hbJi8BVPPZq+qW&eU0a;WRjdy>{@0C9<49(cDaFpa&f z+SN=&qMv*X*$1EbEaJ|y445E@bN~Odi2D{$a~Vdk7TlL=N}0wKR9_3u6CK?QAJ_%$ zD^*Hv;Ds<~q`Ty|%*Bkp#?>+xGs0na_8)&#NSb8*Q0vl^vzr$5#Fwe;?% zqipqNE}q^1O8ECzfGW)ft+KHj*KWxDu4|tIud1rJQd(!;A@k zg`gZzN);$2XYhBWY=+^oOeYV_T-1lsuar3`E18|5Fmo{u?BDw8BA@lEqw>wx0D145 z9b{wXUC6%^HYlH8fGxAfN6cKTk=R;(xqoNn&?PP9*NW0KN?CM*);V)rfNtjEQU9|P z!@WY7e8TZNbD=k8E-u?1F5c`d%^f@}S)-IzUv^2Ev<6al8Df{GVdf$za{k+UVWA+EPieR68aJ(bZ&*(ojHfjZkByiRZ8Q&+{IpY zpW-Dq>n@}y9};ij#FMi2l{vD%&$ri+&~rTgJf!TI15qal$5W#I zTbZHSta?SBGZ5}z-AN)zoJXsjeIM>G0I#La7#Py5RH)XgzL8?)Eg8p-CTmI2bc)KU z>qjiX>u$)QZiCm-FRO;4k6_O`yxM9Mape4M?F@y(j7^(r84CSF5Z)o0m|6g{d}xNk zl^{GT4Isv~cpu~>I>tF&8DeNjeUQ;D5%m`Y^K1W+Sv8Uny~BmrTWR?q*+=q~_zOYg zi~gVXO%b^d7FDmK<%76e;`wv1sAgN;PVeZoyE1O%0eI7`x>j4)tt;g$daf$I*Gv*?f4TymK%S)K<%D zNr}j(bDy}Ez8cAtSK5Z|shsS5c(T}iqC9u==M)VW8^$e{ZaFhe+8Ev6yr&n4kv(`V zK0?OQ4y*kxkXSU(@>;m+PpU_+<@<#HEqu!ABS}aZt@w%P- zLbCeNNS<;cY~k}~1QRC*@LH1UBZbQBYs<&)Es$-Ox7MND9wAy?@PY^&wR;df@%PKm zNW^@{iZ_!f7Z;FQq%$dml!4jIUbZt?Oom~cEdOc=<~wc(HDJb(5+Wxhtdd>C#6gb! zY%)lNH@csK`Hmb)2wc3MYy;^9O))^G7?t>Yz9Ta>rTV~H0~BJ#WIo>!*Y)m!PNHJw zqu=r!6;~kS*o<XuUb{c?Svd~+11-4VNcm(PW+fSqF=JY9rf*U?7uHB} z2WD{wIcDkRJKjX^NckRuBQ1eh`cV3rHP?~aKVu5{5Uqe&T*+3^j&kwnCd!42+skJ* z4$sfp7My>)=D*VM8xR{U!hFYXV_oF+YBpE8ncK>RNB3)(bqV|CXEum*^Bp;6g>2}e z;9lXo*Jx|s8O(P~s*Dg{FPG=GoPR*Wtc;$Er5%TClscfJcIGIoF47K|15mo7SmrX3Z>_WCkY9vPR%xZ}*^lTsK zn|B0eHF<}GC{6e-+qg1cmM_aNOE9an|26WKI2nw5}M zqy=`s&NqN`KTl}PYQfM(FIAo@O|_5>W|P@SHj+e>VN1}SsGOLzSNoOa_|WHDj=~%~ zuITC~Q~g3Vko=wkC3bx;Tyg$A2k$CVQGLbJkSp{K7YF)b4xXI0aO=O|+2NJH<=|Z$ zn^G+Y@8W`}|3ePm#Vww?8Fe3{k7!usL`kx=5bwSR*6i`tYT@{dx{F!RdGrBRaSyIO zy1{$q{uqcO)?gGCzp!U^sjDq!)Wzh_&|%dg<5gyia3HIfvh3 zbBKzD8EAgMDt##Ztm>JHB^3dfQOA``xYkB)H?o6LajuTMWpE?K_-K1Ytml#Zlrf0C z1zE)1puPIMLM)#<%~N^R^{s5aaJ`0A@4^rVv*vU%>Nx)r_QaJs!7CuxlPhQrD?9{1 zFWW6(w)j~)dG1Z;qZ(FqFc~Y2%UL1qh-n}Ntzprt?!YQo4kQR$odP+mc-lj&y|RSr z2VqdIzz5cn_h7mA&HIiKBWb+~y1;^+9UxkFNl&!y07kM4y0App5ikXMFx{7<9bbrM zb^=VH9*jSZ1QhswCqhraT-Jlxq(nP@5UGSIbHXcnFvFkmn9s0tIAE^o!Q?$aOxI~d zC{8Ut^_dG^kA;fL_6I=iBJld>v}K-t#}MXX=Q-9p$AiDjTo3RL{l0w z!C}ZKSNrJy@o)I{%Bqw`$G;h`v#!@AZLW>wWo<1gc)|M$OlizfqD<8qRZAY}`b4($ z*>W9+Apljn;O90X=&kKA*r6mB`oRtueZYC|92-SBC{(4W)~HmB2NS?-WIKS~jlWK- zT{t+M*aU&ztr=&))KsOaR;Zi|8Z+LIgggoK?%@JNO$Z^DeZhI>Py&!P*AO$9mb(W7 zh=q3{y|`aB=bagMsI@14j{JW^n_`!}@Ue)P_6O(Povw7muL@rHqJ$U+^UnKB>@yTr z#1g{+)M0RUr4_ks?oJ#A{?TEu^+t5RmBfCKmc!6+{2`6BInrv``66PDrT@&?EVaT>o+49Nz-$DF z;g#8b@-b6eDgVxRER)uVr=KzRdI~TSRb&@Igd??__Xz1B$Y5+D<6e3QMvRN1&539f zh+)jh`Qkz2Wx4)8PHMz3^pdyKyL_GWHFhzJmct%Oqd^Q|AIAu1`dW%MyAz8sT4J~s zs{b<%ukBq%EJMM?cmpoRhqr1jhGx>M*X^J;6vjL6#cVCFGrt~)eZq#*he&1k9b2w< zV2BgsIerS*j1*$m9hDuMv`tp4u0V&2)3LvNeRmsTH;zWYRzU>p5{-aC?60d&|E~1I zF@A%+{Oc!TG1ZZY$pv5m1@`VbAh@4TAOejOv7VP9oHs!ed@JNFRz=kecR!-Q8?eM3 zO?BjomqRwOZ@_@yu6&%1TPW0U(o+PsfQ-S38jDwWAg(6B6*e4?Lku^%Bw|)06SEiU zc$EiMEfrwQHb9FIV5eD)ObqwbMY=#(D!_QeO9U3cf(ujVt({<9hig302X>L_MMI;; zQ&u6c^ao}>w<`@j4Ue-)|(|xF5VC-(cf|dnmBD*#*pMWX_ZV@P-!9uWL|XpCQKY zjw8?$x(yK^hCyQ&QZYcqTCMub zHh~=@{$huaHN<-gqBeLC%NZbs94ZTXPvgc}fEa$gi&qaVBaSnxiQy9FZ1uGnZ(#4K z_;@ifjRZ05N7E9w;0Iis4+$HycrnbpiiXdwC5E%97@oyu@@5b4^XB|f46S(dXxJ|z zN=ppiMJFq{ADufI(f^iorgyqI1$s|&wZ!n$S3G~ggNWvV7;+D;KDf2fxxZ)ZRrVQM zvsT1W#NLPA(|nM&uyG5kNn4s3GjunC-h!VO4SpVHP%UkhCTC0@LJ@`;-Jhavg+vm! z1t4wuQ2M3Kt|OM5If{rDg0$5D`zl{=`K?Mf<#11Hxo1q>eDnLgrSk8K^T*6a>@3(_ zRjzjFN4&t3tBZ*3BG9{+*#Yt{_N|p!!JlQ{ToN^U*A|I&>zX?e#%SqX$cDXKP(#7J z*VuJv>ow@?V$i$$^%je-wUg$WN91et?#szl(oLT_OVff8`!SsuEdjmj2dh?f!Bf9r zxO1tN-f_?5@t$70-T5`KTn2jg9Q1C2M()ji3cdxS6jU@w|LwUW6 zaYq|dJc-i^(7QmcV#t42;`ohm+I)9-B`q*EF|`S0joZ2UrJduTXkCXpK1;} z9kza6%C;aoV7F&P7C-~G5?D1N+<=*`$_La2b||3cu%pO2vKpO;+xIevi2YBNxrW@iQR@f>!XR|>T0aI$ZV`W2h-Dy-tw-^BVxJ+Sk;%ZYFq`Lb$}I5*Yd1N zxQ*wU-64kSD68rk;TaiBd078PR^4R~Jpeqd4O*;fwST9ERgRP-*RY+vI~rCxiq&FO z6I6h^QD2B?Bd}^DJh=L}4vgadUa@D`n#>f7A!y^CsXMXW1gui+SgOOS#l}a>n1W`s zO7|KK;Gke zC*{+;e`NQQv7gVugHcZJ?eiqUcr9k7MC{}yXG*zud#E{9s3L;yM4haBx>PJyNOEsT zE@_yR-#t=l{HBF;F@EOvzE}~X1Yj0SRN9F{QukPx^1NM(S@gNQsOkH)!IRhl%-RiJ zeRmDB)?r(9-%&^e?bT_#OTwCV{ET14{T7fs2p6cw7tLMRGz0Bz^CUKjJQp9VbnzPI z_eOGYyW01V#ZXjCu2)nbZ)~Oz={$eDC zUxCV@kf5*t8_1GvR>U$1NXnt!KtG^g*1!2(1ZI1vjR&1!+p@jYNP3jXZ7s*&pZ{-Y z4^;mL-HeH8GVKR&i|o8Ri$;3ErYieBxsvrdOXOWWnkbicX(*qY`apWHrmg&RaBt=w^^72-~Z zrMchFRb>Iss2C#s;Mzz!0J}er#s?6if5|U)5jx-#Gy z`w!MHkz)d1o}%ArP`^wz`kW?v-`kzj3rGTA`;d{waMgs z$H@lFOx0Y~Ce=gs5oGRch2iSuWcFl=`g@QqvCQIpM-D{^#K6`esVnj7)GXqdU5!A8 zne5hH>Q9dT8ya{H;q%OiX$}xbB-{rCiXDY#mp~eQE>EC)?eN?xnAn#`3AC;Uo+p*^>&lWhYo9^-1@Ap92PCr5GbxYeK}>*tcdWE7JuG#&Yn#Rm_uvGeC^ks=+CfZvM-Qq$Z5Uk&^ zIU7&yEG8D0wFtyjzq2E~_Ou>E-md_Gu0d9uKog=eKp*yLGYC;#5FjB&xBnpfI?P!9efAg~0$qGe@A+&i5a=2ZD1G-PN}z^h z9Qm$l#5QJ^GrQSNWGPwJ36TjchzU$i#T{+E@H2gO5QYP;1FJesF<>mnMDj`1fvv-? zfgsi-GK(Z*clBAe3$eTbtm07Jz;~3^c$M!ZsH{Z|zX*ZV@{6mnY9EtSeU;2WKZL)4 ztc{z%s!lZWz7U(_7ZpNce2ZsQZXHB^enAXxQ&v@Cp3=*juzts#KeB4=H(LH>lK^6W zSBq7rn{Uyu%9)a+Ho8$SVRD4|JuOxxoW0CQgtW&>t?yu99k2zvsiL=R@M2imzlj0gh(^FR+~tpj3iL)uIU z$Xec>O**ocV7%IlNktF;<=X&a^8jRx`$d0u-v1wC=KRcf~GN$ld?lxk*g;9!m&3F28Jw@l@ANdIAxNrGiyVq%H^-yEcDN%7yjxLCj5Gg zX3a;!r8J_;bCbdPiJn;#9)Fn|oqK?0?J1hIx#$<{)tR+m>ixcMj?*u^H9q?2_?~Wl zNi;qCb-N&Tg8As|gt`nX@68+h37%;T;k7wU{nF+wme~*Q#=cS-hmS2dO>fOa;QAa5 zVbWGIY!w#!C@-|@s_Zs%uz?}mM=$=Z4Nkv(q3@$#r&j#k@*r@0i5BvKYz?!Jqtu1! z5$dkEMQM3%1>YP~8%c}VE#IX@u*8h9gGOSyboDp&SoI|C1ZTm`<0rvzSbmUH=_O!; zQyQHFRYNp}lO^x6e5~4$LsRIS2`+C+8AC4WNa<7{{%TfOp&KT`e2d1=jdi5W$r~8J`8QkOzwJR=4Os`oq`E8x*J31VrGkK%AikxLcx5P}>Q;QT#-#E)Ld z;8230<&A}^GleF3T#F9v!U8*Y?$<$^JHT@i30q<0U5!G|MneJ$O>P(naZ)g6Wwn=t z{V=yMpwR7I3{K6xX&~$=2)i#M;ZBTd^C+zC+8fvE-_i+#f?Kc}Xl2!dgr{){J~j=S zmG!rELL49HB+LvptwmAZkNIKXfOw)%$R}_|C+w;jMlh{PuEwW8oN;TaEAg&Q7}&K- z2jTXnFO%4w=3_r>3{B#tjIGgK) z{}~9`dz?u9nNQckz|lhJJ>A*BOq&wsf*88sHmEhYMK}z(2s%=?@zc}KYzyhw<)hGD zg?Uh-9)(lg>SFjI8m2gt_ z>-Eohy*^|zKabx7E@l45C|)eRe7SlXx={}9@mv;-qJkMk>$7w;w>OBaHAb<06*_hc zw`wWJjAHpYbmUVWINSWwD0=N->M#90!LhuaQ5<(}sm>_YVm0h~SyB#<1#tyEqc}rz ze0BqnRz#z?0$-W-qcw_mamLegeyhz-GKya|Oaa?UXcYh4-C$r86Gdw+x%L5cqchmg zt&9$eP@vW*{@toYw1`x%62MJ@M$wqcxKRuv`oFw&0rPg+Za~5cR@~Q-=^(X5ODPmr z=ZTNf{7rq8$STT`Sjje=PPtfni7fbhaE9rJr#eeneTt8K)0e6K z%g81D`Zxm25M5!3(tyeID4*=X+ELF^3XlKCiq1g}*i=PJ`3)_ltIksXn99z6>roTz zq#8^4%+1B`_JU=yh$@{mmhvODc;6-jfvXc*O7VZhmnqA%BNA<$}v~Z$aA26~MM0;?{U{vH@;$MCUBIx4TL75QoUz5I3PfEpC7J zaPjHLR6kl^Fuy+HW=v%qw>qA5WiKg68z5Q2m7Qm{Ro*)3sS3GVMQPW}Nglr3Tt4(l zqwL~tq#c7(cioY!jCNs4F20E>s|lx!kuTJdRp~P676#!$Lp`#DSfY@>NO*(I$n(V*07io9mf+J5PtG9$RJ57f&lfkNq#;fl? zIz}mtnLlgjr3SNjbHdV`SL%H;@DGTWN{=$`Fp?B&KJ<+ z7x;NO0PMUpEY3Vx!|!&&HJSB|t{N84Q8BHBj>dyV0)>*gf(^NCnkf><@H0elx3qRnxb0HeUoT zex)GY!QCr8T%Awd(_hcS!J-*L+LomZzR`~gDf9)AOarM2bsm3xEdo=22I5e3TXhcD1344rvh>) z{9VUs^nduF<<{MxGFAkDZ6LC^t!$bBiwU9&mR$E>5@kODyXMHEP~iWv*mo!vXN1M5;`c80A+HDP$|2Hp1-sS1ltb2pmUH%NX z2=>9q;^y&T%8nZvsVYXADxK#H)3G>~9P;9qVHj}HWAQlVVi&d&6kg%8RjjPyk{4{3 z{!tyoua`e6v=WxvO;xaohBwrqQqd=Mnjg*f?9rKCCz1?{rYOiI?{>Cm@yn&+ag&< z%MlR%_8pa#8n`Pf-r8W$$}ORuXvxJKaBPPF?MU9q0D7xl2!61S|HL&iS;0$SHzePq zk_&>^-p8?yI059ddL`6@ll)_@mdOl01X7`51ya4c4K^JRAVIYi0dk&GkX6^}(oJ?& zJv$Cu!b$W7R z=Pv&QXlPG%JxKR}V^=+ZQVuLsX)&nD{%6BHQhM$HaW_4H6yxalcz=*~M}Vs07uSA# z5gy@hKmP)EmWZ%fG=a1W;=wi?0rK0r(*U4lqAQkMC{;#C!UP>X5FnvIA!bh_)7o_? zSBA2p_(~Dr))N6TrZNuDDhXYQY09O&5Fp{o)=k?fL!IiY+K;KJbTZkIHTp%YqFO|f zB8x>d3%KL+!M-;F^nP)eGI6$t%3oAY>E$(62awM-q09pA!V8e}(E~_m@PzFkgjbl( z0y701T19DJ>`-5SxlC5yt!>8KU7vLTt(?%_ckns2gtOrqGQZEy1`XfM(&`qqZ1E^aN71lrn<{h-o@|i1iuvHk?4bV{aF2Koe ze8XRqbo>9B2~f{*M8pMkd^Rv0Mn9x;}gm+ox#d5a}NXCQAm}O z|2_k%MvIPHat1a*QAd|s*I_OQ`LP4dk9f4Gq4Kd z=~0=x><~&Pdba>cM+|!3$H<2En`r;N&{U(j0+LRsDKMg`&0MDfQJ*#->5Q5OMl?MZ zQ#pNb;Ghd?9vacmc9{jDzO6vg6*Z5HXg2(za{8VHNjKCyHlmrtoXY}HKP5=IqvnYb zP5(eDr(Xt0!cp_oh$cORG!Zh8^gzusBbv#!8qG0~V8B%J+=ymG%>PZ=qdNGhs+}@fb|4Dv(_3P{{eI93(Utxf=wKnweA(MU!*f@wb@8g zf%!s=22Iphu(A8y{ra4Ulx^tSOJl*}S#P$$d|L##PC^ToD<_L|{!A0)l$5H92 zSTL-*f+aWqFAf|hqXpY`=Mb}C|EZ$^=b~{}xPe@I-X2cD?Hp2msKDkW#*W7*(gpPh z_@O?)o#aMvE%^>`2$ERKUtnH>-(f0RFhNxX{em;!-)Fg6m0^u_fyIz~aG6%hf=%Y8 zdIV^H3HI;6$*k*HU@^J@SWHI?7Rtu*L)ef}fyG1-h~hOC>?n(c6j;Qc0@E4Hg3Uj~ z9@kl#Z*C}dnPYCw4+Lo}CcSi3G=4dNyy} zyV)x3x1cq!6wxjaC**;6ww}#vMRrWQ1Ev7X#yg5)OxvW)7-F( zX6uS{$c^Vl$ae*O@jq)p<(E%b9ajQ0@ulSWQIa zWR*B>j1IYyU92#h8V$g1sRp_EgJgd1d{4?2Ex~?1e$u#cH%O(J53b7)xnuc+P;{K<@fJ(uZO)n&tYP+%y&^DX_U!6C76{i#{>O7>mEvX;7qYZ}Nig&kg5o zAPZ*p%`3ORIOnFZFnn`}`R6CPLvbq_Q!90-GOkV6zHY6jXhX#qV`r zWI0*AYR?{{!ssw?SzU_730!{Zyba&UCRZ5y9L#%Zy(;USRK`S{Y_oLgC1_(C4U`vPe#wV0#d4R zwpx-NZamfAid}p`x)E_p#kZmTG(^;dzfArm&Q^O->Fq{VM#aHgXjFE=Th?`L0-%)9;7JzRet3bU|LQo3u-DC*iG#+vKodWrC|r)oXZ=G9_lJ4!6%5 zT`EqtNzubihye?;)r40lA`hlg26h-y5x1nR%Vc#`oibJj{@pzD?e+k<(<>|ad9q8D z&SDFfMvnVX*3&Gg^k^kmZ_~p~c>JEMGha~Yqc_-WN8H|E&(}^jTP^<@`x2E+aQ4y; z4Q>|)`T1>|a3v#Bw4~W6bl4W~0gll@H+}y8fs!=6P+eLFF96 zMRWsDW6bkv$rid7R6dN;C`>9F75peN5^?Wa040%wVjH;cNh$X#@y)gkdgHmU!bJRz;Hhdc2fe(NS zpiE_7#jZJaUyovgBd9#E!I@L|Hp|{>xQx#B#Hi}AQVq^5Zgc773bU7yd=L&O9>=z& z5gSn4%p$}Eb|d^jbVAd%G@w?<4jm~gALhK7aJ~BUY}n+>W-2267dwH@o94vQ5A1|} z`w%ca$y%d;N_1ohwniEMY>jrZpl5;ol;hx-sn;6aDEHU-^I{BaI!EQsj{tF&UTgHV zB^|%}1f<#68r{TKrTu7~zf*h>&XTP!u_KFT|4st7Dr}7!mCH0}jbcQ{EV*X%TiUD9 zB{+qxkx<~@)=0a+p>ij7TL+wM>2?}hBV#J#tQIQnXBVyGNId+77>T&R>aCE?<3qf_(p6Dla1d z%+6zL)JVcLr!KPN1za9}L9aCu9-mf17dYNc1)Gc58iiwj>!Z&3OQcYR<3|bDUDC8h zV}I55J8|@~Y~Js|n$`$26bb#Os#bB}dKryjh7BQfcqAwW_N%7s@_Vg;^A|}ruIjXW zaJ+)ZJx@8skn>gVRy)B1=*j2t5txAd9Rxh4l9!|NnTtLi#F=pJsHzC>p&fq>k#mEm z5a3CwE$Lu$6_Mjn)%fYipmpmmWl5~0jbE^9uEUqJR z-PkP8qqFF!XF7=TG{^3MZ`%CFS0wAik{!(D~zZoPPt-I|z{Q#kHSD7%dY1@^E`dD=wr*gAJ;0&e;m`g1mJM}eFW%YL4@+g-sY-8doN|D z<1_{!eAy2hNY@#66)n&MNO1WOAi3}gPgC5$WtcZeAD}z;By_24=e@2O36KBi09x$c zLSCtVsyvChLoQ=(gV{p_s2k3mR?#h%1cCJlEcC!Z8rwEYqb^_wGB31Ed=3Yhev-t)9 z+3X;F_+T&}tnG*NwV{LkaoXZD{VvtkTsjel!yeBOxA*tYG29%meLIdz6_#-|`5`=q z$$)N z)mBr%o@>GMEyL~UMLNHb_4pZe8(x4$UdXp3qo|sKj7HO8B5wAYfpM>9V0iPP7 zUQ_W3gZi%eqxyonBi!Q3;QCoJ#Pv6|f3+=7fgK>!yC$1(IXF4^oVqXMa8}%4-V4rx z(|lH5ZM$5s;Sp*Pre0RvuDIIWRAUAFnj#vZP2>}_xs{nHFAAeW-573Fm?_G}C4bwP zs9xP9mM5`>P@s0Tdoiw9qTIo%>ZA&hfLj?f1IARw&A^3Xy7Gu8NXw!b5UzX_+){b- zY-81lF`>%c#~x&#T^g=fVb#z-ouU)<7Mxrn+w-t{MuXEPIx}!Iv5S1gv$^u; zVk&PWW;H5LL6qHcIy6lL))n+<-;Iy&x|+^q&Ig-{Nc$QLqNM8F*0q=EY+g;UtE8db zGTPB^#*$_Jht5Z8Xuq_8RE0~ywKCGKk`O{q=WSAKy!lwMz`M5r?LO8_-vAd3I7oC5 z8|kF(8$`nJ_uycw6B_BHPHIHL;lshfPA4?dNo~i5>0L|UVxoF($3+^+(qj8;0QIjD=>r`!nemUR(~4oavzU*0UVHa zL3JHzpHp}w%fd<`qcT>#2RBE}eAxgD6kAyRD-W(~S-SFIIJi_TMZJ`}S-SCGPb9g2 zN(T!mqka>HPF2*4bN?9zA}0;?b;y9a^Ef)|%&6b7mffmhl>l&d`6u=3$B?>V5KEM( z`&}Q6h|*C{+b7hf=wQRy0U)lXM}6<7RKn)tAgzwn3$IN3nT^B?f7$$JUc?=*;6*Wj zhKJGDu7T9wXp?6^{bbQ@%)L3B3OtXC2x_9QZGr{PDo22aGp-1Iu=A`X~3wr7x^_hGN+@64Lj`g;%(R8flLO_@e3|^;7Z}%eDuGXV_O1>8KwW z(pWydZ-ktqR>xx*rn7J(>YI_p^fb){>-u`s3y-fESo0K32XpjTX(eD!lX)89{Rp^jbT*KMGhQ25!AftcNnOg`h@zk`Xgou z{KQA%WQfC%yof0qH+chgjS$qX(@eN;C6{qsy%`scZAUM@BW#D~14$K#V>68r)NZIc zfzhOUDfwBZRPn&9G9io=%NjnZMJiAf}nMh?9hhe^m` zl?ik-203h^;qbOQ9b5AYOq((eFVvzVhl;@2=bs!7Oeghu%t!63*ZNL9+)u|LW$Ijd zfs{A$LF}i;;R~|-jUVEx_tUr{-TFn=Yj!e&E_jO(Fg(Fr5q6^B5 zwVx=YR`@%M^W06j{PHjOYTxR5`F6pcK%4NP~iWz*Re;K z$~!m-+~i2EF_m$01J=`(eZ(MDAi2Vo*Omk+>wIsfI^@?xnP|2;)9hOL?D*SDG6!dp z_GtpxE0Nr+^{tgJ;*~0iSq&W4k6}%n@MVK3Ead%N1d;$fa)q9>F!fe==}WG&vYJ@q zuznzt+o<7U+1f|p8C-pH9k~+@){>i53zy#@bJ#>81+(Tv?mX)9H0g`E{#)pgD?I)U zj*1@I7HonLQU!YF7CJ~VbF2_RYBB@+LBSeGJB+RE*Yv<`+2lXkUh!aK7_bXL7Hh=gUacjaa8_*{lPcUGt{dM6Hp4H98#ehS2AkH%qM%BAJ~F7xy~$a{ z;>_l(jHc1Qz$LU4a%XU2lEI^K17}kgscGy=uxNwG)syT(`xiPk zy8@WDW5`))Zgn>voZJ5sxd3YGn|_$hQvT_lBVta6QplaQq&xjS4&pF9P*Rj1C|^kUg{SruR7aM-QNS zy*scllK@bK0MZ=A{&qM5v~*&EZ1#Yj8Q&iL1!zR0NO{*GwdJSYk~SOXuJ=HI>PfiD z6j1d24|lrjsRxko_+9BY_eJYw(+dGwi2(K10hCHZdcGytz3r_5Xk&U6zb1F@`=9Bd z%_7-gFT17RmYU$&2LURRNI<-)@;8b3Xq@#mRfhbZ#)}x7Z3JTJL_~P1+H&P}1J;JnU6*%jP>&Q09 zy1f9~p-9%vwa*R6nkkxM$!R7d$cCnZ-7q9eDDZF7q#XfyM4fY4-f?gnj$|2A87He3 z1&C#@<3KtB$@+@rAFtr1%xv0N)y%ww()q&atZFaU$sak-%F3tMrwjv&_9Kz3*?}I) zy>oq3pc-ws!WjM5`(PGLvEsl>IRn91oDdr|%kr67$#vJTx`B(urw zmC>(~g|2B@xY|qZl3CCS;}@5ubGWKh*kX9o zJoF!fbbBcL986~);&^P3K$e_rx;!cd9LFO-H_$5=e)m@DDe4JoYaX|w;0N-pF>kwV9+f=tJ=je^ zfL_nSb&KlR>cQ&r{8w<{2k>(s22RoNvOGPW&6;x(R1OHxy_7v!pTvpuL&&d}fXl>E z03G3;m+qC_pGvp97XucP5TI5pBzrQ2jy}ev9FsKw4IpDLe}&%Q6b8_0dYOvAF5o=% zp8)Mz#>!NLzW~Q+dH{V3?x+K(Cgb53jdUm?ad(pGdI0r$!%9$o#rYxe2$1l_wI6NM zq{iW-Vm{g?p6agh`zSCUrtLix-eUy>SkwjE8AufuSZF}iI8me}*V}|d4md0_6R8sJ zqNVC@d$qDEsS;m++bpEYn94X+2d~hT+unn8Hc};AX{M;A?0Mf$b>@0a<&h(kvVYH5 zlzn-~$n2Kn^9N+N1^YQjRU1)VWt}$)Rg<3*tc-u-v#feUb4aUoJw9owtwx@7Jj!dPK}Nyjk>pq8p54}IVGm-GMGr=y0d zLUPLjH_O0kI8Q$->)!09_9rkI6L^fk85%Dz!l?b#wf}ldr(0}s0m(?zyfmV@7DSq@ z-O=)(=9LkRi34d;CV(UcHLs0mBD<3&bu36mqvnkf%}{E90@D_OWDIKF8qqAGZfM{( zB}m4i=A98ukSX13+XbATi<&|sn$~qmvmNJOk3-FSBbuhvoCI#inK0u~^TCMb-U=$` zcq+Iipjo@$oXpg|3I`SC>~ARCy#sabr10J^(EDuehqL+?Ykm?_vyNtFtEn&4yd4g8 zEsQ0VIaGtLS1NjBe83OCGTef=knWgNj_Gr%EUsi#wq44L*ZO0aI zuhqN}r2T=u<~n3I=EGM5cBhDZa93rjD+=!QU(75j-Hhy3YP>`? z)jlF4Rc@tY_etCJ^4G0v$?bwkd;1NTB_q4I-H_@lJJh--P6*wi$FA`BmmAZ$Aw_KC z;Z1qiB0kh@WZr@zDy^qrioPboUIzFH17mr#q zNAb1FT*aX$h7+X5r7?Y|MJ_m`=|Z6|bn|s^mXa5nrQ}L=EYtyW8gJ7HUm6O9sX}$A zjSU@G0uI}C!dHeuVXDwK&8;V66m|y+<7aXqg(ihMVNh_leyxKVa~225e-2H=0Ps#- ziSJ7Zy*P_jzVu~2cgfwMd(n{=RB0I3 z_43NddMXa`qqF1kz-3=4KVT1bQ8l~3X=>rXokUKX85~&bXO6V6cIFg~{tAJp<6%8NVCmQHDlHSpJ$_y^B<06+ z5U1<;0X{Uo*LF3wphwUT5Wcwf6M~lte?Ht&9{4FH#hI*(w!1LJ%TY8N9oGCYFdK_S zMHXBN#bDZ=#xa>=Xf}ib|JQ7E{K1N9?-UQ#*?JV+LG=p?b+vbQ1sfH%fEAFU3174m z1A1(yD+9vVRHf6x!&WY`@XNn8RaW0TnVHozE`=&m`(78p^)ynndL7k|dD)2yv#zTY z8*7RT46ulvI_y~;u$rLXVpiMCZWmUB19)fjEwj@QI`Ojwn8#_IqP)@UV8^mJMs^mf z<<~7Hm>~eYaCIm&!oJ&A{-=5Xe}aFmZuW|l_0hWKV71)3z=T_)?g0(dN7OI*GLXod zaR=1Unp8V5JLoyAmVzn^tL68)$Fm-Y4{7dpb~w14FI6qGxP=~p!mV|mfvd@P=y(OQ zgI>UDsgMYp=Y<#3E$$uw(M3(QbSXo}?&FMsORQQB*v*b~a`FY|%m1vF%?FUW3HI-< z=vB*C*9YpVC2m5GAB#n#4DbeVu3ojAMiI4610%pnhQUf4L*ZJ6Mb`JqIYt+ZvS%kS zS(WBQ+BtTjb0EW>@C+lJi6&O^Mx_8L~?ms?FN^m7#@ ziw;>z;UM1)Z2yES zBbIDdT;EzvNaXAIJdrNWeDy0U{@;@^IiF@ywm9e6h@q%1D)h%R>X?0=doHvC=(4 zCB45M`!QJg2$5^TrlD3`N`)NT0iwqmZqz<6k)k&9<3X*qv00|=km=h^ec!iEi(qt?JX(0mCVDNg``0Pm; zvo=)L0krwv7y0U8x$=Npq&>@l*?R=2iG*8B0qkBk)4}?K9zeq5ds7wd9pVo*A2lJB zKVP)~MJ2GpdiTRwW}h?wIaQeD*Z5;4|1K3SYp`f`f>h%lfa_-jsMSFNVx451!gjBv z!skM|0YH;hGJU_%IKAr&0+i)ko&mI5JqDhrSD35>5B?xr;~T=^$E2K%1Fv5ZAiKpT z+YGqBZ`Gx=qs;R8aI+b-te2gLj5vCVQZ}=L>agqNs zz?K!w3X8DnO&h)jv5?BFIdrsQbmsJQJbkuw@qSS3UzZUyNw#P#i15 z9n*!*M9o(t8fWS$N4RHzWEN_^8PQl#TqnXi?Einq-GYdLxJc`_o&|IGGfHQ{8Z(ph zeFlBcLAY1kY_026z7`!Eb=%lByaf?+acr&_&6-dhwI8in6Sh9)xSR=-<5?N~Eq!Sl z-fb@B4b0kLkt=SoLHzc2M880det}TnU$dr-6i0YcQ3{+Z4`|kmsf?So2R-P@DbchI zuW;q8CFaVms{>U}*Ns%IJaJ9YZ^Fs!12?;6-yw6=e+4d-#2?_$ZHr1usZ9&j_3`m4 zq0g)RqSf4~%oNOFh^HpP}w&4wuaMd;M4x1}$k)Bx-9zXLGD|$dVT-srdX6+)zv@U+qnl&6k6$UW} zjCBPoe~qu#xm}NjK2J24O~VmuJTXG>_1K9Shu9U74w&V{LSqO^%og}XR~_mYcoP=_mC*^`7z%|hcBq^Qqx^A^OKoI#DvM1R`MIyx_#$zYNy!t>B5K$ot`J!`|4eB_`Z2^>c8B&-`FadX3XPd0V)*nV#@1&V{wb zwo6cH6Vu!lYu-q-IgV7@m2&>#Ba2FBdYv_t6&792A1tb%^VgB}x5iM57A;8vk-f(G zQ&KEFT8T*w9hmcXpdVe^JsO-H|LOd-YD4Og7s0Wrp6RS!Zl2C`HehD&^aD~(!Wr69 zJ?F0vnXBm67zS`cE18X7T>H^l$xMDZ-;irI&VziK=wgf>I-~PfagD8kmFy?#ZOQqO zXvh?t8Q_9eQYi3$!vGB^5IH0%1l(NFN*YuBKdj_8_C9ElUKG- z4Zb@^bz_5f*1k-0#mVVEvwBc3ddSUSW@XrWq<(3DTPA{7t;GRkpVL;tcsTN1c`QTbw4p{>V*%nVLDX^B6h?2XpJ7m8^ox$@}Xf|4*qg9Xbc6deqg}yn7=T z`Te;+Q8sN|fyR>6IZe0R8w0NO(D}<=OF;O7zmgwpt@M9z-oWPVqNa3s#VO$Eh5*$O zNf|)zN;1_^>YgUI;W57)X7erK-2_(haLn&(S0A0fflIOXRB}-rp`K)N4Ic7&@S3-S z4C?t0_r`!l0|ZD=X;+Qk7R&ll89Rg6uDz>;GwgRYV(2}7#;zUV7zfUc z|A}5Ub$LfL!tSS+9(t8_FV>+~o3RuuqH^V!ao$@Gy;VEt_=Z@JHbL}+SEl{6#bxEf z-)a6dFXe2Uutp0t;ejW zk=_Tu%@@%#rZSG+okw(K=r54^A$pNm{*6da<@C^Is<*bwRV%w3R3vU&mt9o7Y?hSj z*T@057O5Gc=kQFXOs^tW1yxqbrrUYANnLs)ydy+yr622ZitoL$uvX}yCp`Wh z3fzxshO?rTh+ZvpQ2yvrht?*OJ*wSWunW+j_w>dXKkG!PfBTuQ7*J{4M>lrMQPFR} zH4xGB5)(>Gg0CsgZM>}be8JrSy%tqSKfDT9&Ee@6XWf$qx9P;mblg@z-w!$aiB4ph zf%#mm-y2A-Sj-p7vWXXlKj%?_4j=YwbsYUDrdQX}YsT3p{)7={!TOjkD##U#{ zuPoWDUaOwW4>5U&BTC~i)nQ>bcEd5FW`kW2GLIQ2xVa^}aKqDCd=JbOaT@Mo+CfFDmMC)(x@cOgj5|2e`B>MQ%E`zjQXY2IENnNdgwFkX!{zhd7fW zCS!g)0a1vC+>6&p378b3H6wRAdAVcdZNWM8pX8>}^<%qWquEA}T-nFfrN~uzuse;7 zhy-z4J#rsd(ebw!2xy1o3SV6NS&q~Sf4MlbxhD60%!#t3E%^nu?UCHmvDFR8oi2*A z8ArWnnHn3|A$g9IatDwTw^NZG`#> z>d*D%s#~?KvTun`C@wdtm=#aamDqHg-qi`o9b4I3dA^yi>d5_dDj}Sx{i5dUsLbcs zwdkxzZsM6$!t^di?rdt6V*lI*X%{4SMe;V;+*|82N{U=`38d=m)NaHG#@fmkC0$h6_xiRAjh~ja!%EC37ild>1g9UX6pg3&C9D5=_=Yr}o zfUE(>JRsI2h?~hDf;iq6-o&u`$7P}y)C&QcyTXJ6^(OR9SDV!3rt+`RM-{{4Vy2qt z7yvfC5g1fbe5cSgllufS8#I})O8o>ZMSDsXfnD(guKLN6HA@x?=1$2NOKo`PObO52vU!ob$uN`bfa^><86#cxLlB^<8~l|4Y2K>H>?JDw3C4xV zq-%sB$Dw)v2|Ha16O4sdxce+=T6=clOTgW`fRWu%8mz{@FZNv~GLtWed826%uhOqO#YzIMF^JXqR)ooqdS4V#QNI+6 zZgn(h5Es2=_nLMLH(Z~u-ylkl(uw2uK(YX1O+^^$&{h-ezctcHb7B}s7NX|65zU!I z(wsEIbWy1JVMJ5zrbaUlBnhbbX+*>QB29)RNEV~!ml2K46^&*VNS2`Hw-L=JGWXLm zc#tHb=8qAL>s~4+b23PlqNdo0CYYk}(=va8WEpBojA)t-q;j%wrpELo(0U>}yy&1U_E5&4u@kMr z1Rj_S%8m*Xyk7;$hY3Y+@w1#FjF4+@OTg ze*T;rBwrs77UR&^DOrv;k2iF5YY>RWYmD6iCpxyv8cZiJV<#cUY5M6*aE|+@v710% z`t&aqz;U9Uv2##u))_l@Rx3MFFJt;|5r`-08N23W<>Mv(Af1fHPWa;5Pd<7I!rxuo zI@yUU8uw)@d)oL_;b1!jjh)!Bp@FfREi8i0Hzm=I&tNwdjh#@S*4X_WUl~4@P(N-)qb?YJ)-!gUj&D-p76A(36_(J5-i!%2 zFgg>BUEkAbvgNb3WQZ>PHFn}712Ok&eZ}Fr?Ay(l-UZBNp|Qi{$@cr`&>|^V&($12khjcCqK6v73O#?&%wCAW~9+T{)9$3swr|N|)t=LwnTnKKPMNSYrxwJb|vX z=0si+J27k99aBnmRhOuEwGv)b9YC^JN9iX&nL%3otG=H)5Zx(BvnJi?!;}sd0yvv@wg7X9)=- za7xv_Sa|s4y;IH zsB_EbgT)er){l+pbl%1uWNsB46iw7XyNOVmtE>s8OBu8)*OIDd2skhMC$!bcH=R3r z2RJU*gSL8&Ejnl$GYThNqjD$W?gK0IpuJ5E@7#N{LAny56~4Ik^9+F%{+{r`Ts3a_ zgnMLS=Dte>+f@i{=oc>oXs3!!T5|PTvK!4a?E-eI5n7=@eQ1S6AGjfI2U3ll4{mD^ zT4O5X&~EQSS1$a_rU5z&SBi#)D6h4_BRsGFu!V&k6Y=KS9puywA9=M-oEoC*e+!qdcF(OgkI(pcNkf9tBS3 z_v`{Tn-JRn5ZWWUCCm2}?BV8*z_`?A4T2An*7;t@&X$cma8Kil{GrIxLWwK5CL@9! zzY!4SUZpB_wFy`3Npdkj@EUaq7S@>p4qK2knCb0bX!6UDG$E4zVhp?eLPZ`pY(-&~ z`LfJHli!9yA(B68FbU^00EZM7(-u;C{m}}&bnHgbt5}%y85~k|!eT?AaO?e4l@_Lp z^k@E+7z%}3SD?_{!aq1Hu?%Tq&4vU*_E352 zad)AeXf_1ZO>FDet-F(zE8Z1CXOCj0gI%S}#xCxNhrz^uZlEcRi!I8U4Hmo6Y&2(c zDcV$~LeAk@%RL&ikzA7P{WYWG6=*6^vuSrI4WT&&aOX*W<&Vm+K;wl^NSDRe)C=8)|1&tNX3LFhtO;^ zJL_j)HU;#&P<`T|?yzIrlH-ptmte(P$#n38FVcI34<6wPK&z`XF)t$~sFh-q$ z_T(c5`!4A0$#iPcm(;<&O{T`4*uCEG+q}nr{xB?9Pr{5@T5E`PoHA*Cu66s zGvN-Y6;Q06!;ioU`308n<$?Dm6`FjT(@5?#RJ}uTdnevRay?(t*$?*Ma;6lyr?^WV zzVu6I{yVTNIcbSSu3&MNg(TKvNTRJD6;e_GL^&FAJww^CrOji&^c*Aimm?kN@fn=Y z|C3yt$RmunEFF#M9xmvSTU_R^mrf1-)pSzgWNh(8J#sJqN5?Os(|ZZY6~4IkqxI4` zt{GRAJ38SP#VVIRMshDBxuaGo4al7=al@6!Rq?B;P43o zBz$r0M}l+og})zs0M~$gRXr?^iUsF}da-yo$(@DCzd-4G3T4Ag6O0VulMQy|Mkxv!E z(|4UgnkC50YplD`F`Hz3xosIwTy1rAxBqpe+_L>Od3=4+t||hvH&}NYOSmx&>Cl!Z zVEtCF?h22;dmEiQh)FfxVciYIDX^n;;k5cx>(}~7z^+hJcjxce?OX2FbN?n)iZpe% z7uEl@oy6e!9_w!6V5*CbgT%`JK%(rr)^JB~H^O>jcrjS5)^7#R(f8cg^B73hV9*DQ z1bu!<*aL6uH5epoQDZE)_U5NXQw)-Is4*5?<8w&UdpC9xP-85(c77RY`qT%>2GsCI zo+r5?(`@R4$@BxTWi`dVcDu0tb(*%wq7xDGz&uIYvc_(rgVCRvdW240o%$om)n9?X`Ra- zxJVrMr{iu>zbE-Q4mM_(97Mj>HwR9=PX>=|5iO^qk}b6a{HO8qgzhM^R3rp4_-YqyX`c( z%U;C11TjDGz*FhDxQ1#nEHQRH#*b{S7~BJHPu?NiTL<;=r>Q< zi+xh8U7MOB<}tcqr)Bl%%F{SM%~XSVqn}rNt@7&ncR2i6gL&dkQay+US2M&s$*&D- za;|UWl=B=o<(4lo22E7XSkk}7lyM?`=kGK{3sbAFWtrKkPAS`w6*O7>Ry|LB9-KHa zCb|mbyjRy=j9a^kOOdsgd*;zx`<~dp1M86ONX2Au7FI}BEw+)+y3K(ZQ@>u5k$f{>~T zN3MhhF70***i}Tbeqw=t$>M>@g*jaD9RO?n*Qe0jrZmoJ5vkOX;93>Qx@|*1G)^g2^b5MA*mA_nfUGr}nSQ6_ zHaJSr`CI(B8w02ZT!!lKgLmV8a1Wp_UmG?MKs%RX_|6H#rLmh$xR!7YBv8z|bH$t$ ze~ka5u5yRU+lW0(X9P%4RY8EBPO`|pAQtD*+2i@(;!+BrZCr|n?w25d+PITECk!lH zbpX|+fw^6l0U)ZT0Vs{g++~vrrqvlhxG+tqf4gcUKsEjeP?gT4mgAzzntA{&sJK(t zG&N*IJffkxU9C9~*U|$><0$M}^n|5Ot0sJL?WZm}e!?Hmx8o{u?&B*{lx5duT!d8z z0s8o)n*l&8g$?7Y_o7ES^oz}Ut05Hl7a(o#sRB9gyS=60Ru2I(rZNst!xgOj-ECY! z>V^P~!}6O{cUSJ8;HKIU6|c(s+Bow;PD8oh*(r*$)Qs&$FWkO90u(sUNBQeU9aS06 zxhi3{gZ7K6u27k$D}bbd9zYl>RZf;PR0ywdyOcEfIP&d|039}8D_c8kXGWvfe{;PJ z;o{|0dsryWJ|gWC>^(IkfWoZk(9hmr?V$&d@c1gS-g_)XVB?7ZUB;%#Lf15P*v_up z_!r4)s)r(C^ zF#XPRoD=B;wM?kw4?Dol8?C|DWD~9$4zRRS?=pFh`@z`ZUa0TY1!I|Nuj~NWG(l@1 zsIH?mm{a&Y>w>t;Z#vue0k}2Q+hhI0Kj%b#A``H8QWtRXDP>1aaO%?OeYg{Jqs0ke z;fr>}k2SJ9U=!Kd1>}xt@^;i)Ra`xPc3Cou-?E%ZSV5>wUv-WUr10%Cb)X9>|OC?dk%U3T}aDWQ?hd8=0JXRQ@5%bkH1)jBw?O2M)?Q5@(edJ)uRaJJgCmXcV?E^{o5VMp7=@}WJn~SY93(!X$ke#IN@lfkS4J6e$w}=Cdr)SJe8{(oimCKc56;B2bS=@y;FwHY3SGWz3Rt(& zGcv;Co86#uN$kl$p~z+I5#sFb`}Kz0U3q3QM0g80Y_w6i8utqSrznUB_5XIYKkxvCdLWR$QwK( z6PBSC>2Na+96O@*DV{TcS)WPjGiX=p@Dun3oFzX3^L|vBNkyh&AgU8upO~#C+%QZ{ z@2_r*>zV3tjrkm0Xr7rys_nU8(;2Ogpn8f!w`J~Gp)c~Xn9gSAf=icDHYAz5=;5cW zC+y#W&hJT{gP9Gwq76~7Zn9N5I(j7^MBOwtL}TC&|G+)ozr>P^Z<2SD6Y&rCdP&yF8ybrIb9BCqU=m&y@uoYyFN zWk&`a2Wda#Rk*Thl2mEYy1J_W`thoqO8v5*W?5%{9qui!EvCDS_Xhh2Kv-nfz!VPLmvjyjDb~ zV4RNEb`&E#+SQv)n>#K1*gv|S^nF^rt-s5z2O3^C_)r-!ZNYUg^15vS)yz~A8)ekk zw+i?DhJzKgIHo_*YAHBIV@+<+J(|_zmQajKMjvqXFz?|7h{A=X`E5wqGau}RU`_sz zV!|mv4Oi5rCU$&ToP=-&*KZF9Al1+auo;RqSx_Cvnj95njWs!>COez)K?PQ+`Yy{v zYR)qgadyJ6QdN9Ecc}D~qM<}|=K3747>-pulx4x|;KEAJ+&UjbBQ#a~Ej@MSt}b9Y zl2!2+3rKZF1kR)WS;a%bnL0}%0>>D=D*n6dE?pI;NYHg_Qrcbs^E7RPx{+#WmJ9BN zJ6f;aKg=hwPdwY(w3_gmv>&Yx{)?~0{o=2Wv&$uI=pL{gi_N1)c(g(DI7+nCk{h8U z(P&)o7>k`)p+N0s3x6k7T2lNkYgHV$jYHgwsf^>6OQDyn9l1E)op}c3xt1Lx-Mx>H z&CJ39Zs7!a2AUJM8?YzJo`((Ucm!0qSBIKSl*>eN)z+yqRj;=7SGbPpo&BzwlmA-k zF=lVTv|ket(A#ZWD08161(Z5zs8*m)J0vG~YRp zPDDVXbC<~~hwRCiRqv&)K|SC&M&AF%SNR5t9%Yv#f!QPk6az|*W!U8^aV%I*)&o>{ zeA{ny&K_sjOhG`Sa8PoLE^eGkRbRENH=F9k0DW_2lW*|Ldj8I-CpCahjG!|1`~uf$ z2&l3r0eAZAL&f7MHxx4h8yYmI=cuQkI*uEkOxJHvHvlW>wAXxaj7M@;*Bi;mT~X3f zy-IzMtBC=nEzpY(fnO9cIo%Q`K+QmMho+fu3rgCnH>%MXacVvvj`LL@xet|>x&v%x zBDup*)eAk~7`Z8uYpW^a6bCM|N&(76y(~Q#qTWM=U2gyuvk}n74A2|oket4SfX>kX zy6-6|?o7%QppAX-mPTa}Gh(wGFga$+t>mtd6>t}HZDD6M6o zs^i_}s%n32qTt3#f zV9lZ}b;g~hLZ+?+QIe)+l_LXmZVsCMjjU!B(Ca#fIhLI_{nPXZ-=Z>~<8b|EJ<~7p z*`zc59?Wbvct^^Qxgbu~v+|v*v*YJ6{i1XWhAM?GuKirYNom5L2!{Y1xJBcy$eH%S z#2B#MidOzZ$yfs`-&RO~dhH;ImL6c)$!Z7%{vD^*hAI`*=v=I}6x>n~AY&@y0F5tX zzH{<%| zTRMQ0@lof|;;kYfS`(U(c*Qhku^#}n5nZ#) zg|1ePXR-r&fE45nxKs_{*arnbeU_3`^LXZT=zjwA-Bd_lZake?Zqrf27Y?f3pT&)| z>R!z8un}3^PH)L4iy}b&szQGr0_3cy@zD-(35EZsKccBehz`VlS;n3nh)so zPeH0}4<4(0Nn>8S0}JO2XgPL^TK`v*&FauPL)G>33On|#=ZLhgJ^#Th&l+1et1Hrt zZ!MYQIbd{Z%VdGkM{OsD&}Us~xDt=C4cLlXAGV(!CNcZ-z$o)ySijo8*j9vl$Rs;# zdXuO737bfymp&ZR{uh7|m#Pgtq$+8idQSd@v}F1mE9QK$2u6w0G3?@R{MRp-Tmb3I zv2nm9Vd3yoC8jo`EY@T7@?||n4jFVUJ)N1R35-tmpexyt%<0Pi#OOT%dm|dlzpon6 zV#^A`J!lB>@=uZOjcIvIe$9xMS)?6rU%ft@0;bLIe255#-#V4)bKxQn(~Z~HvIpRIQ%J=j;!HpBb>sk*VyS>0zD$tJ}xvwLKH{W?vT&Sf*J`$o!x z7r#9@Uhm$?VAc9ph%jgl$`D9;8N=DFVA5$WG+ zW5ZlBfWznuHQH#Bov6R_AMyv0$(?lwxt;FhRx9D7@P~A6HRr;#6>PYEjW6<&ht)5H8pw)+m zOKA1O`-r>u%@UdO(;}_@IO2PY_?8+TA@MRe4*nThy|)N*>e+>^c09pk&-Ja|p5VRT z4GR}vh*p2tm83>TF{ezUR_|3g`)$bUtl(|lmeN%doz4m0)I=6UmAgL|zNME&t^SZ( zL42==XvXbIP`XPKnEaJdtIsB%)BQUb4ZKFH=M^{n8A32#VE1e*>By+S&XmSmY$}w6 z&b{=Q*g~CqoXn<#6xEf4v=~RdLFdjBEQ$tf1VxJmbRpt&$svq%F-EFO@P0x5{suae$HSn zUqIH=Xd>l$x7%vdXS>vca_kD3WgnAC{`XF1{;xsbdrS})Gt9G@Wv;RIaUi2FLvd8Z z09BgNe2(BSlC{@;%zLKwG21OYV3Jgcr8cA_u$;sG8#sKt%R~xe9d+4xSdeFSP;$`q zl%8n!(-ca^>IiX!;~!k=uT($zY2*0iDd_FF}Rri_#> z%;G0F>?GpspVIIk<1B&=f9W}Fxrz#xgJ8qog2N@`JbP3EYwGfhILrWtcQUhr!y6HY za=~Gh`r`RVPC1Mp#hCv>OJ6Rq)oKc`M$zYZoC6^*urQ zna$Ry%evcX#?6h@Otvkh@p0(v-!8JQdU|gv%e@5VAOoOL_m8WWrkBx7-7-hx6uUDY z(7)aZxu@8p*U<`k;F-fB(f%H4J#^3WX6bTFYN3xGEdA8ZC9l}id)dssG}>Rt9uw&@ z<`*94ZPMK{@sn2RlBHyA*cg%CvqpK$+8TO*OBn_ch<6~v^%=Tw=Q2gwpA`PA=?yHs*z(T??ax;XB7!Ln{8=9tCM&CNfAW_kiQqrea-#j!t4>#Tu4GQ-joM!+x9qo@ zUt|TJ^P=|mNV-1SL}s5z(x=^-qpeZ<3(PGD7^*Lt2OCF{m!JpijN0Ey2XXy*=L8W4 z;_{+u!od52iEq&9u#_aD;vIFGIt^!)qC&xvFT2pEB4i-|+6C^Zgh&YANjVJiu z))d{Eq(0^{&x&YG#Yq+4nxd(@e^DZWDIC$7dLsQ7zIsR)(_aLUe zc)YRdISpW6IAI5fN@z{*&bLs{oO&tspxwwqM*gi*qBJi$Vic}GcfTdFbO8VDX|a)S zI-9~@;gP;1Gq9%EUutu;7W4c*)ZLSmvfxF&k>Bl)T`G&}tJH0GlkCV4X6A(M9#fHR z=}Wzs5X!8ajkfU-gPeEK`mK?5gkXFMbI1X|B!o z+xWe_Kw_)3m`3@T?h}|xWpwv96a<7WV59ol%UbHiHZJ+S6aT(hrA4Z*%PX0q8vyz< zd$|B;Hyfe*@jFmgkDZq$=*D9=%s**p_qys)aadv0gS{qjokr<$es|U>S-NyccL@Ml zWKw!F0-1Fc0K}ziF$%xC*&c?}zJYWXZVBhAMF1N5UpLk`!s7LII7q7jpg;l8NW$v% zUM#op&;zvi2_<|uk(pK(0R5UpSAJsn;0b^_w5N)_M+aU40B!NKl+MDCij+1)nVJ7p zS4d~soMDbNi~yS1GhSoBprIfl`!z`_wlH~3BY<$g3*yGDO@R z!RF&u(&?Cb)E={rW;46m0O-m4<%Iw$XYOMmy%|IqrNM1k2i-A$lm7*11F7pbY8(#f z1%Qf^DjuNCCq?>ig7cW7E&viwrruDUJ$FB~yLUfL(Ds1TdGhzEAye9@>(3_HA(70X z9soMm%SCPOn4Y?@+F%Wz_cK(~gF4wa8@!lpeE`I5DYB<{#NAgFe}%seQCf#{n4$sf zrLNjJezOkmNqQImIv=2eSvjh*?`NxPQYZ2z75k1g1VGrGu~H;Ge(EN(+@ZIGguf)3 zrvBbsa$r`CKvrlAlMFjYbBWh$*(34LTR()ic$=8S8Ol3yQ`x{Z?aH1B!#DPkHZ>-x z77duS5BO^h{x1J8@b_sb-R%W)%U91|^D|p~q=ngjn`s+i08jm)S{&xsaeKK=Cw1{BN0Y!QSA4ItqaV+$s;mn85h{bJ!o}sQ7VwsSc z`l0(=CTpti8Gd+Dk$PbvRx{Bvc$}dtub(ofK=cgpBj}a90NeOB>3N+!G0`Bsjw|t zEA$M-NfqBSj3ckjr!GI3qBVL3{^Zun*OQOjv)3Fu8LH_%_L*w0$3@l6F*{OrEvH-- zJY^1T&@+^_{-B%`R9-VGV<4h@68sGnZA8Z3r_IqLoxA{Foy}RdB(<=>C_onHW&u+JvS$p&h*c)c^Tk-hkI#|ro z0Uf}F{v|{Qz>B}`JKbw$%j`R%127cpB|3mXq63ICiIjBHNvhLIX59%LKvl#7-TQ6m z0KSsm`5cbL1)cRBK=#t7J|63%{90ZAL*D^ZUPEc@tI1rtpaTdvPpxanx-9jen>E#6 zUREunfaiW8`3p~(<6i*u@Q;lG&`NBYu5TXGb(h?9jdY8oGOQDs4xb-pG5fy(=$`%9 zMwZ3udgqmt+Df%`V|AI*b?xOvBE2v6!D1V!Ke*Hp0Qzj40)U>qPIv2KF-dR{%(h8a zibm`{CG+}=3VWD!17_sOaC<|E1ZFZ>cRgm?cF?t!XP9XZfm!LjbmchC0Sf_U7p83x z6}yk7pN*zJs3Kt&B{1tsJ@l9B@MQEf!mMPyqxlNBu28^_j#IjiS~7VrBh3D$AcWjH z6GW_wYiU&6kk@jIhxqTV?lR&9#zt$&>zms&kJ*I+vy@*O3t^Tet7ai}r_L<5djzxZ z0|m_AWC3P|h~0K%IOnEKV4i(}S#eUuWA-oE9Jw!`fcpWny+}WV{i`zRotK)FH$v0> zLA|6atBkLa6fdQ?<8_g5x!2m@xf&8*ZbCVWcm+-V$ED(~?(RJ777A@^04%WV4t zGwvqjKUK*i{#znb#F{Z*nppVS4f9Chz|7>+Y`^5-eM#vzKICKOK4zEdc(-|KMs4nE z&x6ct068p1la~BC#D!T!0JHQ}Rsu6#{Bz|f`^}i$9|+70#k#(^Y~cAeT+edMewHMu z{n)!?5HQo0LSXz)17^Re0e?N$MVw!FlAB+*cbD{SxM5)9qo)jd_CXG%@f><~2r#o^ zgw35DU(}tNjZ&}JUZN0YqYn%DZ?~|I$WUN*uJ(4(8aHFJ&+d8OSaZosYKXl=%CR5h zn)>#-C9@v}%*+m&NUPW@UB^5#otIP(j>R|9O|5>1mG6JLFzeyagIvmh*#&vSERoyy zFq~%+Sp>6<(&D1CO;Zy{d~go47y-=ciGWs*j&yZYI+KmmWA;~Nx;7qL1&$J!^`%$- zJr(=wMgg-Qe{U5PyT~;R92JhXgxO+&nRhLE9!DxWjyA%qQjK%@n31ExnfkHskJ>Q# z7$eNqlS%d?d?iyvLz~SxfF(8hyky9k|DFIdS84HRSYOsggxN<~ z6${CW9K=5moM}H6n91-a3otXd9o~|o>8F_$^Bf1vijyiHvodW(A%0q%XO_EkWXubL z(eWwWaKv=Yc<{%Q9C%@-%FZn}bydc6&9%jGsf+i`SN%1vrRpH@_p>ghi6(%*Sq?u{ zgPdNaHmMgU_%pnL`qa#RhQbv;5&V7iNcQKyqfTeJs#EiKJCX)cKgU01ib>!vv)61t z<*)ro3w*xj^SAWGd{t-n`Rc#5RL1Emnb~CUhd_u|)C7JmzzA{*_>-S2EBNEZ|3HI~ zpKB0-9HciIyLSt#-FWa1N@v?qaYNXL;zr5Y;>Pa@9wO`|&QOtlTgnD@Ys-o4V3Hv9 zKSENI4>0rH2AlIBIWvFH!CvUofbj-kyfPo-<4N?$2CQ$HuGf}6`xL&>9mgrB^>x>4 zOS!j@%CmgRTxI~{DfI|Tn;4aP*K`kcooP}bjHi;C$g{aw9m zUFDSCmKbIo2fn$K!4Y{ue%^xaCfhRSSw;9BD5VwMC#XRW56j)1vUobNK0lBcN-76QhxvbV=X zn%cvNxt(vs_X(>jMfk4kOp@@N$rl*$eQ%Sv&K$g$Vj=jJqvA=(Yc%o-K+gP^qq~c6 zjMk%FXpF*YVCC2%@cn1_u0ni&ku|W8S`4EE{e77IV(`u1glXnxv#zs#3$#%n^sGfKKlG;BqRNJ}*@X-# z+>1FZ1I8icUDYKPJx|>;W|nX(8Y;R#e1;5Z>X$ogy%vBD7eB zv`E1eD}eFqMzj6Y9S$b_IjkTiebu5>s+3Dh)N-NfGo%+anb}HUj1aozV(KSD`h1I7 ztpdg^11pfVisHvb@G51PSVV~f3*!vMx(6uj+H)u!OrA;|#26^U#9m_7YrtO&_UwO(x^Uz*{{{}=PR@Iy`6qu`JyEmdRwKdr%0;9LFTd!{C$cbY@Yw#tG2t{Pd#R2 z;o<5RF*L|93G2cf*8{WQb^AnXT*RvArsqkf)+TGER@i+*ryYHPQvL*sdjl}rd)P#Z zh185Z4^t*Bk^a$Xq%+!)Vl0+nD#70$56rmK_zWIT=aqUo%xt7b&{t*0$nS_W%uEk5yMOthaQ(hQn90riTS&8e zl8`;D)g8c$zsUm33~DqdRXgfhi0Xv;*T-#aNteKPTW zYS|J~H6K09{13#=R(o%DQNP_LWMx+F%wab$yEJT!`ud^EsZP6NH6`z!_BT|t_8gLP z-o@w1wlt5~?}xQ&C{`z67T(l= zS(?5w@mrYn0bn*0ULmu5uPkN&IjXXw3TA&$k6BxHnQvayM?dSX2CuAtBa*tgmbn}P zW@9!|>#7)kK^+wMSiRt6;T^TBdI@=pt!Q6|fmzGjhXrQCSdi{OUVFAyyGT-FkB(p3 zqhjVN!y*}<{Rl8KKgtIYYTfRm*Ya4am+@EL19LTz#mMOq{r+|J(6sb#!Qn1 zX7gIn6@;)mr2w<|UI#_RKBMV(Mbl5zYqQT%WVD&A*G`h&wvsuf8ez6JFD+l2QBcRl zUnIFFfXOvRm?a3~FGKDJ-^&STvoM_6WXQ{)%_QlSu7vb@^nB_uK`I;c{}iT68y#9Ib4XpYqDqysd^O>>YL8&Pk}%FiVOHNj236bk<`s}=6M?Y6(?0Z zf4zmi&XB)@x;X>>ERg<`LtWKn)|A%F&7G=weD_gm-W`R;teTzrYo5r((iBmLXThKK zlUeF-u``PV6FaIN*6=ine}C0>{MEkI(#z>Iu}y!S!y_(yJ>oiyL7zov+r_3W9|Ld!Uo+c zZ4|axMydND%;gF&o^_wFys>GS+HU7`_3x)@M9T?XIv>-(i%l9x3Vxmhjz!JKat;d_(xxah|9x~(L>av`(0 zDb(l+@IA2sU5)R;WViHuZxOEi46El^%=EV4yRLBhWRxDYkU8A}-#Jr`i;CR=-*MpE z+KSZZYN;pq&Mhs{EIreMIo>tmyVJ~~YP9Wjl3YBO$?qBQ?MSbubQUHP?t|}dXja^h z8*HRTwYq1zGLp#{)htQ_;dyosfboIS$%QaJEkk64X}A!wE^|5KCP%fN^0dQntlo{D3S6Yn+3scm$03lkE;pQ#UzWPBS8Os;2wBH1)R7vZ=ur zzNrq65@oR|b&xqc2FAO>*W--nlA2vnGZB5C?r*5*{beNQ9KdX!0AoJbUz_7{j-kyqzAu zZo{me1LK5SRRzYp_#dt59zrASUjRx&v1$X#3_lKK0tS)J!cUP=&Upf}&IEtS;BUiM z1AkM=(ksWe6MCuVZ_t-xJ~PwDD>tk&Y$ufXUgT7+QyO!51^(vP5H`E|uTfY0Ra$+o zo>igIqR%UmUmC|8Ujwt@O;3u}ctg9B?aLddbC6!>zA`tdEW1eERJom*%sva4B_7A9 zM|*^=&6|O?^G;V^H&MEyZS|AVJAyjA0cKokIIPuEU%gV(2h8e;6^N^IDUq&Nftanw>@*qa<$Et>rtbx2E9i5SKkUMsKJY=| z<`be~*U|KsaWz_!FzX{QGmoM)uMA<1AB`{z?^mEkX$4|)vQx_6&Svr)Bg}3He`$to zjSful37Ey9;*XKnIONp`IrEGJm1=?~S68x{Woa;nVPY?o}3(Sg>Dju^6WUbnMg^%ScFyl{ln=@10+oH0j4vW$B zu3a*9^QCjj{Zn(21OE}Z*bl|gbKij3RL_6a=}#Rs_5Pf$;TRbz+K}40{ZveDeiwtn zaTpYi^LL894BX69`75k>m(u!hhADnPTTY3L^Gi!Rl+79>Rmuqx)00x#?J!XqC*ZTx-eC=1VgbBvBJY?)5jaDm6%VjPMm^BF^ zY(}3e?H`DJ=^CUoDTLWw;grd!um^@yqOsvrfvB$V`v-H>fxmJw=R`C0VNaO9cDBw= zdZx=_CXzi24ek1I6}WGl*qqICX?xjok0Wmin|re)LanzLb!l39I;}~ z$pXYi96T*v#cfbD0~GDiE5^}+*y~hc$4W8Gv4jz^4US*RH+*ZLxk*xuEh2Zvs%My7 zZbYo_1iC&ED{w7AY{w)V{)@b3A+MUqng4!ZS+$i^bM)~MB)f0|vnvT=dyG9-h}aFX zdlu5^$|SV75;NatFseGAr;D30f+_`!`3Eu9mXE|9&?SXaDx*@(r_9p|7#Am1JjNG< z6EUMwU>sAF=0-2lPjo+{wp-<SfXTMUb zt~hEQj+v+7E?7hD6R1)CG3W=gEdz}C{?Pmvsk)TER?RwEr1i%%%q7_XW1D($eoj*k zCGD?gl|Sg5H+PEa?9B+Z)m4(6ZOhEc0%Lz$sedcFvPAT!+C?Wxs)8-EcI1{Oq(XsU?7O8gW^Y%VdA(fvQF}smt0BX6ht>N?1u*9l`$T z&H(D@or|JknP}vF(8$wElL|a7#lm6J9?U)0qI zsE}tO1y{>>rl<^{Uf^3A;N^$x@ZVPeC6lg=$|9$a>uhWY-sFGT*-u@R>&b)6vkKTLPO5lzZpVxCE1RJWR|Px#$whX%)hWjnn%ocb zG;2&7q*y<$p}zG-uK7d*?aKCP%%K|CdFGv_p4-7zbJlFBCOrI{zoDYNE>W7En8o)H zD)1Ln;4e&VT)@&|HxUm#k%qXHqcA~K9qcUFG}CXf>!GA1>``p!OYLq(tL|PLpl-3A z(whLks3+KQwv}#B*H?K?F0-luc03L=672Be&-p~+8{pHd2^DB4)=H?r{z3)%NGD9@ zkjux-VJWk&1r?ZzS^Q&P43_4#k0K4XT5#CZ*7H~UT82;jxN?3W-#_U2vt3P6Ed!ZL z9q_keKVdV$_ojO5x^e216BP^bSD9L}+x%V3(F>RbzDyUbu?ZWhtEbIj{iO@Kv#bhq z+RiLWc_X^ay1;B-Dpn5)sXW$7x}htfi<91K%af()wr>ivt_RGxR99g3Y+Sw6tMW~R zs=E_bgVryCS-iBR=zwk@4MW|l?qU`VfLV1BEaTZ!6vVwA^j1SXX18k5wMK22X(NHz z`6_g!<5A}14b0>}uZfEB2r5rtmY~NhS*kP2OtytSp8Ei60c;+AGHQpID|E{LA|tQ33rIPJ%i%^t<7 z6aT59>1DZ0^P}&a)OLQ?R3#k4Q?dx=s^2y<%l*cN(rGdqtC@p8fAH6I`*wAe$(1!N zZ>Rm0ZDR%94?OwJL(Q&A;Om`En9pRTD^qjSbVW|efY(lhN>8ZLWWgPLmv z{h#N3z^*3f%PzLR9F^jffy|-BNP@4?r z>X~6o)=tm*-9aSz8oSUQFc@@yY@mzTh?Z+FI)MG7#T8GpGt8+2I)LCx^kz*Ei2ep) zJg-WTo_!|OMh7szCrP{36np;Uf1}s~XYxA$SJ44XZA6mQWK7=4r~{bYkFH1DV~Wn` z0Qj5Nq5~+24&WC;c=+#&?hO{LI*z#6hGZvnVRl{60ZeteQ>X(tD%)Wp`P?KSM5x*S zg${rxSTNKyOpHvWp{D0gIA;Gw2T+_;@g0CvN2FiF<|tEig`Slo{Y?RD)gQmwY1Rx~ zrjBPtBU)}DT~f?tRw3X#qI?s(^f^ehGsCYPsB3X^=8 zbuZ}Ive2`C=Nj~^Gudag7X4uMz4e?chg|Y$7}HNVB&d`>Z{S;{3ZE&B-2u!c6r7t? zrqLt=It(2^Pe{chj4t-wAF1hb+a=;|oqh4lxqlIi&qxc3ZpV;AufNXGL}n2VC@ETX zDA_4>&Kza30eUF!@1=w<)MTa+g1_q5#T7571m-jl{DnToU<`ky!CxBqGbrGxg1>3Q zNxESka~x!(fGd?ap3h%Z@!I0$B-vyNlMgoH&z}aAUMnJ)VhH$4Mtd;iwFB(&U$*YM zE<;yi)FbLbymlateJJ?*_*)}WTS%_ttMW>P&wd#A<8QJ+0UP*RIztqvZi}VN zb2#`bPO5nR%?^Z0*H1jT#dRARl-TQ2!+KG&>dgm}k z90C4H?)6f8<@}-P?zj@`{`UGCD!MRMq*?Ed4YM5y{*F3rg^On^ys5|dQJ|^(75Y~c zG7Tc9FvTeFxBo$`UtZHgN#11~^7ZVn6I)c;8}rn`AtW1viIFJq2ajqCGS3^#Jjkp@ zgTJ_DL4rSC{HgXNjxZkkG2qWoEDP`#+?wlI&Y#ZV{x_PUES8p?8*%UJN|(v`4z+r(e}N%B`ecJ(jB-(YW& zZ|%h#$3f4&`sb-=jdFHTmzDR2w9zbF3eX*pDl#83LmKwQXCKe)+*3G?OM3=Vep0O2 z7-@>Gl*v79T1`rCm|ScY^aqzJ!0Z>Xle>_*M8#nwR`$4Nicx92_y5642RDT2SAWD+-;Gl4lx1%DUv z9*Y`t1NbBO8)r@W&r`C-;^;Ez99vPCJ?3H#lt-@cC1Og!^Z z+3wa*{}!6-DmhJJdLNBqmaX*mOmO$GTFNK$DUs6`#0_E3h#RSS;)btHI&+u>Vuw~d zuDaHLd+N}@se)L;t7%S})z=M&CCmn~pj5?wd<{H4u7V^>xp`>fzM%8lTWH^Fs#f=o-0&8lQ7#W^)PSQ1bpXzK*RW=K20`a#^D)k(@v@&g!gv+{ zOl&bQo_qYIXw+UXfiM34tP7Mv;hNPTzM!NzNhYQ-`z65G;*5z@MOR-+`z?pDKSZ*T zOiVOd`xKH&J|Q+>`h!auHjTI;Uqj4g;xTH$ZD`Sdf+BX048Bxypi8 zi{6xGvn|YVwGpj%t}o7~l_o}f50YfNbS7V8L~HT~x*m>shP9ye^J$uYR3NV?EScoL z<2WAcneOVCuKId?v1NAaK&xHy%R;n{GcRQ!O}Hi!R9m3iT+gjlyvc%SSVI^=N_ zev5f-;MQs}QpM96+JK%M;=mN~pp`$V&NWkwj%x88u{VRh!JoGj0&Vq1{x z+Wx80l4; zWFD<$ip^lJzxxco#+ZLR+p2)Q746K_w`^k7Ei@$i5+2npzznP850iPW&fUeVwgR&Y zn>z^1c=1gggt)&PUZHKk%uuWs(3ab}8MNh+*Cd5g>#Vl}v%#=q#^+;}=|gu{UJ$3i zo#YC^wccc(CaX?0UhUS5cOkG=yX&P64q-0;0<#gR)VczXCaNQ1{M2*zwkw3$uYn@f z08^~t+F>HPeX>^fgwlGg1>#b8@eueJ5BbO<-)`|C;is`A`>g1mb=({ zDXPa=6KR+3mM$vqrO7(8*J#KkP0na<|EBbm$;^5;_sT-buzA=``5`yDJ4D8u_Y~o8 z8y;O|tJxY9&!!<_c> z(PGUkQL%GqDk?OUdKfKo{z?h{e8NfE8H+v+81a{@oSn~KJ<^tSNwQi8CO>GzpZ73v zz3K5#aoU^fcC-gWUbVp<|DDvKQ;^n0`#mJtD{GnEVesdg^R^Iwlg-VcEvc_+`V14% zN5EeQ-eiHcG+3+c_KT#Nb;3Hgqu{SNsp9!-J)52!h~e!q@W-DFf19JcTe4B=px%+1 z4VxdRGkiz*-`LVF`3a3wnoSL04#&aY#IOIV7F}wX`mf0tv3Z!GqLpZb+ic}ZW}5{5 za5#{P|M*!5X=!a#{1uk@oAOPBS11|$<$Rguml%CG>D`!uL#}=ee5LB}wY9od50X8S z%*;|q&2=RsDiD!ER;l1G>*imAKVJNs-Gq2x%bLty1O5!fiiB5ocP|5fi#wB4SEz^+ z;13J_q<#7PrTn0~gF~79Nxhmo_WXiR>X8Va=P7md{FV4hQfFwVB zU%zYlyKYYm;G`P%sh#y=$aHIUh# zftpJ^XCfWP)?&@`f~0$xB%3H%nq1QEdLpEnR|{j-XMq`)I)WaoI)569CH~v*B)zugtwNc_d0i#a~nGXJnlPaFS;bi#- z<)kykb?~Hpehr;KSiD(Rlx2+fXR6IGXIgr zCuJ9(C~@w+p`w{pL}^+~$!4}U!5?Ns)cnW!!>VT`=WkX+l35uk_I=tsz;Bvg?BgRz zRjL$>7SHcGrTWXlTYbZkWHxU1$g2Ox;b|(v@9y30g0nH<2bHuLH=-5t@?!E@KE_D$S3k4M;Lt$4boZ6=?0> z?Q0QQf167m$f#`!^IH}@k{pX`7aGRH~R^NbD z{$$^kL;P~<%u8BZa)c(Y+k)iifVN79ho;H3X)w^{dmeLm3tE3Dr>c4_uCBa(Its66 zioc^*7A$7?Bz13Ap<18DVV5GrWp#h<>L?p>b3>_0+V z8j6*-k7LnA$1ZJHBZCL_ch+RIdF|FwC2WZPrdRku{E8)9s*CxNU4z2aH zt|a2ydF3&e&!E*mgy=gHw@aOId#3tVKxrXqAa(^=x9xn=ndKK_Yjpz|b?w^2shA6l zmoNAwnrRcLQ72$r3g*>d=>{-9N)4>tF__U`fpN%1j4m+vsgx&4zjboyA6TpDTKmbO z`0XxYiSjo<$)#Rkv$g6WUs7(%A62KjnNOMX_agjF>8~le%lTRIfwaqZXBI!eAFZuQ zqw!k1FIi0XQ_o-f_9Ef-O%asyOYj$To33=bz?^=AznD2xvA$r!=4Do}g2{!o>LB>r zL^e?S5eu1Po)LdbPW)4pzgv{<%{EM~HR5kGDT?-QV;Dci&9w(AJ_>ogFyilq4(kh~ zMbXX4RoR}&n4J#%B`o|^h`)#CKh34v)PZy;3tzUxtyTUe_0g&Y{P_`o9lBt*LcGu> z#Yq*wUxsGxVW-9}K{EQF&c&n}m2o?vI!Il7$7*oOSb#sQtui@AS%k}(RSEFdGORyY zt0;aD%{X)%t7P_a@MkENavNd@`WpBfJDyUAOJmlS;IBLi<(1Fh_!)F}Z5XpJspqd- zTQlDV$EPR&7Oo zpHBZ`N9nS9%xEvGj855D!dOmVrdK7MODv_mtm4;dMa6oc>DvLb{d&y&1ZH=Bikvz- zWfk7bDrMq~BA5-OcHP-CxwyToGCGe2X7<3$9ThhqZ2=X>e|KS2=yc1XZ<4*)c@{9M z0L+G8&=tb$f%y+}X%n@X&hbNNFRT4X(14j?yH81~MvA3NIa}JxsyM0QF`IK$RJlua zAKJ@`KN-=wLQ>OV=E+XSBQ<^rE0UArmCDvjY?4~MA=$5^nB`G?YyKxp|ERO##$WZ& zeYepYMz@tkBv$Z1=wYkSB0?N%L6x>}}OKC$Nqj8N5f zTdyiZU3S-)FxnQYp{+Ew8a;jlvysjqw!_Lnf>{10-X5lVmto(!fLKGZwu9K-`5M#P zg`^&0eTOTE{R4&a&L>u}fbM>P8>O_Sz zU`{ol7;{q1M8#@>*k};@>pLmN&VtzClvB5;Wae1YNHN~sG_44+&uN(5Z9)i>*D_L! zQyx%$m*JhL4Pp;phTVX?{zhJTW|G8z8M;htpS3*No%;K3SIRT3 z1B@}HTH=Bk{f~c<`{v)wrJ55+=$nGsdqG?B*K3S1t?gJroqP8P8|GOT+Ont=k7+F) z<9OR%RR>G3U?In;-? z{Mve?D!7?ax#aq2&AW~<{)XBI6Qd!P!OXS+*n2jv3pVuV;?MbnwJO+q(?+BfGBTGb z8bVuk${6c+Z0PZ%rfmu$e!8~otg7*Pf$GI~k{vgJnKgp8Y-1~xccx3TJ(!g@*o(X{ zT(HNB-SAr;Y&%N=i zzS6`*Yt~_8|0W}cHg;*(zkirZ{XmzXfie8c|380uG(XexI7W>sV}sWvfYQE!RnBT? z;<&mcMOpmyTw8(JLBinO@I^@Wsu{!V{kg$=#YFN(d`gu(IYv>Y!r;B4Jt`+D?`&or zzztqV?SjD@srr@jKwe@m-R&I8oSPKkdXIFms3z`DuCiXe5H#BqT-Ov4J^}qHkpU8u zHPdr#K7g)`gWo7naP4JAR~82|r{>@~;F+bUSPif?9;|KoL0mT$Tw7a{^uORb$cXDT z=0&-FL_>$(6%I0a3nQ+Zd5RQz*N0YU39ehB;-1KBGV=Nirupx=?xs$wTM?Z!hGc_c znBAX1cznH*MG*dKF6o1mdmn-2(~29sNYEHz3OK(^{dn&OX(B$WNpVueBfM%I72*?? zNwopOJ(2#@@%NL?J*k$g-WaK|nzJhT^!rxI@0a!-|MP{A4fVLd9NGfmo0EsCN=AZ_6+5_QPi7|c_!;U9y@h?C) z=Cn$cW;IhalPtH;a&=NunFIn&o(!j}X-An=M}VD>8zsQz zm1;zTq0pxd#F1-phQdAo*cI~4;J2iyL%(3bMQ4Cry%5+T%S8Hp%&?lIiyrLpW>Lp52TNt<3nJp?vcC;>o^Ufo=C9*h*o0itbov*P6uN zonRI{fUUd0_J$i>{es|x5IwfX2)n+&5d+jyV0(f(?SA&T%&8Z!jreROUJ2h6ya!j2 zzX;p@0^8UrBF%oDGUnLZ2-_XzQ;MkLk55UmA+QZK!Zv;;U2ofkDf$50vUp{Nyt05S z|7GgV;uSBC?yoP~+m_6(FR=YNuuKtbznDv{-&2B25;0e9{2LgsEf}Xh?Ifha_>nAO z(7eS-6_2e)JU!Xw3A0RsImQ2kQQRtsZuCQRZh!F1lf3qieRA9?_vGb!BQ@S(@yWqq zEtL;~8YLy2CfP9v&Iof^h%wH@txdq`wyIilO3YbQXOcyNn$BHu)Ydy#v9A;3-=`?chUlO{lt$sAnwRc#J z25YtA@&5L^#0@bT5I3}BB8UGDW!6K$x(Bivn6JdUjTMg#C?jL`L-nlNu1@oLbY`1h z)D{ElbC-~mXEt*g2G(~DA$I?E_fU=Tt)fcYQ@s%D<&ThjBwQ-P!TP2RwtCi|2?sHD zG?BQ2SYkixk>qrQ?M8xidAbSq;>yO5*Br|(WH6vhz<|C;j+X&Tut0MJSm#nbVL*TN z$OP;2qeL1JQXX?2S(MoDHATbbJJOqquv9RMQ6QE)OIOJm7Eu-xG*NnDTaj5C;o!kc zM+;*2l7}v$emZj+17g!{%8QCM1F;Q3Z2C`QMLX7%3bww9fd5n{7PlH|cW zCXX>9)`0>*BGOih^W0oFUE`-eXTNQRydHyA{(G%E24a^*51`Txti6=kjRUcV;%$o% z``KK=DKfm34fN{A%##gP_DT8(1Dhm^m@YT|dJPyCjDsh}(xd$q%yR-TE>5a=jJr|S zKX5zxor&ClM*8k`Yb3{2c1wP9AX3xs_T1#Kf14=lwkdVIR0id89DzZTK&vLNuPWCe zNICf37|rI$iT;M#4y4_ZmY=w2@vztdqr8;Ug? zw3g4GoT-scQi*WY%m91Uz~0Dw_MZMrchA865UXcz?~;c;Ij3zJAD$6_j)w;)-1|gQ zPcoRxKVYxcW@2f__&zGH+##xm<8BpV&zZ(tgWg3l%bCX3uj_V^(BR5}%rOp7I^V7+ z+O8V=WYDNq5~ErZ7Dw%2ux|php9Ls;UN@0^Vg3G*R|0-0M9fR2Fl%#^920|^Z(-K6 z0VS6*?5X}(?oHou@cVe?Jm)`9#?}eswafqO=Sw!nka2)=E}#sw-HYj#;WRWJGEKo` z^Yl=Ltryi85{p&S^97U>$PqGRV*qnn04U|&RIyF~#T}r8>(wYtj;^7>{g9(unBzht zC_mnrS_Dd2H05;0i^&%mK{@{dUC#()ip5Z)4N>t{$jb|P8LZ#ex<_8D)ksccM9l=5Cz@Kv={$4Z{=?}L)Dq^xu^47S0%?F?TV>c^1{x@j)iHbAK$P^p+qvVH3A=Ayor*ZvFb^sZZq5 z^x7g#W-#Z?MKD_@jjR*EE0zD(Z!OuSk@5&;u?3hl5zeDeYeg23WpbEos~$5t&lmu+Nd;t7~>SmF( zisA?LrlgZ2#r{}vhGM;h^EM&GV6BGDBB?Yiw>kv=DuTah`TFl9*=NRafw2`Z{wE*fQZzUm=M8J|njYh4XKj3UPs;Z5bunN(ocf}1 zv#`fcI-rbiK`g2LEmfn2SgCB^)GP$02X#KtJul*y?&U`U326cM*oMP@@vt zKAP%q5T?KlsL@`x5u^@fYbRz+IeR=fA?6`TeF1wn!5)_~sL`kL8k5A`@g$nZ<3e=PaB)8KlU@J0Upej-EYzeDwG#KbYxV!QSkZ;@OE#q0H$X z*vpFZ5EbLrs{eo3^SepX4Pi~(H)8K@d_gE*U3?Dg_(#5yi2<2R{=kU6fH;xDq?^f1 z@eu5}qT*eUS0M5-gz~-6ZNwbR%;-(jb544VS9i$E8QpkLYsL6 z%=nw+n8`~dniq@~&HP2SlZS*b&&R;5IH}?>Yo&j3W*AdE0cO3C{?ynh$t`0&lkB>T z(D-ZDCEG}UD%Y8PK6dR9<+29*H$Met*&%IJCSSWKYYvSO+R{+b4JSx01v^qcGs29A z^6}{w{tCz4Bbh5RnBqAwtE(O1_jpBO((nTXp?p2>%2ge+!&H$H$=0GwRA9!7uT|5%zFuM*tT;ol$^o<6`Pyj*b|PVOvALD%>vmJseCAvT zv%g4jP5F?^9Nz%5eu=e3YozEN9-LqzVt{noA74evQ?XmA{aavm@D5jTnL39&KGA6* zFuSVlluS}h&{ezxW?ae;n3pNXp*!6BFf|0$YIYIKru5G!Iwg`#>SSsdjwyH#%vuN) zH~SkUG8o4ce9&X&OVyYgjl9sWG-z zzmTyz-4vnh-@spSj~CBhcx92~^op1(`40a0lSyl)B}=voj;i8DXjYwDnOyOPQW-Uq zHBKj1r`PJj9DabmZrT>A#21WJ@eBNYKR41Zsp_7j@P7-IlAP#kqUzc8Z&lZeB)fPmGy4txTG&b#F4Lt=ZJ1Ra z=kNPU!QUYiUq1~q{l1OZA1lsKtPjzrD$UTkp{ArsBsTrLx-6?^;w1dP`NG}Uj{r9C+xq-C`@z;|&k{LZS znI(YWP}5S9#dRp5(KDE%DZu>eb$!u(x$Wts*MAga+l5SsIE(~5%iv3wyk~6oP-u1W zUpkWcydAKW+z8}R{5PcJ3=$jYjg6TKFyUDULSmV zkR2I!8v9$6#pkb>*Hl&ZWjAFhx3QX4t5*3NU>kT&R3`4uJ!V@Dpa0ZX59}@D;m?ms z=aD8HEtC2r^I-y0l*i}4-E*X0jkY_JUMy7PTRA0P{Z?Lk(MI)~0%7AY<8Nk*&)?ow zYBEziKC1y->vs73iRagg&(DjWNvd&H%S2{x4=cw|tfv^Pl<#i%{EY`t3SHBfbp?F> z$M_V>@;`rH%5v6lSUC>*&%a@@r>}LAr!u{+um1Dj4W%@0WigkE`1}>$(N~+k&s3#K zP^e0kbuIMywVz2odoFWy#8-~1vO`#z5i zdx7p3QOUXza28m?Sx|a|NN=_pDnx1v%dR%MEY%ZB&-}4(fyt#AK7e#$~w8C`;A%Z zEh^RvU81c~_ghhPzgM?XPM4#YV`Zc6clyxz=tk&|y5BKmSI@rb!Q^g6-LJ)4k;0tu zYnj3w-S2OF_E6+i7J2=Ru9yGr!^+X=#zx`PLuu)j<-uveT^@$7vgYh!MIVCKQC9Hd|3=e*>Eh5P*4{T`tS zm2XXsf89hmVdPZb#8H%sHiJ1-2WD#rt5vJ^^-?|_JyydP;~6SC)LqEUD;vgaJ%JhD z(w_gu+s@C&tX?e1R1ai|8o=!3`;mS_bqPtGe4X+!3mg1V*&`xI^_IHSd5APNs|n1o z1)3M>n|Z_G6R!o#q@2xU<)HZcs3V#;4Qonk12aRh_5!nGJq?)kIY|XrjQOZK!0Z}6 z@4S4>x*VmuTk}LLkFat!KCSIrsmfHpymJlonC@8lQl39|2D7gZ%u*k4*Y_)3 zdAPnAqQ*F8m$iF3k~gG&RRObzXmugXo^#B`k+*H3WXtT;z>L4i0?ah# z6uVV*tVn91Tbww5u1RrH#bb8Ei=JGV#uNd-j6Ye=b9Qo^wWV@w-I1D43s)w;%I>60 zp5X0Q(v@TrWXz!nFpFB;SXC-HOes4(78`~(7jcukqG4q8EKI_2qD_I>SC0%e|6NI& zn~#|*b=TOaiYb}_vl45f{HBcEmQ=lrOFm{-AHP(VcK26(>nHMERC)+A3j}7puv=O< zUHYQ|vuX~^JVyR2FyqC4*qQEm?GigJiMUB#taxA+JlcTSI^ulMeivrl0+{g+T%gUI zlPHa|FlJinwb`4@`o7gCHSi1ZXecm~q#i3s>gfgM@+UAWHIA^+c5keD`eeMy^ULKz znC)IB8~)l(I^bt02o_2@nrriu?uF7tpR53oy|o1rPye4mJgI} zBGS^qQ6#aXCQ94}V3yA?ks3%@x~f=7^b>i-VWK!qyO=Us;)6M;<87@| zU&)_R*R$kS4s&i-2+Te>sp>!582XbATY`BWi}nDsi7j6O^oB+_OEPVltb-oRsmA9H3(4h-%U8nC24516*(H0_77o}9rPa6 z&fUVC>dhs0?a~oAtQt3jM^)T-|68QKd^Fr|e*@(vyP6e3`2|P0-%t{o+fsz>xbb&y zK)E0oB<2N4?L-V$Ff?XyQpKaJeo9Y%zfT+S+_1D# z*{64>V=<&LSD0hbLU*9Np-LlF%G5CB?egO^TO!x_8(z(K>d#i#IWXHEKv`AtuA2Yu zZeHlm-#UNkb;!6`(JzB3LV)sPv(bJ*n$1Zwb6oRLcCMSD?3v}GN~bce7_4MwJ%KX3 z=%4hL#w0SUUO+i?{T_ibFMdsPQKc2L+lbAS;ta*w3Y6b>HK07?p^#cBKgg^@f%0Ay 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 z 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 A; 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 z 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

}_tRP^d6f<2EfnE5MJQ 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⪚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%0AuZ^_P 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

t29cHOIxtoo&s0``N)=H1k`+{VwyQek;b*O}!)f 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

ck;(_0Ro| z;@e6eOc1Z`LsH`qW1awr_Z>;)-&lU1d>-DK@f{yW0g|8owVa17=r zxV6hq#FMJYD2tXz0`^-`j}+rX<9~UMW|ak{;1BGR^C#Hz%QIZDHhe#@m!uv7`@!3{ zq#v>#N5p0{dClAo{DFP+z&jr8ieukxKNW^`3i5-%zM}nhU|+*XN3s6P@{kF8FHbra zm&D8ubL@w9q9Z#n;cx`lJ9VX35{zbEhGzE0OrGQo!cx2e77E`4lGejdeH7Rq|9%$g z2J5=k{15xS9D6PGei`Q*Fhz0^?6bR336GS_;TW*@tf?=nLLQYfvNIg}d+<95=Z2Ed z=Z-vv%i|bY$65YKW+PY1|F;QAsp?$n_}(eZCl%P2Bvmr@z5b;uPr@)u1H@JeOQFs2 zF{1A_FO^N>)0+3Y1Jz|W9ux0|sMX`>O`U*K%}ED{|EoPsOnA7tY0cUfIm87G_2MHh z^F)(8X0HdtVR3(B8=k*4Io`h7>`uvmxTf&di)6Yv@tj;+HZ(V+Ja^e0V3+VeuUGO_ zEA_g$YsA0F6>=hM4zn--Vx_%MXBl0-23e0X0I_29Z4R*#)$eOY=k_UhvaMLDZ>fRz zcMK5s-Ch83?Rq4ohbBG&i0uIJ?Oz3XLVqrzv)2%!dJ+&n3VJ0zX;fJ~>MuL7_g)v1 zcRGkH;FFrh%>5J~o^MR&@Z=ob7ihl8R@>rg@xYjP^3|N|b&@Gh1L8AynVnI)YN*|I zXyWod0%kBqVE>m_RktBsk3 zt6wxG*=>=``79v*?{)^ShnMidI0v&KZi1y*N5KXY`AaX7WI6(V&H>3?D7BejCTzhD z$K?bItl*1ar}IaXqB?nD4zoQEBqb>;AQ{$STlzukvBcP^hFE-g;ZGz7z4IJf++r4% z@>`w~vH0>Lko4z+*r=9tv^kO+T{0p0n7jg~+CFFImpPK#sXsn7G=#Zc0g}<<=)puZ z+COMCy$Q+Q0t1q|EGqLLLew*XWZdza97+Gw{~;O9k*r6}a7qtNe6M(CEZ^d@NTHueehVJ@F*xmo+O|OL>`=Rck?k|%WaB+!PtWaL zN%p;hDW8DTevq9QwMg4{)@_4FUH^=shE;l(mPzTEo6o4HAL6p-g=Ne+3!LUoKF#Y9 zfDrXQc@2ep<2;0}3c}&V@C(yezqz7fOXrIbhqWpnA`I|I28sz_w*{x>5)VdUwe_sUvSkarR{BB zhmLOj$t+)*IIX#zjwK)!{wvNYdSodm>O%RQ%=I-mjh{;m+!&2E6^&-=L#ngCup+`j z(K?KzYaC+EZ@?)=XMqxyk!}CyO%0b02xq^LWWy;;@wN!3enaSZ$T#MY4NhwgIa4+Z zc@dt=9&k=?$~@#kE}3Z;Mo!_;SRRguYN#rIj~)Gf78%5rroQe%9J1cO2a+X8m5k(> zy}S|^-94G|1CShy^8Zn75(VFc)D?@bYp(XFD=yv~t2(O4QXN`Lvh^o0r;k9=F?@^I z(|vF1oaJ{l0%pkl&``tCP#x}&+_1{bs%lYV`}|xwu^dz9pNiR6WHnW|BF>LnD?X}5vInvF@(Wl+qLYUQ=+KEYX7g2I zb@da@>Qp>e{u?@%vy(Y~1FO=D&3}Yg9I!e?RWOs(g`6XoyqLB7jPthOfhF6qOW`wy^sO?8elQf>dSz|{+#v_s2; zYWcTe`e!4JSTEg;V#=RjwH#{O5Vgxi?Y>~fw=YJwH;prlX-1>x(KA$o&zK$l1y(mh zc3A!b?b1094OcEU$f$khk$zmnj`Sf>wKa#yhkLntEVKGubUd_)l=x*Redk<2tSo+4ysOhR+v&bXS7Fz`Q`it^ch|5 z4?`p$5KB^f=1W;W*8}2~)OB56mdD)K9}wRYwt2QG4zUXjW-qV3!{kOlT$d}`OGLuu zt?>-meauz~LVWvUw|QG!P6%Y?C>NGTtI>4iiaWE)F&X%gkrDL*PM@L^_mLd}C%A#n zPwXJ2cO`Tvb44LeXZN1xP2r99?_LD^F+$mJ3&mzFFXqbk2=6M&eHMXn#2h^-|-3?g{xiGjoU0fZX zsvHC5Ahf3l?Cs=NieNuzI!Uz&VLqjReMwR!WB+CVU3nWmBn7ZvhVnBKE{c9P-J5oe zy{cJ|IapnHMvSO&d!cjACE09C=41uzd&gc9S8wXpGr)&?HIx=Y(TfKy^zq3E)S1jHf2C}e61Ip?j5LpYf{`-CqUcSf^JW|zc=9L8R+hr zOpAYvY=Z9x_|yGu$Vh6r1DP(^W73NuJ!ySb_rCdzx9-Q@E2i==d+bXEtOVrK=bWia{ zMhxQ|V}fy-rwdKiT$_O*as|+R1+tgx%-24f_sp=~wQk0`B-iv#-8Q7Vx`k?zXcpr- z5|TOF1LEa-ukd=fVF5~L-e6&(Fu)iBhy`{(jo09Y0)9OQK-|E_QjkJpTjWK-vh8j3 z5bCj0`3-0^c%$M@X6p!uC8_ENr^_z4CViiE-DFv`% zz8R@|odB^XPjJ?*939<-^hlLV5IfU%bIVd-=FS{qbLvfQxnU4n8AxVEQUg~-qp5+U zwaH?hEqv)?p}0&P;w^t09&ClZs1gDtkZkwY{sYPThxy%asYfz}OA#bLHKgOK5Z&eq zB%8g-EL$I$ik?de$nblCoFsw|S!uTte3_#gkc>g=sN^qX4)Tjdki0dQirTl7$vg_| z>SG`2;FSr?#~qxObZN<)o_)!$yj>%LDXW0fTe#_j%=cpTe&s~FBNsG*tCr~2O&P3u z+qIH@$Z?Vl#D+6f!Kw4qZ{iJyYT|%PS2a@TsS{eSCR#6sdgI&OlbF2+I9VVXyK+x?+s2X_NTJeKVV8vaGLe&LQ2!?`vN9i@+;)Dvj2N=z}q$A_75bx-I7^U zBQ2bKpAPMZ7WR@jE&G;p`WDr{s;6_O;83X!POVX`Ops6-b3u#l7KEqT{>!EAU^RiQ zH#nV%*YIy4rxs)AtP@7IHK2v32Zo8&2mKbGJe?CT_Vy_grw-(^xKl5gx%+_AyM}9= zkL5wH1N#pO);610JcUsM;`+`>a9R_bjzn!sp>~&0yIU~+f~pI`4&!X&2ICkHpKrVd zcaKFg+d5!nU>Qrnck$@p#8NBM_gZ^aq_gN=-TeMwC3;YZ=hwNxT#h=Wedr=RVqEQi6u56(a?jW^~KUiru_h#92 zSxtGSEReI3g>4mu5gHPDdx$wU1}lfqI`idkWJj>{;(rdGd%d{See1T&rwOnqNvdQl zDnF(x+eR~G0I-nRS_;em`YC$%dDHY=;yI1^uq<`Yl{We^lNIVS79=}3kU2F47TdGl ziBTytRRfn?(QNJL82l4?RBX^tx95}GWEHbl0gIUI{Tk`-_7zibFQJ<7hV;Yz ziyCI-S=6%KF^?|(w2>)A@Y106m6XZDk^&y|{9ibCXj==l!>0ss#14}E0jpIFUf|9( zCl&j^;v}=tfS1TEA2=_S@LWfGa`6Y9VQ~h6myf9LQGAh&!OQx8YMJy}hz&{gM-o}B zNv{PK^0G*vvlAQh7^;j0Bif1Tm$_ol)6Y%c<%=d>yq=QOvyIHX8FazQjW&+*nBIoVK6F4w z)*O0m7-YYHo1-19{%W|jvs%W~hwBg0LgUsd#eT7!SDP(=M8bOkqVYP-p;iceqSB%XC$GqNVorMnY+j_FM z`MWES)c&E&wiO_jq_UU5YMs9*J;Az;jGukv5X;CWya}rDHzf%)A|k_@)ybX@Nb)+XG_n40^B^XwA=P%_XKd zhjd|VsD+{dY2ruH!paVSc<|sLtyGN@W*&tQ_v7_iLzeWT31^w2V-bim$szk_-W2B0 z2@s!5zlZcb9T4XLZ!LZ|WYgtBXdSB5TKLL;z?8Pa?gB%`L{x85oyLKWb|7~JPK+u% z(SkI=lQ>M#cLw&>Wi5pj@`o}{`TioqIak}4T{^UAzNSxRW7uE4%G z${�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 XVDtnT-mHz`tC$k)n4#ko5 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

@u?qr$e1^h*aPWbc>Z3>jFPRf*iO2H*< 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 h8F(qwx&tYp?@%@Dh7BgxK#nWa02 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%0D*#-MxJfOEcPGP!KKbTg;Bx3r~9 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 literal 0 HcmV?d00001 diff --git a/examples/flight_replay/flight_replay.py b/examples/flight_replay/flight_replay.py index b90d61ec4..66bc28f31 100644 --- a/examples/flight_replay/flight_replay.py +++ b/examples/flight_replay/flight_replay.py @@ -7,122 +7,200 @@ Full documentation is provided at http://python.dronekit.io/examples/flight_replay.html """ -from dronekit import connect, Command +from dronekit import connect, Command, VehicleMode, LocationGlobalRelative from pymavlink import mavutil import json, urllib, math +import time #Set up option parsing to get connection string import argparse -parser = argparse.ArgumentParser(description='Get a flight from droneshare and send as waypoints to a vehicle. Connects to SITL on local PC by default.') -parser.add_argument('--connect', default='127.0.0.1:14550', - help="vehicle connection target. Default '127.0.0.1:14550'") -parser.add_argument('--mission_id', default='101', - help="DroneShare Mission ID to replay. Default is '101'") -parser.add_argument('--api_server', default='https://api.3drobotics.com', - help="API Server. Default is Droneshare API (https://api.3drobotics.com)") -parser.add_argument('--api_key', default='89b511b1.d884d1cb57306e63925fcc07d032f2af', - help="API Server Key (default should be fine!)") +parser = argparse.ArgumentParser(description='Load a telemetry log and use position data to create mission waypoints for a vehicle. Connects to SITL on local PC by default.') +parser.add_argument('--connect', help="vehicle connection target.") +parser.add_argument('--tlog', default='flight.tlog', + help="Telemetry log containing path to replay") args = parser.parse_args() -# Connect to the Vehicle -print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, wait_ready=True) - - - -def _decode_list(data): - """A utility function for decoding JSON strings from unicode""" - rv = [] - for item in data: - if isinstance(item, unicode): - item = item.encode('utf-8') - elif isinstance(item, list): - item = _decode_list(item) - elif isinstance(item, dict): - item = _decode_dict(item) - rv.append(item) - return rv - -def _decode_dict(data): - """A utility function for decoding JSON strings from Unicode""" - rv = {} - for key, value in data.iteritems(): - if isinstance(key, unicode): - key = key.encode('utf-8') - if isinstance(value, unicode): - value = value.encode('utf-8') - elif isinstance(value, list): - value = _decode_list(value) - elif isinstance(value, dict): - value = _decode_dict(value) - rv[key] = value - return rv - -def download_messages(mission_id, max_freq = 1.0): - """Download a public mission from droneshare (as JSON)""" - message_url="%s/api/v1/mission/%s/messages.json?max_freq=%s&api_key=%s" % (args.api_server, mission_id, max_freq, args.api_key) - f = urllib.urlopen(message_url) - j = json.load(f, object_hook=_decode_dict) - f.close() - return j - -def replay_mission(payload): - """Given mission JSON, set a series of wpts approximating the previous flight""" +def start_default_sitl(lat=None, lon=None): + print "Starting copter simulator (SITL)" + from dronekit_sitl import SITL + sitl = SITL() + sitl.download('copter', '3.3', verbose=True) + if ((lat is not None and lon is None) or + (lat is None and lon is not None)): + print("Supply both lat and lon, or neither") + exit(1) + sitl_args = ['-I0', '--model', 'quad', ] + if lat is not None: + sitl_args.append('--home=%f,%f,584,353' % (lat,lon,)) + sitl.launch(sitl_args, await_ready=True, restart=True) + connection_string='tcp:127.0.0.1:5760' + return (sitl, connection_string) + +def get_distance_metres(aLocation1, aLocation2): + """ + Returns the ground distance in metres between two LocationGlobal objects. + + This method is an approximation, and will not be accurate over large distances and close to the + earth's poles. It comes from the ArduPilot test code: + https://github.com/diydrones/ardupilot/blob/master/Tools/autotest/common.py + """ + dlat = aLocation2.lat - aLocation1.lat + dlong = aLocation2.lon - aLocation1.lon + return math.sqrt((dlat*dlat) + (dlong*dlong)) * 1.113195e5 + + + +def distance_to_current_waypoint(): + """ + Gets distance in metres to the current waypoint. + It returns None for the first waypoint (Home location). + """ + nextwaypoint = vehicle.commands.next + if nextwaypoint==0: + return None + missionitem=vehicle.commands[nextwaypoint-1] #commands are zero indexed + lat = missionitem.x + lon = missionitem.y + alt = missionitem.z + targetWaypointLocation = LocationGlobalRelative(lat,lon,alt) + distancetopoint = get_distance_metres(vehicle.location.global_frame, targetWaypointLocation) + return distancetopoint + +def position_messages_from_tlog(filename): + """Given telemetry log, get a series of wpts approximating the previous flight""" # Pull out just the global position msgs - try: - messages = payload['messages'] - except: - print "Exception: payload from site is: %s" % payload - sys.exit() - messages = filter(lambda obj: obj['typ'] == 'MAVLINK_MSG_ID_GLOBAL_POSITION_INT', messages) - messages = map(lambda obj: obj['fld'], messages) - - # Shrink the # of pts to be lower than the max # of wpts allowed by vehicle + messages = [] + mlog = mavutil.mavlink_connection(filename) + while True: + try: + m = mlog.recv_match(type=['GLOBAL_POSITION_INT']) + if m is None: + break + except Exception: + break + # ignore we get where there is no fix: + if m.lat == 0: + continue + messages.append(m) + + # Shrink the # of pts to be lower than the max # of wpts allowed by vehicle num_points = len(messages) max_points = 99 if num_points > max_points: step = int(math.ceil((float(num_points) / max_points))) shorter = [messages[i] for i in xrange(0, num_points, step)] messages = shorter + return messages + +print("Generating waypoints from tlog...") +messages = position_messages_from_tlog(args.tlog) +print "Generated %d waypoints from tlog" % len(messages) +if len(messages) == 0: + print("No position messages found in log") + exit(0) + +#Start SITL if no connection string specified +if args.connect: + connection_string = args.connect + sitl = None +else: + start_lat = messages[0].lat/1.0e7 + start_lon = messages[0].lon/1.0e7 - print "Generating %s waypoints from replay..." % len(messages) - cmds = vehicle.commands - cmds.clear() - for i in xrange(0, len(messages)): - pt = messages[i] - lat = pt['lat'] - lon = pt['lon'] - # To prevent accidents we don't trust the altitude in the original flight, instead - # we just put in a conservative cruising altitude. - altitude = 30.0 # pt['alt'] - cmd = Command( 0, - 0, - 0, - mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, - mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, - 0, 0, 0, 0, 0, 0, - lat, lon, altitude) - cmds.add(cmd) - #Upload clear message and command messages to vehicle. - cmds.upload() + (sitl, connection_string) = start_default_sitl(lat=start_lat,lon=start_lon) + +# Connect to the Vehicle +print 'Connecting to vehicle on: %s' % connection_string +vehicle = connect(connection_string, wait_ready=True) # Now download the vehicle waypoints cmds = vehicle.commands cmds.wait_ready() -mission_id = int(args.mission_id) -max_freq = 0.1 -json = download_messages(mission_id, max_freq) -print "JSON downloaded..." -replay_mission(json) -#Here you could actually replay the mission by -#taking off and changing to AUTO mode. - +cmds = vehicle.commands +cmds.clear() +for i in xrange(0, len(messages)): + pt = messages[i] + print "Point: %d %d" % (pt.lat, pt.lon,) + lat = pt.lat + lon = pt.lon + # To prevent accidents we don't trust the altitude in the original flight, instead + # we just put in a conservative cruising altitude. + altitude = 30.0 + cmd = Command( 0, + 0, + 0, + mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, + mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, + 0, 0, 0, 0, 0, 0, + lat/1.0e7, lon/1.0e7, altitude) + cmds.add(cmd) + +#Upload clear message and command messages to vehicle. +print("Uploading %d waypoints to vehicle..." % len(messages)) +cmds.upload() + +# Set mode to STABILISE for arming and takeoff: +while (vehicle.mode.name != "GUIDED"): + vehicle.mode = VehicleMode("GUIDED") + time.sleep(0.1) + +while not vehicle.armed: + print("Arming vehicle") + vehicle.armed = True + print "Waiting for arming..." + time.sleep(1) + +print("Taking off") +aTargetAltitude = 30.0 +vehicle.simple_takeoff(aTargetAltitude) + +# Wait until the vehicle reaches a safe height +while True: + requiredAlt = aTargetAltitude*0.95 + #Break and return from function just below target altitude. + if vehicle.location.global_relative_frame.alt>=requiredAlt: + print "Reached target altitude of ~%f" % (aTargetAltitude) + break + print " Altitude: %f < %f" % (vehicle.location.global_relative_frame.alt, + requiredAlt) + time.sleep(1) + +print "Starting mission" + +# Reset mission set to first (0) waypoint +vehicle.commands.next=0 + +# Set mode to AUTO to start mission: +while (vehicle.mode.name != "AUTO"): + vehicle.mode = VehicleMode("AUTO") + time.sleep(0.1) + +# Monitor mission for 60 seconds then RTL and quit: +time_start = time.time() +while time.time() - time_start < 60: + nextwaypoint=vehicle.commands.next + print 'Distance to waypoint (%s): %s' % (nextwaypoint, distance_to_current_waypoint()) + + if nextwaypoint==len(messages): + print "Exit 'standard' mission when start heading to final waypoint" + break; + time.sleep(1) + +print 'Return to launch' +while (vehicle.mode.name != "RTL"): + vehicle.mode = VehicleMode("RTL") + time.sleep(0.1) #Close vehicle object before exiting script print "Close vehicle object" vehicle.close() + +# Shut down simulator if it was started. +if sitl is not None: + sitl.stop() + print("Completed...") From a99d3d35fad8cd81d17d611d19899808850837f6 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 15 Feb 2016 14:57:23 +1100 Subject: [PATCH 308/475] Update flight_replay docs and also to use standard takeoff function --- docs/examples/flight_replay.rst | 180 +++++++++++++++++------- docs/examples/flight_replay_example.png | Bin 601186 -> 168903 bytes examples/flight_replay/flight_replay.py | 72 ++++++---- 3 files changed, 174 insertions(+), 78 deletions(-) diff --git a/docs/examples/flight_replay.rst b/docs/examples/flight_replay.rst index 48fbd5e87..53a71f30d 100644 --- a/docs/examples/flight_replay.rst +++ b/docs/examples/flight_replay.rst @@ -2,22 +2,21 @@ Example: Flight Replay ========================= -This example requests a past flight from Droneshare, and then writes the recorded path to the vehicle as mission waypoints. -For safety reasons, the altitude for the waypoints is set to 30 meters (irrespective of the recorded height). - -.. note:: - - The mission is not actually run by this code - though it easily could be by taking off and putting the vehicle into - AUTO mode. - +This example creates and runs a waypoint mission using position information in a TLOG file. -You can specify which mission to replay using a parameter when starting the script (for example, to replay your own local flights). -By default the code gets the public `Droneshare mission with ID 101 `_. +The log used in this example contains around 2700 points. We reduce this to a smaller number +(that is able to fit on the autopilot) by taking 100 points that are evenly spread across the range. +After 60 seconds the mission is artificially ended by setting the mode to RTL (return to launch). .. figure:: flight_replay_example.png + :width: 50% - Droneshare Mission #101 + Mission generated from log +.. note:: + + A more detailed example might determine the best points for the mission + by mapping the path to lines and spline curves. Running the example @@ -26,9 +25,6 @@ Running the example The example can be run as described in :doc:`running_examples` (which in turn assumes that the vehicle and DroneKit have been set up as described in :ref:`installing_dronekit`). -If you're using a simulated vehicle, remember to :ref:`disable arming checks ` so -that the example can run. - In summary, after cloning the repository: #. Navigate to the example folder as shown: @@ -36,65 +32,147 @@ In summary, after cloning the repository: .. code-block:: bash cd dronekit-python/examples/flight_replay/ - - -#. Start the example, passing the :ref:`connection string ` - you wish to use in the ``--connect`` parameter and specifying the mission to replay. + +#. You can run the example against a simulator (DroneKit-SITL) by specifying the Python script without any arguments. + The example will download SITL binaries if needed, start the simulator, and then connect to it: .. code-block:: bash - python flight_replay.py --connect 127.0.0.1:14550 --mission_id 101 + python flight_replay.py - .. note:: + On the command prompt you should see (something like): - The ``--connect`` parameter above connects to SITL on udp port 127.0.0.1:14550, while - ``--mission_id`` specifies we're replaying mission 101. Both of these are the default - values for the parameters, and may be omitted. - + .. code:: bash + + Generating waypoints from tlog... + Generated 96 waypoints from tlog + Starting copter simulator (SITL) + SITL already Downloaded. + Connecting to vehicle on: tcp:127.0.0.1:5760 + >>> APM:Copter V3.3 (d6053245) + >>> Frame: QUAD + >>> Calibrating barometer + >>> Initialising APM... + >>> barometer calibration complete + >>> GROUND START + Uploading 96 waypoints to vehicle... + Arm and Takeoff + Waiting for vehicle to initialise... + >>> flight plan received + Waiting for arming... + ... + Waiting for arming... + >>> ARMING MOTORS + >>> GROUND START + Waiting for arming... + >>> Initialising APM... + Waiting for arming... + >>> ARMING MOTORS + Taking off! + Altitude: 0.010000 < 28.500000 + Altitude: 0.020000 < 28.500000 + ... + Altitude: 26.150000 < 28.500000 + Altitude: 28.170000 < 28.500000 + Reached target altitude of ~30.000000 + Starting mission + Distance to waypoint (1): 6.31671220061 + Distance to waypoint (1): 5.54023406731 + >>> Reached Command #1 + Distance to waypoint (2): 4.05805003875 + ... + Distance to waypoint (2): 4.66600036548 + >>> Reached Command #2 + Distance to waypoint (3): 1.49371523482 + Distance to waypoint (3): 0.13542601646 + Distance to waypoint (3): 0.708432959397 + >>> Reached Command #3 + Distance to waypoint (4): 3.29161427437 + Distance to waypoint (4): 3.63454331996 + Distance to waypoint (4): 2.89070828637 + >>> Reached Command #4 + Distance to waypoint (5): 0.955857968149 + >>> Reached Command #5 + >>> Reached Command #6 + >>> Reached Command #7 + ... + >>> Reached Command #42 + Distance to waypoint (42): 7.6983209285 + ... + Distance to waypoint (43): 6.05247510021 + >>> Reached Command #43 + Distance to waypoint (43): 4.80180763387 + >>> Reached Command #44 + Distance to waypoint (44): 3.89880557617 + ... + Distance to waypoint (45): 11.0865559753 + >>> Reached Command #45 + Distance to waypoint (46): 9.45419808223 + ... + Distance to waypoint (46): 13.2676499949 + Return to launch + Close vehicle object + Completed... + + .. tip:: + + It is more interesting to watch the example run on a map than the console. The topic :ref:`viewing_uav_on_map` + explains how to set up *Mission Planner* to view a vehicle running on the simulator (SITL). -.. tip:: - - It is more interesting to watch the example above on a map than the console. The topic :ref:`viewing_uav_on_map` - explains how to set up *Mission Planner* to view a vehicle running on the simulator (SITL). +#. You can run the example against a specific connection (simulated or otherwise) by passing the :ref:`connection string ` for your vehicle in the ``--connect`` parameter. -On the command prompt you should see (something like): + For example, to connect to SITL running on UDP port 14550 on your local computer: -.. code-block:: bash - - Connecting to vehicle on: 127.0.0.1:14550 - >>> APM:Copter V3.3 (d6053245) - >>> Frame: QUAD - JSON downloaded... - Generating 95 waypoints from replay... - Close vehicle object - Completed... + .. code-block:: bash + python simple_goto.py --connect 127.0.0.1:14550 + + How it works ============ -The example requests the web server for representative points from the flight, parses the JSON response -and uses that data to generate 100 waypoints. These are then sent to the vehicle. +The example parses the **flight.tlog** file for position information. It then selects about 100 +points that are evenly spread across the log and uploads them as a mission. +For safety reasons, the altitude for the waypoints is set to 30 meters (irrespective of the recorded height). Getting the points ------------------ -The following simple function asks for the droneshare flight data: +The following simple function parses the tlog for points and then +returns 100 evenly points from the collected set. .. code:: python - def download_messages(mission_id, max_freq = 1.0): - """Download a public mission from droneshare (as JSON)""" - f = urllib.urlopen("%s/api/v1/mission/%s/messages.json?max_freq=%s&api_key=%s" % (api_server, mission_id, max_freq, api_key)) - j = json.load(f, object_hook=_decode_dict) - f.close() - return j - -Some comments: + def position_messages_from_tlog(filename): + """ + Given telemetry log, get a series of waypoints approximating the previous flight + """ + # Pull out just the global position msgs + messages = [] + mlog = mavutil.mavlink_connection(filename) + while True: + try: + m = mlog.recv_match(type=['GLOBAL_POSITION_INT']) + if m is None: + break + except Exception: + break + # ignore we get where there is no fix: + if m.lat == 0: + continue + messages.append(m) + + # Shrink the # of pts to be lower than the max # of wpts allowed by vehicle + num_points = len(messages) + max_points = 99 + if num_points > max_points: + step = int(math.ceil((float(num_points) / max_points))) + shorter = [messages[i] for i in xrange(0, num_points, step)] + messages = shorter + return messages -* ``max_freq`` is used to throttle the messages found in the raw flight data to a lower message rate -* ``_decode_dict`` is a utility function found on stack overflow which extracts usable strings from unicode encoded JSON (see `flight_replay.py `_ for its implementation). Setting the new waypoints diff --git a/docs/examples/flight_replay_example.png b/docs/examples/flight_replay_example.png index 5464c7ec8104fbaa05f9bfebb64d103028379461..51a605a5bd5bc9f06a55fef216a181b5892fe241 100644 GIT binary patch literal 168903 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 z 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 z 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�ma3q&`?5Fn+|1E(A?El-^%`czq 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

`^()M8$V6l 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

v;dol!JtXfTLv=#>b@^c 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�W!j$@Av1hrlYUS~d<6p2gb_l%x zcb;o)SYq6!q5Mz{@RD^@9`uvR6PjvGFHD=x5m*o7HHyoooE2;lx}N4SwOrVrjVFs{i08Yd(!oi#E-n*kn?=a$ZI;kgCP2yguCjv zoWVKcXP?u{V4a`)z+J@H>r@pkrhmo7) zO(p$2OX~lVSQzqZ0>LduHJIwnHw$bIZ(fWD|Lw3ncDS%j_Cyv$PTr6u307Oas9sd{ z>^cV38&p#{bcYC6S8ijc^Il2wf^a>0;pF?${J@3 z6xjKS8Koqd={1I=2Bh@kawfJ&Eu>~%tg$eR?Q;7o$&9gJvs%8Gotv^<@_Slr)FdF# z!2EKgcMViQ(P2A#849hhLu>yUB>8Mf+Et}|$~MTh$jw#_Nl2I^p`4_P(NvHW0?`l^ z#Bfz7SIh3OK&V6asei@++Uvf|*8|-pCO+?T_%E#czEI?)`x!ruEcODw5}U-tZA<8_AJjx+7T7U4m+G**vTTLS7lJLzSn-|k zXW7;RyYF+%?y%V)GyBAd#l=aHhKbBz6OeiitKS*{fkTpz#i^+c-SQH)-W4DaAZzuq zq@pH3)7#_vI`8STkBgtZ+bzn;b6-WZAHl4el+Gv-gu$|y%Lza__}EAg^ra{!%Ahnk z*eSej?Aa8w3iXMbUY#4kfY3d`|8!I`vWDd zd;`9maw@ng6g8i)VXkTOii1kef8S=oDB!5=iX1qIZ2gSLVYLqKZXW#2jqLl!Cao@( zgt7%xTvpPq5I0>_Cu?0*wymw17;x~ygd$r9?>Y6d6&VJ^^WtCA4k%o zZ@(^@nw>Uf8XGJI?}O0;0t2xzem6Z!m1CD0e|N)uZxW&@9{JVw**}1slLVL{#!(eE zxH~Sn@MK%Lb?oQE6cqljOSh3bV(SDVw~BGvJ^S}MD^>QKdrm~A<{((+h3s!xr&d1R zP_Ll8^_>^?ikQDQ=B?@-!KGb^T^+4GJeohJ%zyLM#H}aW{&ro?C^$!Y)aI9qo(n^2 z2j0wTU|umYb3-1=+vwD3=aD>+;BQBa{vMSUoHfFKckk6OvYcdKS$_lBHFES2@7R1F zkPdCxYxhBt;xZ1M!Z|Kd#>38wU#y5I%&;6N0C*3z)@c^mfzqkmXzI&_@@T>YeLxD|( z&b3awtwT${nffCNOe~89$<}yPC1mmUg~1WsUq_XdgfvM}(0!gf)sBr z@E}nHat4d`qOfqwa89+(_nTL(O)EystTbc=e-+*ivonT*XkKWn%Q71k>^MBQ9fAzU zz2-{9MBuzQ{)4uD)>RM(*9#_v1clZxsW|Y?!+IjaQ}$B3$4g*c%~m&JIpLQOlGYc` zB)cU2uqW)@FEBno=Y=ZoBNb`M+oU>Okt}lPveq*&gboPGR!x!eGMMGl6Js?SbL3o2 z>6aDo#^nC;rb$uxWPT={b+uDqB5P!WJi|MT$($5f*J|mi*e`#m+ozx(`b{<&zrcbk z8jsyl+0K{%EpdWmSqptxffp6Ck&-D#e*1jEPaTi8fw3`jJrR$Yp?E5k8)Cji?%+r! zS(GZ(#gdjoN=~`Jla5MLK$v-XdD-OYppD>E~R9Q@djKEZ-zw8mIZ2?F#H2xD6be+}8c)BzktS%oqQK69()%-_P6 z+<4iE)z$B+8e3nyMh*S47VfmH=LPr3RC&ZO6jrQQ^;&?yTK0U|O#^;j)RRwHkAEH6 z{2`mPJ_*{v*m3?eCp2B6ey0_@oxo@(s9u#^$ev-GUc7o@k)( zd8or^-464almV)Bp10KpMOU#T6ZfeR&yFXD(n^uDlp4X<^3R{_F%1~xKP|jMN|90r zt7JqJ`3q~4L~!mOa|r*0+h3e!U!niwjI&a(p)JqRXjR<;8M7-n#tKpGj@_N_gMRU(h&Al0vhwR%S_p%jyR2(WCctUw$Z|~>h;W2kQ z*{GEaexc*~JH7Wth9JtHWch>7Yjr$1DmizK$Ib`8YKAwrbZX=z0l3zIWYRZlXOm-3 z?x+0VD4+_V3RV|6{qV&gEIKfB`uR0^_qQqmj?Z?&rWm#s(D<9Xua~+%4+j%NprEBw zZB#n1ryJ+>8)|8hCl2Opub>qV7U!j)`S$n!rmZ7+8T5p>tQ6XVsQXI(^W9`yOzC@EU}A>NjAf# zG3RXegWUTaf$lrcyeIoI-c6yV2s(yP%UWto?lL!aRqX@jC^i*iXzb>fRj2W%QoDsA zj>lq(S6_P7i;`GC)NN;e%J>-*pOfe#@weNKOW2oue0)gQkCQYwaPOsNrxQR$YgI2t+paD`5i~cY=K~lcNrh<| zKbMoVZeN78$73dIB!i`cf3{BnRD4v)AN@2IW1s!W>(u}myazaJ%%y>`>d1Wv-rHKK z1hin1e+b?2GApyl;Pc2a%E<|pD)bYE0y6-74Lm94=2)U~ti4@58RjaT3IGdga8OcG z;`V;!Cubn_7#^Wr(ziQZg3-E1PT-c;xH1D=kC&B*L6|Q?%%Il}p@l4IkiQ!JsRJ}A zC7H-lECo2`x$0o42pt8esHHh+xVCtl#UK_9s=`FgMoIFbxM|Bj1%*vPeg=m``u~-m z;|=neXO0<%S@S!#A_gZtVV9sF(eCH{ZZEiLv1Xa-ikmU?W&BUpyw=)o7i*|cX*P;f z?g--N_9po&4|c{bFO813vsWoYp#G)$$CGNr_wKt<>DGw*A9Nj8M4QV~zgA(bL>I0{ zM}4B6cwdx3<8GY|X{3vKPFX^Pq*3g-Pwwo5O~1`BJ!xsY><43x;tRZW!3a~ z$wMr!`)((zrgP_Ym3E^6g8_GNk+SGbnB~U0ps`5OV z=MoZH&|)i@wt>|g109VQbG!>P2vlaPuC$inYi`^)V7D@xtU_W`f#gws(zD zg+H5e%f|T{Al3`PIho{!cG_vCQK#SIziz5Ng3d>G1oyF{=~mlOHg@f2)zJb;PbkDM zS8&^fs|>1+S8M5Fkl7O_{q}3b5Vhjo7lzfwQ^3fme$xB4=lg%aj{jJk|FN)lcXt7Z zPzK3o}J7(t2bkN0bHeqYV`-+9A9$~?g(=YcMu8DjMY`5 zk9vA}wRCoN*4Gn&)O~#XL~#1-`R(*m3mm9+=ZBE}8zj9ZK66u2QnnhslTTEDeDdlB z63ffPQ*F`uVmn{{{`h&o8Rz%Ul&(s%jn$tl-{cjrAOQ2$rIqco{ch%kE2FZz{;11_ z;5)(>26jUp5WQbvX38D0Gt9nfQ}&@>HbuFxsp($i=cmjV^cd;Wgv!hP*>(wM1w3Iu z+Mcy_=|NlU)@g{@GbUD9MJD-OHsGwL=?C_l@7IUu`NeLc|A{|SEtQp&VpLT)9fu+# zLct1(%De^1oN{)fY#=~O`cos*HFw;KCnKgH`Yi<0JVqb%x{SD__{Me9g)vW!fR&HA zStFw|O9ATl;^MINV@dWAdT!4^lHqz41PK&CQL_Kh{G! z9A{MXbih=T{@N*S6IGHrxykqhaA$X34T<}F8ZVkANRlf5F<&2ixA?BX)6it3mOWat z(AFp%j%pUz=TZFNPw|~3b3%QC%p&|6KU~Z@nJ2S9Au(73U-p|tZQ9?qZAe`B=b-Ae z%6hi9NyBXWhf&hc8KqDrb5NmVZA*7|d%Lf_y*+TqH610Xyf1@PIgDOA#EV~lS<^*Q zL#{$aq8Mc~z``RaWPt!DD-RD3@TXOsL{3&yV79zcR08BH$#YY>Y>r{-yFRN^5JkXL zVr6X|LXBDYLqD5SA!9(0L_?>%EAlPHu&XBphKwVqQ`c;bavt$Sx01Z+WwZG!%Yg-I ziRw%$&meYo7Vqxqsa;Z9-Esa>wOZd5xMSoXqNcmgQ)&*ETQ7>Jo_674H?47T?-G7i z%Zi#k9-9JLnO|`&QV&WnEn1Bxir|`l)MQTGfh0Mr)P>`lrNM35a8&NusX|` zCYmJ9%VsB-4)c~vYYbi;g0HoR!<|%dP|vhvzvQ4ToLId~3wQ&uI!)f|f^oG&y_~$) zF=XUJr*}f6W4}4~%dB#M5YAR39Rt#rt~376KbHpOFx$$?BJ~?XAJK|&#-PaQRAu}P zN=r?foV@QqGXs5mNHn2eOOihk--rOx!X9u_%0@OhZglOcsYFsks#HISJ41;-3)uJ# z1)Pfi{#CGBX$F|-3+MC+?dUfxWxVUe3`!vq1WAsz0S!GJoG!aoet=DN@&X5~57SP- z$A|MH3;Pg%bgxvwTAL%GY^eT4QO~6Pa-Fx8|4tzdh)3Ys)OULu^d`{7cwc)H^k~|c z>%3SlC02^{uwC;;C5Pu#P)X9AWoKWbtSjHna|5X}$&E*M5P=t4&{!E@r~KS-hH2ge zcZ79yLaLs$YeY{H6*=0^qecVaG1FN8JXc&#Ji7u9I^#teJua%x7RssUK@DKyQZo*3 zQ@AsmAgP5p#o6=FYSxfps@U;=!WS|MkVgA_XFy6H z-78mK#i}@ST%KnpG!@mYQ(kKpy->vuzAoxX=R8SkQW5*(e1vUZQQm5fp#(+mX2FC<9f`#0)uecML@wS<6B<8 z>U+EXJ)TN z>3p^os%pbTT^GKd>gL2^o6K0fSl!dO=|jqNsjB~pVYe_j4rW<-d2`oQRWmH0or^J| z*R%T}5Yc+`BvrN0wmCua!8vhmAH++F6T?N11}3)LOD|$>@^Hg#7ej+(agK!>Z{;g? z1t>+`n0KsN%X;nqBOX;{xCMSdhX0Vu5-u=5%DoXBZ8Hqj*Xl=h9E&LH{8M95>K}1 zpF+~TpfXJ;Gay=dLDSDuz#rpMDH7n72gvr@2$2n|EfekenE=ROc43HBBb{)g1M{@$Kf zw&2GcH|KzjsDkaQkA{QMjXi;<-vdR?Hsg^cZn{=5vN&3vnzGRE)(-bA{^i(#)I??i z_EtC$W7gfbMdFC+-KzMQqT@rJX*d8&dwvpRtnnWbA?XuQI#YYNHgpUqfjduc7Q)0c zZibR}IynNNaMA!h9c{}P`RT3G^}gm+A774|ltZN2O*p;;SW0OGFwyzz* z5|!W9t$*O11jlF}=jE!(AZc;c;WqKRV2fY57L~;?oGQ2Vc|rcg+rw2PK*0H~Z`2UnJW7Gt$93Zya5v4aB52Yg_K-u!ZgZ!9#a`y%#K`3*141BW3 zodR5aKkY*UuLJ`2OJTknwbPA0(qUY*2BVT-W}^GWs#V&D!2z|BcYg%iJK9$5Rhz6! zI)@Q=7jU1>iJ2Kxe3YO@gFkTj;-}D48zj(anLUVe@Jm%yqkN*0vhp3TQ~Qcsf6<5d zd)^k+yZf=?8eW7^^QJ+cVnQc2C7z{zs-^x|#UB z*V-4C&Tk9%S@A$ueAe#)3&a_H7IxD?fA=Jig)LpT0eo0t!g+xK9|Z-l&n{>BQ#{r# z(Eot`^slkxNP@|%qYDjAu02l{NJ7s>eBvYCJWi23*8phBo51JifXjZ1_8Zuxc*g~0 zC*pU-6C@cRtzRKrS2Ed+Oi#1fFqXgY7AFH6go){h( z)cF+W(^=Mdbcw#mUHEtLzVX;~&e?FjmpIo_I0uQ83y>AoRP0y!z;1e9|HFNvp zS0;fjE_Dlz51HELq^v}?7N9&%X;=T?$RT+lkds*dE~IY7(UheTplyIaG;_LX!a0p{ z>gc&$%!92OEN9IOog?xi7ol zqYGSKV^~?cYwKtOJ))613cG*bw&r<^Fd0JY!gDCmx5UJ5EDJlDV2V9?h$Iem4^WZ> zJch}SQ9U1ZCuDU-MiHNleJn5FkPD0)^s&720ar%emeNXA-&R;9o%*4&3q*ZwZBVjQ^eLth2IAy5Z5JUx$OxU5j`&{4#>1zE7am^S7Rn5!(|w3j zQdPyqGWFYiYt!j{0U(J1B#-ztol_EWJY~S`VHrU*$-9Pqc{=3{LH;p)6J!a}aFD7l z<(5r!nEkpps+@*7VK`SIsX>z9TfFS*`7hr<6X6Q1EZKaP3F1$}j_bB&Y~O7z#wkU*8^Gv%6og~4%iul|f%`zF#$ZuR7+l{nWxxwKn7 z%+29(l)$Es2+Q*|ojcLd)~+e#0IYlf1?ve&e&fLDd%mR#958rrdOqqF21vjUuxCW~ z{rr=+2~aHEE-kq_3iv}>`ajOYJIQ+L$O-SLCxL0Pv^fa0;t0Ron?ACtpS8V{Xef`O z#yl6Hf;t2sdXk3yJCtQK6lh<6u*;1;9-bZZgXeh4smsW8noK^N=Dc?=hn)nX7^HZO zbe@DZHuAxZNW%@%Hgf{<0PHfg|_Xjv1``5PMlM7l#g)Ya~cfMZ3x9qpLcmQI4Noatpo=b7j7JBioYJ6imiu zz8&pW&^+T4|VI97afw8Ry5uepq`5HS_3{ubx)hCC{qP z^+Tq)(T`6&EWb9JT!HXNmm`+@ z$AUvQX-1uvmg9g3L7aR4XXufz$I)u%l8~OhKF?y!viY1~`?cQ&LjO z%LCRh0;u!fmK4M>HY#4INONM-TEC>ll$K&1=@NhX zNA*+-oG6qcUZ;R4s)1`~fFr=U^PeAF7zRYq`@1=M@JA&TvH=1{mWnzF8T?PK={;is z9(@OF4Ar4#zv6(rg2GBvEV#tSg%j&egc-D2v{5c36cn@>|3+JZ*OtXldKV(`CoZy| zL7#bYVTIYxn=a%_`UsjCoQ>9t%1OLB;_vftATB52B_M-9mHgGv(9qPx&%+ZEA!bjm zOIBNCJGHsaJ`L>-adjX)L2!nVh6l>ff0=(zBg4Pz{{CR~X_O56Fzj;8cbN1b zThm;t0@}wZC3E0c;Y@Msz1N~jcCZSeiF|M94F-_}Fw2YgCb_WJhDb#B)nlbRDBIUnUa z2vCOU6`?T1{tF^yvQbaIAbBU_j6YCY-=tFmopuXAI3vduf=ScAMTBpcuTwJ_0U~N4kPn_P`l}lZH926v$CH9zRcTE&OckI91{Lt%bVo-f{2Mia^>P=ri z1NmOk1Wy=Ev&T6k1he~2Fs0h3ArAkGnJvhc>+4iiSi01c{x#tXacIkW7*^NzSX@FF zsc04%9_IH6xnJ^5cUygT`WUaC@z#Ez?8D_*K9Y~(yplC=Qkgv3y+r>x71>G|8#&D3 zzm8q1`bOOQGX3jzT;$+q_RvDQ7G%2&vanA<|2maG)bTGGQK)%-S%5ANBhH3s@ngp> z%x7d_LEIT|jK|B}W~V_RP+EvB1Bb2l)5QXY-dgI=H<;q(N zO5{d$>~q2sc(0Aqowrq^dafwtGGS1J5yBSLYtsBMed2$@@ig^-x9%BubMwY)?Hdr7 z=#TM=LNE~Vh#`L4BQgAp$O{OhkR784PpB@hV?!oVVCldu4Rl@{^AaW^G4XYRO*QN_!+`x@wMKg5|gjZP`k>H5_tuH_e0!vj z+2`?Wh=iEfZ-GD0^Xl3-w?TZTAQn5_TNDoUriWTFutVzRxZ9m$Q0X)Pu)8-uDK-IE z4U?7&KY-v)`vX`G*wfu)9T6|mQV$omw0T~U=d!>)H_)SjV9(Z*xmBfHcV-b08IeFv zAxhAXayCU4t)i9l)U}{XKKp1+;gbN^o?BavyOS(1HXxK;gC$`ibw>3#-6c?eHrwHh zA~kdOw)}Ag#E?aaL??b;iaY95sae|7gKyB!$vsrE@I3G}#B&LpC}UDAJ?7UB3fVQh zEc`26%QXeq+`;El2&$aW?%Q3I57uwKJSOp2ahW`}wga^i-(7Vdsi43Q(iQ|$69$IQ z`q4_*Gq=!_)0^vmUci0z=knMjRr$(;;B1V3jBemV>b{I|63h-4~}w@Ip{wzkLTkzZWbauxv;ZNkkoS2qfZ zUMeADFvD2yXhslMgPA8+7@6A+4oNcJR z>S(AIV_$Cw9wS%Nhu(=D7+S2g_W!&QFpi1U057#3hv$4IKvumV|tKyn7U||5=N4080!tw!< zZCzbmOAF@V>)3FP??R$N8SuOFDZrQ^PXYI448!TmXRT=9^Pg>7OTa~9X_15%!abS2 z{F{#NMamB_#)2?8{GdF61NCnL;&U6$B))?F{7#wEh~kWjsl^p_V=iNmRquG*=J+pg z2=`6L9+1!I6ma4BM%2a2!Ce;9d9(*5I$BXNI@;hs@I{D(&_PVClsy~O5S45Ml!Sv4 z2`K@v6NZ|hS2<)C!{HpLk_}F<0D2i39U%G#4rekLr^fv8eYmOA2kHcbT?t~ZTZnK_ zPS)A`_!zKUo%Z3gh(syk6z-_UL7z;T_r-BG|y>~-H zJ+$Ibvjq1!)e+!IU%z@N&alY!P zhxuXUIexDZC8yZ6%*)`9rm^M@Sa^Y6ePi7oaQjh##ld8P$gD; zz4g2rP1h%?1~V-TCVd}>{{cXs{>}fXl9S`4Jh}WZDBzB85 z_^GOX&hVt+wR^GxwaUc!i+*epVi2dwv`M!q;r7@v1t_z8{~8#Df)cA)X)H;@8|f!5 z3fV@1!(_Njo`_i$!@@)31^lsB8yrb5pO%(3LQ92%o}{U1sg7zc!o@`v-t!oS?VZbK z@RCJFpGcvs#rdiZHfkDlEDshaXzb&l&lRY#w_}BQ@wJtd~yB&pi|PsPe+0N=Ms?BKK*cWBJ6)Z=6~}vT!YxJS$W!M zx4rVISa6%W_7U~aQ9$cU?nN*C!t-zU{U|5(9Vk??JfF=S9QMR^;?e$aLlt4mXQsPz zm%(FQ$ejMAxq|khQ9ifrB~%-`hHFrAQ83jCh_onTo-(MZth9%98MCydQuER_&hib4` zc0-Rm+QxnQE--p|bF#7wTYmk3>r)Ih^70KPTT04kV8Z3HD5ZB|$*=I`A%%j&^*9md zh3Od?2^x6+2KtT)Pajkf2Os*Nxp+scf`2vJ(H*JN5Kq`lZ`!Q=z10Gz@75$#Cx}7R zjQsY^Twg)I9!EVtQ~3>dVmuFbKSojoZ2hU-H|%D!js_|{hk(h2|NZi8VXF&hmac&l zh$xmiSJp$6r8OD9#yG$f>=Zo&uIq zup)({2;inMz1Ov~-qSl3%N=rU?1*4QF$1=J2v9=hZe9VlUA62*>2Hu)Rr@ z-*KgRb2{&S>wYTC-`4}*@KZ>C3_gf7GGmww)HIj~7K1v(oXw?oy(*jx=Duk8+{q>P zSKC8ixz`nQGWhJ`Goh?arj;zD5#2)ylk5Jik(jgzY+JqC`RiTI=rcUMs?nSjP2uW3 z#IZR`rZ&m~RLvky7*0Y=GFlh2*|K!xke7w>KQw)XTa)ek_vjJAD5aEvLsF$vq(+Pe z$WUkcF8{9iH{) z!3v<@%=J1?oP{)%kJ~9-`47~YZ453;!-uLz|8HQ!O6@cU5mjArVh>u~3;X<_UHC8Q zWGnyExmRoZWn}x8aQ0Uv+)*B){;nSG-_5t*l=_IAo;deHu;W}RS=cwlrE}v=)V9Ar z6-j=a^7c6HQ>L)%j+OtpmH(;i!}Q_pkYlk;tCosEA%eB|EUmU!1XXtC)vBvfQQu3; z+y3b4;!GPey^}N!3V@~%c+`jEY98Qh=A@?Kpd|i04zw)Z*?2HA<|9& zfilKchjY`8T!Ne_gkSh1TTo*MYCpIM0}+G5Swp~)bO54Ffxx}Z%|;*^!|fA&ir4k^ z{9ZOI`_1l03n*jYT4t@50xRh^j($TcCDcoNUrH``B6c?w6dy#a3MOT$=T*Ykj(76n zvFQr?^w#j~g}*c1jZ(xvBLNphIxNs~k=l-Ieq#?|l8%v)k%56df5uxuQg9dQ093vx zfN|Zt_v@bF{fgo~)_2*J~+%%v(7KCj*CsDY$ z1uv)9{a1Ghg?Ip57mOLs@}>hd9L~*WXE!9_f=IEMW1g8bEIfKeMevx8@%oi{L!12% zUa{K5QNi6P1AW8Naa##U0Rkx5WPWeJ2r>?S?X%rae?2eu+5bb$SxiFZ>l6S8LtXd+ ztL(Y2*yXC&_;tMs&W(45(Yvg2tDNj}T)R)L2eS{K7Jd9*BG5;zVi)wM?e_^w;)lRC zHR^R!awaxq>EKOnP*>g1aZQDygE+=$%GhO7?o}{NVQh@kBWm;i@2f!Ucq_| zzyJk3f@0-kVS`u;-9zYxv9f-IK*wDZb zs3G{e7u9fczK?2{4e(g&HDR2oN2z4OK*qjYq;RYK+uPfn9oxoP-%diqKX&|`%wgy$ zAsFBd3IJcX4r#Z&XNfRnY}((@D@ZJ$fL=^a4CjdHZFtt|s>GXnZ7ONkKDo96Fg@H? zJ~ST=w{u!TUfM0==k9P`$a_pb;MUJ;pEjY${XTx`pzdM!)20*#2MHp)Tc3e}C!e1< zAXt5jr?&kzkYr$Z_+g3Ueo0AS{=>>od`rL1eRn}rI2gO~bycRIvm*3xv3*g431pXS z7Ci~fjj`c!+MxyU+#Y)aX<8`L#mvkTqM=A1f!0B- z%l&0t|JC(!fzOX6tt(o6o3yWhw}e)i>-Fh&9t*(mZ9e%a&uXb0|5G;9XfsYf<7if! z{vXl;o~)iM-PYFTP#T1WJ)#Vk1S6I*vEnUs2`GW|c9s%d)KeqNG&kqV{pTkf{Y~?) zcqVtxkQMw6OW%SokFKCgE7EJBT+{(25ht6&leT>Rnl*g!w=wuw;ucYfque0zT2bAy z@p3b>sKh`QWj%6ij9KRL>I;}SZqLB^+;Tm@V${>L$NXZx=kAcf?Cul>NAvph@kYeo@IeN zt8buMGs{&w0Bc0CS|nQ_;;HV;?INQ;e~3K;6d*?ad#nDBK!=ybizhqUz6q|kX~VwT zV!mr6wQul1rD<98S0eICz~WWb?s{^*ctr1ZYzy0nC+X);+gdGzQDIbOq<@qy7#sA_F z4*kvFVjglh*~00|*JQttqDsL8em58QC%Z=Ohjt=ym6Bfv1~QJfVPWTi0NWcxD6O^z zU^UKkVJ2G&A>K6Y5X`yIn}4-4M=$lUE}LbjLjByUSP1Zf(6{o~bKQ2FP2M+rqxG~8 zdLFiKbT6aD88kOya8y2_^1(ZvhgW@xPZu zUmCR&G1xUbN6e*R@{pINUQ}Swv%=e!5Fl}CKbGzK5a-+2o4u#q$%6DSGjApf6EsY+E0ibPX50cJ1Z5tnH(P&bRUt5)z`3zk!)(AQWjA9QU5c z_{;UPhqX40b@Nr0baXdL|Mia(2OkUFYx=vx-LodhN_EdOa!FpA=o*f~#8m<}Ba+HT z!(E4opH9lqTbX>_R0jAAkPac{@D?sUVs_0)mKfW58vJblR$~Z0VZiVDwHg+V4Roh- zQ4!TmwAl`&#>8X{P{{0`^|+K&$C3yR=ZIt!Z9AcU=)zCk;1e`(CxAczGHO2xR!sKL z;)$<$tl4~!?th0Z$rdq}^TA(ZVh5@^q{|R4cloTWl)FEYqaO`}T-!@9!5E&4P+}|7 zGDt&$qqRhaBhSu=@u`_vL6fx6maPki7b5eo@JYQM+*Dk;BSQn3H)-v=IN!&tvb>6X zPd8}jcG^b8FC47eH|yAX_447;b@8m*8wgj#2Mv7no*Z&~XwdfWFEhM)?RU(a{OW@; zohOIibVTZxh_IPm|F4VpjUN{uS{>WgH}0~OFP~5?08t&6*Fz=2tpKFus9p2jO zYD6t`(Wwre^MpAes#Bk#_j3`LI`owNxB zHU`EuJ0WRn%!us51XX^$l$xfdZt?_@ks=7>L{1nEI?AKon|>_i2$84uEI%`64L0MC z$*+6WRlwV_K$~f#L%bp*itmt)D(Di<|0rnhI6Ik|iNVMS8Db(cmg2xMeJB1T!wXB4-B-SRYU%-mz&J5Kmtq_(ECB!^Q_9vZk~U%cABeF4KzpxD6D$(_A#WBWWH zd<0APi~^{N(;qW%hly&R_|0x7yGX+TLS4_$;P9+g&#^VB0Lm1%d>L*Q?PVZux_Op7 z5JUP;J#ES&D?;UROaS*yRXq#AYnfjrJ=IkX`_Emfw4M^-s!@2lZ2>02(^Fp3r=ngI zpq;ZasKs}!8Ao$VNk&Xmg&BKDRNm*sU3>| zxR(tqD9Z!-HcO-OIaPntRFrY6MnJF`FfmSgXT1~k=jKR2pwEfIzSkO5*k~5~tomLK zFdZhDkR_`W1H57+DxbHq5M5AzPGDwMkwT5CsN&R@06h*$AKX}3$)kt|7pit!zZN($ ztoP%B%gH6CNb^$xCFQDprM+SFJ<73g$=z}n{-`_v)|J=pc!mEQlq{jDK(;w|eeI>D zWfOlLEW~(4QR6}!NGbu|_QmL-zI5)oLLfQcVA8Y4Y`%&&b+-8~&}(=U^dwa6!(^o4 zEi?UP^U>^3?{v$3(Fxj`KCNkesZ+Gs&1Xr#ulOXry`p_PleYI)PV;V9+sV_1Rg%{I zg-M@&S+V=c3inLxfHRUq|FK=eXgTy+2Q@0HzE)(zHX4ak$@eN>0Wl#z(6A{Kef4bL zS{HtfuSO${fc!Mc*VR^An%b79U8PdRFEn3@O^R11Kq+NEkyZnfwQ1oHf3(kue%5p+ zdNWCc>GdFS9uxR;NmMof7RxIRv_;<^Rg+VU+YYi4{J`>d!>NQUMR6rnC-BT_K;%qA zK7+Aqsz^5}{|##O*Hj#HzvlTMPKFbYr4Yp;4y7(G%i~p+Wh&5xcAirbJtTbWdGu2@08N7Y7RqCPZFg;ja=mJ)C$sPzT`MjE8m5{cf3u%g z_c&quou~!6I-h%0nnWCA4wsRvnYg!Ha{=KRb|reA z_+d|bFV3YucT+cFH@BsY8#1KU{oPHS&`+x#Zkxnpn6dPJTe0zs#2-0hvB3lRHB2cB zInF0Fw|O~j%j%1qD}r*YJ!}pnIU-NrXQzePXj0L{4-O1m78`tXGUK zj}pFQJMNPogTA(S1VTEip-`ueWFI1IV>Z&1sG@3m$kO6S%^XAh?rR*c{Fv=L?|k9VA3Ysw}(&iyhK@KX?hIorPsrG-xz_xuawN}BhJQ?IQmyPHB8Vj zy|WjXaS&|PjgK`0#lqOgm>@(O!edGS}*+CN^;Qc&ezuECzICZ%<#>1_ty9C!G9%9<7;3z$K&R|E5mU zWIehrDxK1mWCXc&Gq;+|odfM=P!Iwxp;7qxw?+}SBtao2u2T$#I8mDSk3qCE$thl1 zyrkT6xrtQ>RN^Nnd4wTWwcg8s4F@!XZ0A|Y5V+?i;Lg4zIGSbgbNT6iaM>cqP{B71 zZImI$_kW6DYGD%ki8?H4etUyRe zUct|bBOa(hz8`*dMTpckp}>>Z)TG3f2iM4?Sg;mgQ_X~aH2S@o5JQg5(qE%n_QaxZ zz=V$4O%k_zrrv=Bd_n&$90UDx=lFQ%_wf@k*E-JdWIQKJn2G*nm*mNKP(E~`puUaO{ZEb4=IKstfwfH^FL5(d@Nn;Z*I*K_;dF= z8CM~VQQpm5M^IxRh`kJN9UAfch0~C`NFP*g%&U3+_wT?(g(SIn7%2fvvKJRiQe2W6 z%%G|EIB5bAFWAWC0g6q_*$Or)(Dsr^>BH>}TQsG@%RNzd`uW?WVq}2G=bDhD_56`z z+Eha$pU_LN@-va^qvuAxKKK8$YPm+_A{VaBd0yg)qUuJP%1eQ&^Ea=LTR7OMZrbcdV{&4V;8No!71&V8#C#w9vGXT8OHH%TMVVl`bvKIZ!}qhL^}DaShhHg24D9V7 zy{{*dJZf8OSW0W=G~Sw(J>(2it=)yYu_NLQ8)vuO5?BcGsN{(AKfv7@Cb!`x;4LjJ zZA+_-IxZ6mX%ml?pW#q&7mMW2zHkKVI-tg^sE_uVr+Quhhg(spK@gxiEdjj>x7zPt zze0nz&b(x_quprfupB}bfkSqJJ*jYcSEnkuEzfMDRAOx5TEP;5BqNmkKsO#Q{@bs; zsw^H%t%|bGk|IO%%75+n^Zk*DV!&zO{Z~qDIzLDA%dqAGA}~}=aJO4V>mH>G2=ZRO ztkOXNMM;m<2~sOY!bs>H{?Y;pQdTs$vs%T=4j-qAKa@gZ^Y)cuJS>|Q&`K~B`s`Kr z)No{^rBM^%-p_@Y2x{#hQDvpartOiLIkMkyHzQkH^|Qx!T~Ug<$qJE#5|Aj@P|i9r zb4k+xnS564=#%p{s(6jx!m^T35J{wEE?-gawQjNyE{x0E7=%d%)$Ku>zf94@Q8b|- zWMI#av+lLPIMq%gNur6i%zn~(4_H0C%Ddrbk$@++h0LWMlv1-;f14Qmp!E=MY^7aRbS4n9%l`$boA6C5**Ub zN4j|MzqSp{SwlNBwqzmlV1h)Vpl~geg?-^@k~$d}lKTbFs%k(y@aCi6{fGhue?xfr zlR8U7YFwhIuq6tk&BWvT``P7=8)gr`cFPsk_#KXzeR}rBX^GtbTGw^B#oBSoJhai3 z(`nkOX!*zDt(oJ^0jH`O#inNo=9zZR9Jt+ot*4DdisiIJyd-x(sa;@;s8qs)04qIQ zEmu`C7~T8094jmvH^6#|W>+}N)rttgP>3yoj=|0g=Cy^Ju!YpjP)ZwWQs!v}8aI5D z_|#bf<((kygGQD9hLH47GkB?AIMETkW@;oI_EB1Hq-WgHqz#Z-5s8-~Ev`TKoNA;i z=6v4OAc{x)R4A^XUc{k&Jv(Kg+Hv#XVCGoL=yFer#P46>YrnWk0!fJAfGrYL&ew4S zUn^klmcz%9>{U;($gZw+rg-7Jwn=Yf_8Kh7P~ch~jbqMKcrn=aP5rd+;>+OdnD$>G zy>Hx6cQ0fcaak>@CTS2WX6DYHf|lG}hBJl8JwM3=3&yMn3OTR9vo|ZW6y)&-fNZ4wPlhFqMC|6(hTz=rZq4tf;^&0o1Rs(V@P(^!bG&j+Ao<=@2MhYD*lZ0fj|PUkA76Y0C*AyGH=*eI?#4^ z^N|zAAiTR={w(i%lW4p?p_hSm@lk*co&xPur|Ap{lYmO2I>utIxx$* zZFauAyKZbzcTt;Z(f)wD-VrqMMS>d#iUt40^7JE@T{#bERoHe2Bla^iR*g*8?B=7N z1skgb?(bZ7MOHgFT)t10l~PWkOSsIQ2>^r!j!ijxyI6?3{#dii*%2F&ZgVU3So+`h z%k=Veuw?hdmEyly&j{An--ivBR6P@`V9m^&FIl0%^jR^Z7j-_JS`H(5I@NsAym0yS z6W#T31s(}R#Ju_H)HC@4xE^2d=Lq`nd%X>@lJ=YrUR=cj9qI&1d1E@Yn8Y9R)%g-? zlcGHknsJ;&tqO&7%Bd;C(s~|kf!Ne$U>0x^w6yM3WDUoOOa*Rmhca$pt);#FytRmk zK;zdsqJe13F=R$T3E##*8jnppTrC)cKxU+->geg|>F8M3Bh^{0!e&?QYo~;awInzN z1VpwjD(YJe{ek(&&Edvnj`V+{8<|7ukzV}qfMN*@6ea-z0~(AXHa+sUpXMk8`IR37c#I8+Uf0$Q&zx_S%dHM?F(_!+Wuf`vkpKa2Tsu?LCUu(~ z7$9SVY%zC-KlF-9%J|`O`9bPmK~RI> zn5ZT)G2*J}+bBuaxCFCcGt6=iM@S5B$;%`13k$S`Fl)?`+5UEOxNd&0}HhFCCSUTOa>hkBmm63tTvoX4c+(deV4`2osAjzq;@F z=V`Lpv|Bb|EfGvKge**SMM6nOHueNC6(poET87 zEVTYh>zSW9p`zS?$>8RYbGPB>wLKz6pLs<{y0CC&b98TX zP};`(V`zW2Ru*gu3+oQ@UP{QJ4qIG2ozcS;uI&=Ed8(@*9EBsd`$wmoh!!t>1e1%5 zfs~9>uqWB~m}*2QUy@oTx4LP}=+H_OLN|_?E7g-sY7Wh3A;A2#1c-3H)Qrl9NTMC8 z4$Bo*5`DXSQ$|z!pOqpRb}{o0F`(_djEq8_`QSOSNOdZ)rY#9}_1gomm@^LAO?WG2QMmj&PG zS2KvYt`o?R&S8;F7G+Qn%ZDLgbKI03$<91Vv8i47n`Ef3Pw?@pR@Lj*uQ9~)r|Y_T z^(q*L0g_4uUhkFlG)(QULp|^u-ro8&&udA5&H6zqa}rKNq~U!fHsU*vyySQrDg7Kx z2#24{aV`sR%IAdF#6SuqC9tu}Q0$s&zf4&2!6D@W8ETM$VI$6NOewlwl3=sC$vCOJoSJV$XT32XmX-BWl9<~sII#N47`vXT9hL|BAG!e3R=0N$z zBF2u;NW_P6lKthKZC|t7l>r%}y8JI^{j%|RnC|~RKnt^@8U>)sv*)GBX5Hz(GW6cK zy8M_~D_=66#Kic1=+D>DsSWswOsZ8h*90g&o*;nkd7RS_P;ZM<^Rh-_;t-i10);M9 zb^rB((~Xl-5p4K!ahhfE$C?k) z!b&>=*&G}Cn6sT#VZ(*uQnnhu_QO?b6fa0ldIHH*;8HniIp7J|G1NnlpP4zn?un zJb!~5UXKrx$kQ1YtI6RvM?FSw&yR3$af5#JD8Icu`UhMfp$`X?#B3jBu+bRY$kiyz z{SHA+aYf8Ktj@zbAvGMnjcH z9sD6*I%q8MatTWFSR&t4Fo72ajd^637+?Khx;xU1ik~z38XLdZF}O$z=6=^ zxY;M)_1=Gue&b@MdQZjPn_t9Cj}X&ft6iU{F6^yl@Nx5+ zrSXU(h~Ea?lKT-xkoUE=O?c~K7YGl*EU;{TiaRnoT4Rv``*(aS|5>9#3+w0k&!0QM zbTxzIrvm<7IrF;g*#=;{_>YYoZF)V_HP9wk;i3gzW)I-c7%VB-{#6)a?;?`Dn+@## z4Nk63KY|z4du#rxQ3b1|TKM9=@;DOU023-@mErQriloBFlJbRh zd@&V}E@6c&fzmL1s$gg0Tlw0>3>Wg0^8gERMoR3M@3XsBx($vGft<=6RGV`n`Lc=X zvkk-NH@@M)OU7Fn!ULv674I6I&X!hr+mXkbqAj#W04di;n30zc1^>@>otl#aM2Y~1 z%|k!?u8n`y2%=>{Ege_SAD*vVECov>n6q4U{~(pij>)A!NnxR>B^&{?xJD;Qbi{-} zv0p`U4C6Mj;fu!_i(3ku>xGU8|Ip1ZfWT!?#!s*@7}h)wZZsfqP!PxstcVUUuJ~se zMx+W{L%ivaK+2=(vA?UUh&knP9A7nE|2;~=DNmB*6k%wQXm%UY(oA}EjlH+OBE##Q zqd*Z8)^a^4$R5H-1>n86?&R5b>Wq6vc0h#S?gl}y+?rZhBHRyW9zi=Ktn4l9 zUF+4V$eli$Yd)6v3>u+w8C%E_IGpu74&0fO{c&_&Im3rOK%#su((c#3OOZT#xOwgS z@9$}G#-cxRp9a)%9d^;aGx$1cH#|b4B=WZgqqt01JOY9bliXksxqh%ZRLW;+t~~h) z7@7|>#xlGec>hqPL-8@8;t)C*;JrvVEs#q#*Ly!vv*%%<$|0f!V|LccTnlS4-TcJC zs#c&=^E|vrQ68o!xdJ6!f?>ii^0@dzW%7FjCd;-LyoaVm#FRD9P#~qUzGNEEu3kOO zA?1!{miIx0%Wz}Z;d8aFE=IxRQYk0|QV0&0V^syQ1YuCJD75bHBSYna2q5^XHfB+S z6x$=cfoLv%r)WssW9>(3Hj=P{$Tja4a8KlNDMd~`lmRG|NSu0SQqz^|d;7ER;;zHU zV`ZCMMfBuU)P3G{?Wpth?T8g`Fm07sc_%A=mJD&H%a{BY58om%U`<6mbZ3;&vVx$_ zOAny{xxaka@J;9W4lJsSfPF_P?5az1jbJBIs zXM_8sq!MmD7*%JnR+l_*Cp-H*iV4@JQ?w{M(>NBTgj%cNrkTc!m)PQ?()kwA2d>Rv z)98h{sja%%85(C38xv=g8IQ-};xuawZ=X77n^$k>hR14%AE}g~v*|nc1q7{SDNGs# zsZX8-ehjL)&Jv`qP^ld}SLVDXWUEV42!83Q#RMuTgO>*lesCcM|BJy+$ z4Ijq=ZgnmAi@sTucsnT+5nsbmKQXbz(I5IF_u}4E<5>@X&%ZNlDi{lQ_V-Fa8&=yw z6(ci2#duoz>=B-;rVX4DXBl6&JNkfg+Ff~iwJwMz7{3!KLU)P-N0Hxn;4od=;L+!i zDj4Gi=;+Y~sgTiTY_974;ts~Ay?dvE0m4+C-^g^i^K0kmzaMgQa?ReX?v{W@alI9U zQ{Yy(=8wpY@iu|F2bBhdyCZPv-;jFJm)8TXZkhZ}r>#sWy2iVY0rd!j$%z+T<?JYU(=Jl~bm94vRPpmz_Uv2mi2oUuQ>5JlHAmuZ?h!B&+XW z20hp8*S7uE{qE*|=IPL+rl=%lVX=e#YN-{__YnI6D+r#hiZ2Hqpo6H!5imq0`30_G zVW>JMPp6mNf6;CtWrJ0GG}dfp?2oQ~`>lxse~JbBs6$d7WAxjYp<9Wf5!3b4n^yeP zV9Lwh*0cen`)S-_v!iR7|I*Q!Y-RI(T5*ngfPlXLrINt2ef!G!_p6Vz$S0p;cV239 zJV{tc$!z;K%$-)BlJiF)N860mC37MQ4q!eJV!;rqU^H3AW9fVj*(yOx&uN~NX1u|p ztkrmO;qQWGtE0x80aU|<&O6@P1SaQ<>n4yS((iC8x@rHbJhwzLO80YdX^Ky*j9Qt*hoj>d1!_^8fIMaNCHg(`Nek3 zV%YM%zC!8!)-^3CE=$CBN27hw2$?D%p9_*hM|-E(4XQDW4)m_=nEqxi*0*j9ICqeE zUEiOmfO^^oI1oIuQ5E!lm&=y5)ZPT9FPpfEIQngf&956dmv6N#ZU-0+9wfm51<~~~ z-iKx)?gf9k#J|YFihd$kB}Gej0LK_?Ff@OZMhZKBq*rs?dWvKL)dlIZ0_&!0tg|SP zYio1y^>oU%?Hgnj0@4e~BVznIF6i9sv<-z21Ntk&Aol^AyQ_U&j6qFTd0xtN!L3M* z5%%@tOp}XJ?uDCfyW0Y?HjaKj|Kd`4{I`I{x~%)TIR>ag@kn22(Yhg?w-#Y*r#?R9 zNq-Zy>H#6e5ITa5yqrKnsEKhG#%)Y1M&5eF@C7oeMG@i0at@AK)_$+9UYOlpw<#hg zMBAjh%~VKKP0|zD#oL;-5Xx_Rh>z^itTFP)!g1BQ!7EpUPZZ!!#p;>g6YPEwNh`Q?kOJWCqX>$x6rZd`g-!<##rPIrr5&{VK66 zVDYGAvOblk1A*B-ox6+O_chKrU)(G_+;i0Sv|j-X&-sDDw7#C`H^=R*xZR(VG(ngc zm5AUM)Ry6IpCqh=&r3DwYphcat5|wYE-wpWa-d<1WP*Z+K_{IrUvaRHz7nLzL_^fx zSkT>SR49S!_|@PL=LtU_zCiSXH>v`SolF&NfJDyBG_kmWyLhV|+AOiMmWT1oq$wy! zA3wVx&cn7Wvo}pBbptZYV5v_YiObdS4vzv>NjhTbpWchM{BrE5z1ulJdA14qJiGtc z(;-TxOQzN&`mOtU)CAjbZFQ>Gt$DcnQ&ZA(0~?-!BbmWOWm9ezK9D*`wKZoC6_nf}aB* za5d)`tinwM!Cm-4cT!-{hY*r<*H(Sr$DBP?Yc)-?+G=+0Wy*QN)+3z1I7u;v?7BL$IiA^@4Q}J(}WHTQp&Drp5n+iwK9{gnrk?bm*GSnnwp;3J*UUKAPM+C zP?9>5eK;y;#u~om)>xrbr!F7o&PRZmr(Rmgjw0Wr15ugjTqe2rgt&0t%fJik{MwBs zlO~X)AxjidA^9dP?<6hH=_2yfD5Mp;dgktR_TR)WBRFJODOn*UsY_4YzsiP}b0{To zbBxdsh3CD=gp@2981n8kElf@Qk<(4a$U}_EsA;T!ncVd}tmV}NIH0FIpWm$jJ#DB$ zib%mHa;$K^NnMtR7i>6;DsTUJnA(?(oBo4;p$J`y%Jp;nvwPO!qH7wZ-XQ@`U0%8e z=AHYEX2;gZ99_?yCu7S!pXlbk?>6|l-!B>Y9^&0kh@_l18ogTa`3GkKiHBG6M_{XU zXK_|bG0Qyd_WhI~nTwA>335^omxRHjzle+5YA210lQLE_!V@7r`*fV_7Pj=Uf7eXS z7$aP~LsEX0VM)kQV`31)F!H16*ck36L=GL?9$)i4G%sFV&}Pg!HeD6{`o8hxert?5 z+h?UW7mKhW^pfCLP|RwD zOf(tF>@ccci&Zn3$we+c*vLkb^M`wAB!+H9zEbyJKC|1PaE%>4+7%*yL#pB|=O%4B z*|DgGSAy_?Q3|T2)~s-bG+4NO>MaO{a#v`gi>36^8zlILqy4?Ln#L+cIv0+VWxIL zJnz_yhQ;^q)g!$;2}N>=Po%Sp@9sZO?yh?V7Q{j@uz0|+>hiuKC6?MEKe@)xih9(v zn9tSAL@)Mghkb9!FXsJjo({Ur&cFm6Yj05`Vsk7JGWlP-p+S;FZ=({tQtXZ_Pj6<- zyfl0CcfWzDjcsi3LHq*$eLm3%t+X2H=}GXf(TElsb`DjqAzn(T&OQ?vka*82G@zf1o+$Fx6cDqBDO=Hf@_ii7$~ zV}`Mlm%se&X0xy1Eh&viOPYY&YE0Oqhje^gP&UxiO`rK0#r`*BjF*}?Ogav0$(mPP z{&44mpOAN__8YegBSkha_KP`h-Yv~_7XF;)dEk7sdV-uR#i``z3@@#HLIEa~4ybP` zIPn?rbr%Mxs55T6c@rKSzlFw&5GuLysE4N*k)Pw`YMuMy> zCyf2?X)~oD`H4qVPy5@~;W9tWC#!W%Gl{;nZvuHy$D zp=NONd5)kV)@rQMkQWq=x#=?-9f3w#{UvVtK6;*u}-=Geau%PbcBXY)9B;Nr z?BXFM%TB2UHg?R!U7cZXhRtd&YTn)bUTv-OanE$Yg~S0GVj5zn(dyv=nUXCWz99@o zPhw<-RuYO`4Np?SNhvTRv}-H^SKSij%{&-!cSC{(g`axQ z1Azh@uZB<+EmhH4Z@;me)qSsK?drD1$G~o(7kK_P0I$JwG?l&S$G&hBXP~@%7TaT$ z*OU7*q8H66Pv`2t{q7e$PYhJ?Yro`S#R}l)ScwZxw2uC5YzVUunp)V_ar>7Z7zdw#2ILRRZi|aFzl?C^4Lc~?|@$ne;T}OnzUJQ8EkI!#A zRvg-^O7(S0g$-wm+#G4Qd)?SK7KMi{^^f!-vEqPoi=Tz4v!tl)@%tT%mn(v5)1f+P zzv!x*K!1?MHWBDm)B+X!%Wk^#F~_VDq1ELO1LHdhh`74^y60OeBDX{G{|*EG6L*U- zN)U!F6)6MKz&63Wgru^$^?U7@o{k|VNcyj?j(D73`{KS^MZIS}2BysJuV249ja4Vl zta(dI*%aOZVp4;bReL5IK$6+(f#Fr16BW`plD27U!?M+!{|>_|LxEF0py908Oe#5? zhC@N4TY{1Fv1PtyelH3DOGWeRZR_-wri-S#R!sdl=}yBsBei}b%fMMK)fZ>-eXm>; zYjW%H*3^T|Owi*p+j{}{y0bG2J9S9L^7@F`t)^0d z+6`K@luR8toFq1%a}+88x1RQ~Os{9wP7DnXV|Dyn?TO5@Zk(+ac9!p|dW_bXOC%>_ z6Ma0034Y5`0R+`^bYVgV7_c>LO>A&tb)fZ4Y_iCai3xtj0vm3s80^p1yqG_}R0cwl zMrXR~glu--U_n?7JX1D8T(T1-pz6QzFrXP5+0#NQ@+6_p%__Lg=R(HwMr<2q239gv zMx*2yN^2?+%j=i)`k{U*k^9by@1)_SBcJIWnbEg_~%K$ za#{Fuhqs=ki!MqXijmqs@@4T5WiR*_pt2!J6ZrA34EBEwz8p+?GsoK4$&K3VEP*?N zvEd06yRZ?jX}goPPH=B;5Vvp3N=r079XJq-h{L3KeBLQksoR1mAB+k(?H~C{gJWLE z$1M&i{8DOLR>Ai|(OcATf8|@AcNAvm5(TSlnk;QFWsr0+xWhc-dHZtur?)4Vc-j4f zvoRcT^f*Pkj^CEUd)hqLjwHzbRsOD3M6LhuaL$fBvMCu&S~$BWKid%;=a+>_(zmD= z)MErRRc5*T`)&7rx_t-;zqvEJqn%K;!q-$Fm2n7_+-jx9I2X2 zi6uxse5}Ny^6_g><}%7x!d$A0NKPXb}|e}`FP&y7r{$egqSXb3cAVTuJ%#klT#BDT1T(G1pwZ7MEsk7f5)Oq=hIxW zF^qL$XeyLz=Y`zweLzSZv6V;5t$A}ij#)?f*&~*GN38#9 zKGliH8#%mC$r9G2kj|ebU?7rVB2)Hy_j=dN=lh<(Ua90JWT)w1|ASds13KX7uc9(3 z0hkeE8`?4Odj_VEU&{ZHr2_i4Dsg0n=H;7)&p#AM@gOG)T>k(bS*xD^Mf!NI;-leT zEC%CAS~9HbS+(Jav2wacll%<+z!Ki@T=lX>J_C`00#U>kCLP1mgrdLCo%R5?j16-0*pW$X_NRD z!hD6V-J9m4xI?PP-|Udp&#&JmRAu^M{e0`UtA!*XC&rwD{kh4-{$?X0y`=L&Jl)>TF&YXQSopZ z9VDhZqDm+9I{ehHKKbrCEHTX}hK78-r(j8L8jD3z;Rr5PDhPH&wEaIe-{XehoGy z^^6y-3$dj1K&R8=6s>c5K_H5`wz}H2|79bDHQ|LzmQaO;mBWzE%}Uxy;Cj>ZNoGVB zBeJBlQaV6-Vq)Uqhpd>_O_rm|XkwsUe6lM-a62`!-s^S7zV@@jg9v@h$FF49jXBZ# z-&SjD%U%aSK(TUo8y)dQHio=t3ZB@B0U*-tCz+B@AIqq19`q$y$aJa@0UMd=oN}NX z$33}tjItUUNlF&*^>c8CO*}ZP<1NDOXh=jrK&*X?7Q4fims>s!riNth) zbj^$?5p>KJ#r_dG#YNUIKsUO!OO#=i1uPK&h<{GYet= zn824cqhsteu~4PvJ$IuAvwf23{iR2s4i2z5SPj9zF9Lu16UgX0BuU~Q)S8`wdAPM{ z@sN3Fl6oty9GfO!lbY#{0p}%Uh5JUu{Es}jOukZh1cQap3KYo8nVXr@(QA#hl8(0o zbqu-BWJ$CiwgSQy`?c@mH1!8{NMu>ltJX4=R*&~4HX}v&m`n&H#Z~Qac504Mtn>T? z5r8`3cJ7Axt^Tr~GAE_;_X0}<)Th{o@(lf)3jO@QQws~*=K1+I<}1>^bbI)>go4k z-;+!7;WrnzW5aJw_JAnB(?65I?JY2WTvS6xoiXs5V`8ZFuF~7@>fyS5@xu4;Q)oAm zdaACUpKS0=> z?H_guNF4keh^MZW@WpLDXlBvO?g9pVzj#=eTIgIP7>y}es0cY6VGhxq6-ucm$78Yv znQr>p)-GXTw7$6!H57MuIi5#-j`D6diqSS=PJ%??cwrzg)G3m&s5UL)R8cqtR8+d( z%qb+*JH!h@Kh}&}<68c7PIJGtyK3mIgnFuB!pSJG6{66hVHr|>8^2B#A9CB>EbT>x zYgdi@w+;(pcc&_i}Klbm5nQ$mPo9FMAcIl>J6lE(@F5{z%ex)yHWd2>Pbap>m(0OIUtkKTB zad+kd@1vWyGJAAHgeAF-o10g(%*ou<$+|VKfB*^OOlsl!I&e>s#l0DP6p!riWif_r;U+(uTr^%cTDQ4({)~mrfQTj)#9%+D-!r7M)LC z#`>L9)HR>g3Wl5w?wRO3^eHbq_%1!%z3@IqU9}XwY0z7`-DoTl_ep&|G!ZAwp<*DE zW&v47qbt1JW60UE{Z0EFih_VbzvZsDIWpx~u^z`nR6Ly*c$6p0OoA2kK8aLXA_{Sc z9Vr6`Fy(!BrobvD_puPdIR8~WDE@vH`UsCev(;1#(0x3BRWu$Yy(~c;Pg z>D6HY;$7OjS?-MW1+kGSSNoQ9SovDeyf*7&A^b>`&v7X4d=gg~7B<>(J0pyV8{V2n zN3P%pN0!&m@V<&&hOP~I7%{#5Nc`-x@Dd+~c4Cnr8so>%CW+scE9B89r@8nr6MY3$nb_dMRS z{_m9*J7fLdQm;b6Yga;J>VMY6>5saFhb5RT94W>ZxIw@<;&8qn zdj0gw`z;_&R1J=MtD6qL|{_T0p*b*U|e7Csz1~q>8;tjWANsY$3d*fY6Ny-0ui50D_U|4%< zN{dv`r9deI%q@zzY#`MbmBW^Q@Mb;SZXPsj?wj?+fD2D@grK>!IpX)=;Mt9@(S%MC zh>f&wo3aMOsT6iVGH8@oGuc>FL@&o(*kOG5sm!-!#+KI9{|_KX25U|%a%XIZ*x6o~ zC&(Sk6pvV0rP0VRIO9P$_b3r6sR^o!Q*H*mvj>GI4H4sRR0xj9iC;-IWg@^q-nu4& zNk)>5Pq{axeKlQ6zHUSCYL+ zRM~iDz)q4;2tjgj^Ad~i?KGCkP*z=Y7KOI|KD4_Ev?+N)l!J?jmZ8msHMiTjF?5`n zxVJaB;%M~}Fin5Q{BQf(E?=}I@y?3f*WFvZCH}qJGNt?I+|58)xbGd;S2g{rn+@*g zvH=j*z?QO%Vwqe*DAIG033MuHwpy~TF_m#VAvA^)M+no61s>6*&`5o$A3LcLrWlWD z^WO`S;Wn3(l5_wEu0fa0c=~O72R*yxCnyQvVp_+5(=y>gQq_TYF7w=LVKdY3`tWS( zKd)n>`{S%>`kBQ=!jP&>wsfB(dYX_~zPUY68rkrZy)UV&tTh9s2Q)HPRb#y(uedU(z8QMSMp zM*&Tdb>;7WHzj%*EcU_bp>@QuytP(F>g|lIQ77JWtfV)YUsv1$KHPzxf80sE!5`fc zH-jl)Fdk7~QQ-tMrNNH~fPzSX0@AHCl!BE-qHa|3_LCXlF|Y%Cp{zO8s(C1!?&58Z z$31<3RoKw8?;q{fRfWor0L5LF@BK`R_l4gI4ngz7-ND5odG5{K;-bjFSDsj(yB(ve z(d5>nPi5enLqYxMc^c>7v$qni`>9uN={l*1)&Jo_^g7pn?RDEVqfx_6X;aXJj%n<( zmKBeOyYMBSoeI`BRon}U`_IJuZpS|s3}p%VZ|pVzy;8cE|2^m|TMnm-g5Huw()&~< zWHUh?akw}%idaaD@^oMY_WZXR&2k>M07-c`P2h~~oOR78xA{gpJhj?DSZ!^#!zqcK zDAvi1J&sGTf0VmILqp);vuqr#YQ-s)oHi;dGm;;D(*~)YWcgM+eT{`P$qY@Zd=eAC z!!z{Vn7Yj#OI=OF#Md-N1o6*N*Z0Fws@hse4d4Nz1~n~-WZ7S%EapHVxNiB*E>1SU zK%*(p+im;%C;A~Gh(tEHyLQj%%Kh{xM(s>D8xP$|Zi>!9qXUKW^9X1ItEXtAy=BCg zLy3fxTOmsobZ|L2Y)bS6xOHE#{GMYRviCou=sRfMd&!aC=_YXQeDkW8I$e-bT&mSp(#%UVEL1%28u$7|M7QESMlDoMXD?K_n@0WJErLe zxNHfEZEw5cwDzUgIMT1hje%&Pqne^ng=uJAE`i8-oGj;YPNDs z(iA-_yh*;;xAEABr4pL7t^+%nTifVBB+Le4_)*-Bz>0(8X zfz#xY>)0o-j6LtKHbEj2wa;N-XoFJm0{!xTH{XHZMaxhk-;(p1(ZhiM`hMLK=TrP- z(#_WML#>O0Iq%)1|5Wo?&1aK(JIk3y=tVv>v=Sraz>LKJJPM~rh4#=J?1 zg4Dqb=vr~Kb4!$6AH<{yZ8SAbn`Wf;PY1e?nn@bkPdkBV0I32q?Oij*wZ%@^#^-J$ zs1at@88lWVULt=S##`~*vA;sA5kw{=Y)?a_%J|i>c{u30C0pYO#EHeR*py!q3VeID z({gja^&%(!!1qEV>*|zxU(BbA;I`-BWz>)rcfI5NZbP!tzMc*@`fkQ^ZtUQT(xRMY z9iP7bHm%pcR_1zN6j$W$aT0wf`dgL|HPZ53j&MM{`2vnkJ1(RArlO#SqI|%7882dB z!~u90wh&|nPs&JrR*$Dw7P~vmmJA2w2(NCb`)~b3jZDkiC{$$slVja0=fOkW_I(IB zl%?cH1+N^ySKcid&f1y6o?MEmn|GNaFM|CX_$iZuJM^0r^AdP)K7Q(HU4j=yz+j4MlKt}RJ$=cZ2HO)}Q{JJ-e zkjmq3PqBCmLzU55aZ-94An|K<^OJk-jMv||*ZvQ!%Ky~|Qp<;NJCNl+E5ZIp?6>W4 zJEb=c{?~1bi?i1h4>JU1yE^|aygGy|j5Lr4)jY?4S+0a%Fl(G-Ov9#7R?nzKzNEXv z-S?!s&tFFU1WVqSLq$GA$iv>=zI4J`Hn1;?Ma>Ep|V>bkpQtw_xkF z*$iU4H>p4|b5Z?N0Ln)peK^!~{d;>X0?cw(*ECermvcNlzxcrl`d`dBKz97`!1JPM zwA*j}g;DGMHQmMH&CoK{N7tqWixFX;tv~l@kAMr_z3)vj-~~xY&wsEUfD8dAr-~6< ztK1e3+932iS#6NzfcI$88}y={P6u z^iiqkAa}|j7bS>YJc;LX+OCnG;om+*Zd(zh_|Zbj16*Pfczc;>CCK&OgSK}a zh~AeG-W{!g`PU86_BJ5oS6m&-gmE*$?7zlR-Mu85C>m^*Xs<~$XZ zbH(36ef!OuI{?bZ%q<-czNVfbPXd1dc>^e_ z`p#2JVbeT|(IMbw1o`!Dp~iw3HJ28tt}!8(xvujcmLN3}G?=jGf4V17K0HxlS(fmR z08^$d{bAW=JB_Ey2K_e*VFE2ZdK{Skl2vP(Se%}Rbk{9;_W4+r{*b9#IG>am0f8rT zLJJ*^_2u;u5v#u5erzAw8X9J{T_?4sRPsjb(T2K*EmKzTg7{ePFv(u@DGhir{Njhx zB2ELf4Gc<(ipK0w9wp|V;NWyzot@!9s^x+py2VV{C`~T-kbvn_Bc>Nq>1j7&_Y)6S zE@BVL{+HqYmvv&dD{FnROD8ej$FyRg$XRT8A$Ije>?-t;*u&yQbDE^126LxQlGni} zUQXs~F6t2jYDn3|-jD~uDmgA(YJ;+B#>~lf<3p6$1rIIT%a_bZ;8HnLWhs=QR4~@y zxPkyfYeg)IW5xU_ZK8qyuLWR1a#w{c6ZV!2$b98io`v&H5 zJ0uXXZEIptT8s@w%olG~jHeGSf<5G!Q!l-hdHT`b0BOu@!&L+Q3&)&5zS7s1NgJr4Pr5aS9?8q( zQ2QQxrseY)cr0HYt+m9p-RGyJZ(hvb456IpEv6 zvvSrZn_DWW@oR>(Z@6C=9C#iS?6*B!S!M~Ht$zH7^TwNia$NR(DhLNX7x5b0_qV7I z`&OujO+$n2Lj0OQlsiq)q`us1rI#Z1S;GpZF^3GJ+`shVB5OCdnmBX0Of=c5h3DO% zabl6%(AX%rbw-k;S-MK&zpmxCuH}EGb%@>Q_C&CX(i<=;phg3OB)OUBfqL`-~Xw1Ssbd5ToOv=z9mSI9oF!2`{pm|GZ z8fOWu99vl2wjX9^l@a-CQHA8TbFhnajI-3x==*f=H|#~k_XzRA>XG~0VX;bLVXSoflgW{38~8RX3Vh6GFnDza~_Xx{%{hsmh2q7 z=U(zH373>oCz|J4C1~(~P&i;RRo^HB6L&1d?+9Pcg%AqYp zLC~P9u+q@>rsOak=RnjmC6@z2B3R_#bgXL?aFB@66GF|_T@ZYQPB!OD+|t4%Br^iefyMCp9JR%TN4AE@uTP(qU$a^q2@Dda{c%Mb(1D zx2@3;@po?+o3D3l%qYlRJRjs+__>H-L{UOymcO*Ra4N*BY*fr}tx;x4nEjyuCpthk zj+SU+xrH~sbZ5j0gfV2UO9$q?(2CQ1JnR(xZ;R8kLhs5)tCo5(qAu?!jv47=OpC0> z=*YNV2D;mtwb`o!-=&+*3Mej{7^(GAF*{$Edk=o z7f6`-d-Ej?%D-Je{b*g|x60_Z`d{h3S38%WnswRD2s_G8vu}*bLWP*?_-(w(@_Ya( zK2)Oz|0Tr&kSxh_E_+oQQoUtG^6P%V7Y$3JFHoH-;j0FFgQ4P@Nj?d zu=#Kcc&6cpi;E?HF$mqS@05aC$z9n9)PSEIIm?>r?X8n1++7nAtllwobJN4P5GgRr zpXbO~5gid1_Z)a2V?lP8+Kg;K9PP>N$#9>+v4#Y(h^D;f@NZkYpolv^BdK`$|8`0l z72(w^-c4{N>(}ft(B08C-MG5y0SYquexN!U5VUa0jcJTfPkbDAZ`@9^cRoKfG_;}V z;c1QmF*t;L@H<1)HI41L50{m22DxNL^Y#jEM*h@o0{KIf_%)Ldn2qU)aO@fC+k7~5 zO-j>lw&Cfk#kVPfO01CTxjmWOw^NG(q)R^5n1A#cjw_I?}Se1P0cQlS{OEPZ&9+wtXTdsm9Csbw$ zA(3CN*r=QQ+Nh_Z_{T3Lg-JQ&Cf7=ty2jt#*C;2V2bqOGr4o{OE(zy1Q`f;avm#=j z*lAVOHbWeaYy!7W+Cn(&W4|YiP*L87%Er!AI&-v3P`mK7KLp7GanuriYYdTr~jR8#XXc|bO++l z9jE~x(f7>T*4*47b2E3v%EV-3LNwp|>x|V}MjdaVBt-RHG*AD3HTmfFt49P>t2E+2 zQ4~xG6I_%6swbuL&xdB!LkKHa2O1h0?CbQVG)|>32v=Yw(V=KyWFWr1H-%n~u)nFX z)CQfi7ghwD7O;$d@3t|@`jM4B|2QA>N3wv%m-Htz;VG)?+kcs!s)3VQjPe{pZ=cz_ z$%l>{tVh)+1U48-W7RYEIFKrR+iw`+QY#+|}}l z+zpnsZDuyb_^+*aw64X_)}Xhy_QGINgoK0xuFa(DQ>7;76oz|Y-f^LQK0Kp6rpNWT z5L#L|wu?@3Ffdo>CbLm{ql;B_VTcZs<5!?lli$|nqtL5cR$Vxo9(A55aw{b?{nD%$ zZz3Q+w%a)?NJ!;9R&vn1xv=E3n?`WgujS$1=$UG7XLtXJ`sQfm8+9{Uz=9F-Xuhqr z0CXOrw@ICy(Fh|9j3fAU#9;7>d`dhp-__JyNlI8f0_-WW-CHs;z%TnL{w4`2q+>d7 z!FJM(r_Ghew+)O)nb0<#3<(tsQ}R156FeLeXlZKZycy^dJ+D~0{Iqm=*(Y`nmOQ11 z7xzFVf&XO}f$(9wfyV*{BDPQJz921{Z>e2az|bR z|M#VTUu5|5Z>k91aR8J@S^vlX}1KAuHou2`-LXonx@gBk|J}x7{}xenz_Jw zLP`%&-E_X`ux=ED;jc6wqf00~3Tj}=pJ+4v_WD4(dAt56>m z7bVr=hg(Ok)g877p0b4ee8;uzni>w@6i$?1@O~&$655NVD18|B+%({D+4!BGp9HRS z8`WP@v?h9-(N_7T9g&QMCX7UdjS7-18sUUItl?j4(bJ2H`Ro|uN+m;jg91 z-TuD(1Q}HfiEqKUMCF3?E>Py^3#lT`UO~aVMtip86Jcd$4ZKX7FKMtGw8$`X+7Q=W zgB@KeOofThL50ii>*Kj-S*uaQ#sKUs{VX>ZX#AypZk84mC$iSb(LulUReM!QS zcuS1k@kCSgmn78}IUQoGfk-E~gfwsPMdn#)@x$t9?fDRt(_$Kj)V;tI-HGow3RBat zV%gigL-KRfH?*7a{I!&2C*-RZUSD5-5FR2MQ@}$e z^WXDwbK~OSp|qFOEnd&sl=+^5T=V%&QO1zVA&*u%q<-^J)9lP)-`0Rba!iCU$>DPDcz~Gr{ z3R}ZCaOFyz^-wEiN%V_TSCvC1A`3ySYDqf_%QY9 zzc>w41~b91d!JVVwzol5et=g{(DHWI-@fT|^bILniWp#rhib{&Zm-x&n^&V~4i$gd zj^PR~ag#$Jsy7##;u#a z-vnJP)Y`ROu6_i0#~Ja*Ls<{2<4+EBy;kKwjLg8qaOqb*4?lNj)0H4;?3Kv=+YGU` z+}2VPt9KWc_SZjDwq6+B&31+^$QHiTtJQbzXZT3U?swml9Mpa@66;rOJ;4$@;#^2} zX-FGaZkI;HiX`Sj1iWZ=#emXTJPmM{pa9iXv19iD^`5ht@Rj)WS6?x$DH;X}s z&oab~&=EOtucK#0H9(dlmR#~j>*B38hjy-sVpq8Rjkm?-7lxkePaq$_KiC}3dH{i`1Q52S-AcEe$!+)EzP`=h zU%&LfdrCn8P^t1iJjv%@8o&Zv3S%zH4(kf?XuN8nE`qZMwA2zmXOI~cm;d{5eQ&Og zkC*rPm-pS;w26Y-d0%+#W)lY2$F{j49CPF|BB$Vo9At-6Umb>v>1%0uj4j>nxeS+} zFp#k8xE}S8Ds5Df!4WDjueZcKR6@|^E-jU!Fb`DMILDTc6FS`{WP-phG-h$(`4_op zCx8DoySYMjd7LUm#%e8%I|8h?#M{C=`2U-l^4v2wqo zfhP8*-D3!B^L$&Zh4-6YjHg zHt$S!ovD??r7F*_q_2#Dkl&dAs1gzq2t!1mDX_rgnc1QA%O6;i6rQ8xGR229Klvit z7t1Ll5B%3$dQI$68xw9v+O@PXDbgKHaQ^Dt91Mfi%+G9>AI#I}4S75TC4>Q>55js&jJd&Vdhmh7>kp`YnF3A43(81uDzQY=(qD)( zQ!+B`y8RlS;w)PSyAyfjJFfjJ^DvvlENgz-?|;J|Pw?iNyV{ygmA2N_o~sMuL5|d| zw?~m_ymkm^%k{rvfOD!@aiBt@2FJp~l|SO*2qAwoxgp)A75Vx3+1c61H_1a8LUna@ zS~e^%jaqNPHGvTTPIJG@F6zlgmR#g_GH<>r`OCLTRBeKtkji6oeRC5Y9`3O_4aQn9 zA(E1kR8&+G4gYp`#}B~PIQx=y`?rVG=)VgLz$)PkF(XO5KAgpdjSGp@-#3;kn$d^Q z&Yxv(7|bfB|NQy6ABZw85no75^V`<4qf^@Vu1VF6Jmi};OH=D>=+!ckbjLte&*ntT z=l;awe)nA2_xO7Fc0uv%%&o`g8C;4Jj>{eQgyp#9y6w*Ncx-i%=Qi$}^{mqn&&{k; zx@uvb+XxoiglxlEpk#tiR5Vkm01K`=Rie)F9$67wD5UZRTDsaV-+qvi1w}zT!dH{DMSbi@ofE=katPsAA7LZRn6YG zH0bB&S9q!&?1?pXMb4z30MRf&7t-USlTXo`TU(vR@?VZ~!x(DqZd$VjEfR^zB!AZm z5JX+cF-WnJ(4or}R>!2GhZ4(X2Y(LWME%z9+I#3bL^tPzJBCfimQcElTJE84ZB2_$ z89fQ|nr z@NniQA|<;?OlM%E$R7C*{%GyXj6cNGB+`MkQ{F+hdyDnvML6 zN&GgtMyby*YTg0Ugp5{RU^7C6e_%XVKC&|pvBJSTmr%gxWf z<+*t6CNiKT8b@WasSHC0fC3~=KU*kk6;XI=K*Da=?0I4leFXm87|QSlbpjqfe$v1? zU}^t#73pT*tQik(oLrUptiSlGuo3cDNxRl|21FVg`kqbjU0#BFfP_{1@Yjp7A9{8B zAnjDb!QtSEmi`e*ubw2{Yr?*}s*{)Byw-{>D&Zlt9g4vKGfRz+j$5T}w70j5`?uXg zt1@&9T#iFWFZ>VDx~i4+-JN-!(V-vw`}g$e)7#><>j9km(_342{mmF`I2oOw-WeXT ztIg$_6hlJP=NKSB0%=ob6)AqbR+=uBmX>B_xd%7E5L)n}UWI9kKM|j>t;S*M$JxIw z)~Fm%XKf@z=%V^Yv3*cghDv3+X* zFfCY$o_zfeT51`%B@XRaL~qNc?(s|fBNlp~-(s z^(?&jYKSe!a<|!$6e{GFmtYM=6^rkjBLGf{r+sv zvYL-hUk#_Gr_WcvUwb5ah+++sKk{h1$uJ*C8q5$ou=JSs8y4}1jgEe@5a0Q|s>QG%+B6|r=wUOZP+-m zC<>MXOOk!~86c zkaE`I_#54?Q@&+JJfFDly|2{>8OpXw-^%+eC96Kg6!|t+T0~PpaHX&K1U^UI7mk4s zQRA7DM+UuTq=$4u34h>!^~O&!fAWz*>g$)H;nyjvAkHV5Y7ZP1&nT!VX0J|!rrt*D zQv7=W7%V>lCI=^?dD06FRF`K$T6zu7%eB{=`mUG_;;M}uBQ8dL#j%TCIL@+$naDyp zncm7vt3o>xbI8mxR)}O&<;i8@Kf-SRT->?RX3LSMyOi8~C*3?!l9)1-mC~kF(_%}e z_S(vh8PZ{Itv(MIyB}%T%$yT(XobDKX!Z;ZD$~F^Wu;y+D_!|%=D-!Dd4d8_k?$ma zRQ0P{U7oWyFF{+vEPs)E_vpxJsOQH_l?0ULT}OP6(9JbylHq%com}}SD-%F2TbJhM zZUDCgh>4yGZCuC@|625%L)%@dO=)D0DOlegf*FR*A2=buQ#gY;&p}OX;5s4=;qcg> zud$f|C_T|(V~4U&!1%xYBHy6D*yy$sP5$b?1AH^fA4HfvgA57o`~X8O|5n1O4O@M# zPKL$G-v5JU-{0T=_k)fH*cn5b!5gP0WDZ(nd2W0Kr1?d;T+XCQS6sJH?csEX%3$e_ z-kMV}0Rm2$1g;QqXdpxzkt@}ci6ad&w^XO zH?8`MyyT@YHde1;!}o;Mz%o9j{P)(QPZ1x=T80fnZCMs(>#}$R=bVD-YVT`~H1W80 z6l^oFcr!Ax<+5YexOsTq%7g#u_Kly7P4Oc7j_%B(ZOxutP3WIROqyP8(qE&WUiF$D zO>Y-uNkG3YOk8!mVRy1c3k3DWV>73MiVBmB-$TeZ0E>V#LfB~rtI$;!%c*m<2O;$) znN`qoeJ1IBetcx@?c7YF_F~=h_SZ zzZQUBY=7F$t|UD?+E`wWSXy2P1Gbuu14l8jAjAHqdgU3lUG#W4Q5C@~U--B)e3W~B=mv=&Ej%))+=5Iw zW2i}N^R>{Q$}%%F=#%8Vi^hht@qm7W)z! zB8V}gA@Ilsb_H`)>CdVG>fiaRKB;c?syX#PDOCS0^6prGG>D^%TTv|N;i{)>vbDDL zuNS3uP6dMy?_>hU{cX+#9}oAs^OxZtezV-~)t-MsPnK6#3igvSR%M>WkcWpBOZP!y z1R9S{j~8x4Y|gWU5QRU+Db!M62q>an*NQ3-f&Ny3I9^`%^C$r-p;N|TjzJ)YqRldY zD1r=5PrOQdeLwi%yP;zl8yg!AH>xm|Hh3-~D%$EhH~EpRnL~&(Ogua`6N>X2e9E6R01vT!sX$>u^X|$(}uH1zq?|u+o9gx3bUb<5|{60UaG3 z{r&xK*jtDpQ9Y~IXFFx}tJnsNyM+arz(^C+2PBXLdE|fFsQF~*i>fA0ELHgoz{7}a z$0Z+%Mo7a!5if-AB z(XruD#Hd)>sMfYtx^*UN$__1OJ4O$6N4wp4Q~v*si%XjiJH@~a8>n?Z4!&~Gw8V*p zbw`AW0WpDD*>l9wGBdyxfL>*w573DZ1sV2|09e2oH}@IuBC5!p+rZa~T4)lUu+P zx1xcGY{9pkLsEG6H&$Fg^_c5Okg3Xx47*S=LQxIo)U+5!ThW$In2@q85RPbUOHm@Y z1eqCSSoZndP9PH!AjRm?8EnER6i8k)nVI2Cjh!CFiq`prW4A%JU!1V;$krVkSfzZ$!_pU}tx#8DbWf$jD z{f*v>{IKgwOVF$Y?T~<_BwPgw2?#`HtCIWa*1I*Le8QqZK{dhnmY>f2R*uA~m~a#l zoB$O!31xAbHQPIvgrP>3)8E%;CE$f|(8tinp?v7hCPe#TrT62p({ZoxEgAyO%A`Rg zL62U$e|z?&Aj8FeI3KSm>@_OU=KAUcY5K%Sis4k1=Sn=%tYH`JV%}{*!(WNcC@uH9 zZi3Q2LwndbC+VrE^Pe>hS=!KITb#Ry@j8r>Wo?#37M4hPEI1TC8wjmj?JF}Zzt(DO zHJ;cp;6cRHGl+e1(lp1GZI=fY%c^eM2lty7NIYAt#w}iHBqdECL8kk;3fe!#tjSNz%8<#=<`na7M6>z_(2J&iioh~wVA7} z1@n^L#WFmIpOvgF)2w}L#Mny0E1sF?3H|RvR7!VPLaPN>Ldy5Fg`ZjeR+oR`e5FXi z8|D{)0>_|wHR}nJffuCM?k$YYPZM8DEMK9UL}95eduOgqhndvdeNIp@IP$Bgu>3$7*g?s?#0lrj zkKjT)K@H6tA4w>ro9I{{i+xJ02?@xPijoaUJbx!ARZfo}8tTxJZ$C)eL_^T35XnI- zQq0!YB-&r$DIWL@dk+acC@Tveb*r+Y#6EbLA)sSFuON*LKje>&055pGS!>xrET1m%WT6a)o8|yYa-P~kdg&91? z9c^=d1&?W=V@flBnt6_NU1*$oE+YfWc1$O|D$WjjnxAXoM-7<>p#;Nw(Vsr~g2^KL zG|sg}?}Nd0=L6Br-7??1Vlz6)tXrcgyXpGux;l@EB8^%q$q1N5eI{dG5wT26!m=p%lwtXmvVS{*M-y z=f?3bh>eVv)L5JLGG6i7?<-E2;|}D9_2U++u*!uh49KK#b)BLu{+T}g(-nK0<$qg{ zHSfHm=zsAw{Fz_gu26c;xpDx+YSE2Qi>d zT@a4E-I4FsLrr?p!~O%7Y5zp?K;8Oj+EIP)spHlu**2Uf=t)3=EQ&?73L8(&xDaRh zaI)bCKRdPjj+e<4dU~~Zr**Y;PjLscCOmti)QqD%4EB0gsHTqaeMyR(gAoxNxWP0` z#MrF|j}fL7+FW0wdrSpcO3z;NC>j(u!9ytf;>I?v2J0&pG5B&dQG59BbA zz{hy~S7PD2W)-I2sjmuDn5>3MhWKV4*0iarIVA9Sn&s5T28-~S5fLV2b}wJL6^<_( zKkOU$PAse7{dZ=yoBX`t2leE?G zT*orQ{a+M7f)AS>t#`>;m)d$R1C5z(F^`M?;wtr2R`b@tIys_qSC`9HsL#EGCLhu(HVjVQ^sR=XSB5{f^6k zC9%!_gkW~oB0=6>O|oil`s{0dCZ33036%s)HW2ji8Z8FT(ELX_ks=gcey3e}vvYGu zac~G_yt34B>N^Pv>CcZ*9d)m#Vt?=mXg|_Bo4m33q<-FDY@vu*6Q4Dp+nnYt^F0P_4 zN__TP+xz?HzHNexPr7V}scW=2X+n(4ppPDu?^(k*i<{vAW$sk;Sv-xOK;6+rwZgT4ZMm69Xfo3not5o&r} zB~<42@6JyoFcCz3hUnYMoZ;5Rc?_Eu*rNdb$z!uUy3KPla@x2O7V{gp)Ey& zns;7vZX@&IiB;4?+i?1paXk$2pa=y@kxJIRi_xb{g7YOjdnQrcqIcMWe@|{SF*)}9 zXWP)O@7rzX{H6*EY6nw}E*~qi>Qufv`!_LT%L~25VXGHERFNkP4IG^sO>pj3f1}n& z#8Z;=^qzyJ`n7zO^LzE?&&&KVs43~`r@xSm*ZH~gBToT0!I4dJw@Bet5G6M;D8|cM z>$0g7)}P_Acwfiodkui$-Sq2+tTO+-;##|*EU}BZhoeD2%jG|o2$u}+Z zzNy=nV#3<3#|qQvs)$AF_oeb35bpC{$EWgJ0wNZuo{!I1u5n~o6;(q5w zjH$8IL_k^i?$p7^k3oxd@$93KjJ(~yg{R8M+P!Hx#gnf*!)FBeD6|xO4p(~vWi*|g zvMf@Dx;IU)hID8Cj91ziUmR}L?}VGsKiq_iE%KCm3#Z*o);+w6EAl=&J0lRi{rSem z|Ds9D=;6ZQK71!UtE+M8e;4PjnMlINV0z)tuq$nb;pdT;lF-m@A;v82EPiSX`Pj(qC4L%xaagtRJ57% z{ysZ;M#bUzh?rmaTiUUT-K#wD!**`mIVbns*^$wCeqPa>0M;$T_^h8p|Ex&GpAW1{ zv7o5_{DwaNTK;<>S2NEpfdJmbShm6M+0sdD!lx!=x=IRd+&VJw-=Vl4LZBE5uHh=;#qx{&zI)DlpKH=Z2we#@sU?hqJFVJo&qiK2IN$<~Y;3%?%<{LNkz;(r{5X;rbZ$&iEr{O} z@{CVUUyi=9VMZQ!4tpyZ`u#fmX|*(D(68RO>!oGjJ9x%7uf6mKJS?Yw?+X~!wl7Kq z5AwbwU+m4Br%Zwm?7Qf>8ER4w_TpSEpTn&48u-kA>8J~3hKuN1woR(h5OeBKIKan1 zIe2Z~ppSnizS+Mc6g4@Lr715FYA^NGp!N`T2hP2w*3ONCSRG$H=(E1^5yUbR5`ub5aQb(^(3CsD2kmD+zweRa<5iBmPBmn zI(2&4z-SK0*GdK$Erg7ag@GxOiHCKdhy(vmrkaYtnKuR80XtENntxxBLseCFh+INm z2HhkN65L61_T~*P2$t5QOsT9ZxDHq%Z&LdePF-+WP?t1x=*oWgLrN=2V zF%u)R>TKahALeuDEx1?(m}35qrt^-5v-{ruC}D^)`siJd!DvwkQL>JLpbcvSeLiF;U=lff)b^mGBvdn$X+2`7y>)NNPwuHD488}wPEoMnP zCQlEicVP;R47b83%QRW&tjF=imz|anSig(I!c5{HamMve=c3%U@JaQ$HBr!c0bSA5 zHSCJnv=S;=>>#hbX&nkzy&>c~rcU_IwdbVJncb%_npk)|Cc%J*itJ&UC8?$+>vNzb zN&Vq}d0LJoRXzxdLL3z0vJ};|!{I8(?cP4xHN3-j$$>S%G!$N4; z@bU5SL0{%1_4F|6&>+ZDBuNdWx)?9NK4@x0ttG-@{U!kJyQdu-Udv z3=XAdrgI!$KkcS&3wjLms3pxssPMM^aG`U|y*usYk7OqB8>#_>#m)p5J=xgIfe^X^ zYt%qHEBd(ec*yiO>pf+zq-rEV{ZpRMu^1)Iyo38_f^Ox)#Mm{a5Ed?o^oNd8|B~3} z9ibVzxN@P6pIG)xWq^E$T-|1wG-iDmU>eO2!6`f~J@UP#jo0qzW36PIq^yg-Jmm7R3@u?;LLT+>MeLbZ z^jn&DiCVtg{*{z5zw?>($U}Ha^PPg)n{rHg0_@IcYG$gOtq(>WwQg3D*_h1vob%P@ z?+0zT(>tM7qZ!jvV;&v7x`-!RGMF zRpo&cNTy&WRyS;La62e^kmJqrA=e>uyurnM)V4S`mS1(#byTYLa*gq>$uUy~CV8>G z_TMJg;8=0+N3V7>T{f@E`$(33V=eA>vw-nJ$&Z8HB}ci>iLzjYCidNNfzD)sgko{9>3qO&3!0AG<^tJ6Bhdk(qJjdQsu{(7z4 zL@i<6Jk-gFkpV#7%C=sI(?7w{tQy}7dC$+z{jn6qS)}Ju1w9@{XmWFGb9rd_-%hmp z;?pJ?n1c8Rb*>N?x-f0D87)wN&1H#XDF`GUL153gLTv0EHP`^g7yX-C`J*&5 zHk2`(=mux@;KW$F!u=iuYK|EQoQP4_%xBb*1h>2b*QP_bGxfz1OL>7%g1zG(vk^N_RO8KfZ zUsczSOBD)9t;vt%rZ{g87}9V`7ja(J)-m<~T5-{&hoHDb$5Ewm$M0YF9Vaz|Sv8fF zf{_Zy4f_S19rH*mZ8^gCgp*D(q^yPUnAq?&-I||={^KKfcg_ckCu1!~dA_S|)X%gJ z^VQ@wu8irmAw%Mc^;agK;$!{@?j;{fN=g9vqKl9^?8I^*W!U4Tr&nSo=++GEMhYQX z1725ERJ0eAsYF1Zw|E?HqDsalrc|L{A=p8-;4~JcGVO`7jJrRlx$-*;^STonE{=P+G9RPxW?$Dap{GJy0qD!$M&Fah9Rj*F&!E*=qJ3$w zUp_f7v%YBREL=1ECnlR_s9!H{1lXo>11f-(xeW_RzvSBeqz{g1q1*koj6 zz{iubg&~bdIFXD)(S+rpx_DA{1pe%vV{a`AsiCoDIg&K;>M=e}y;O>4olN{F4BjXO za#S2=1UctNQj9}bYe7`Y*QpT~$}<>FalbXWaAVQ?ZSchgLI6lwgZ3$0L=UE9789cR zN17{e@+Z4In&p{8DAi{N*Wu=VMs#&I@6J0)8Ry=MGg}rWvxL|NlqCzKDxn3^uMV0I zz6*}37QL7f>bQweZU;*ED5 z?H+Pp;}Btd;?=enpOc4Q-xc2N%=W$U`~X>%E3Uhq7NfuN-M(9F^!S(h>?Vg~D)kYc zWc9_bB%%(sD_#CC*PF9WS3NbUQ;c=bZr>Z9dJ2o?injV)5(3FCLtDqyO>)SLEVwmx zCWvo-$i-!D&dN$iNEpt)(C~P)J0v*PTSsIAiV;YZrlGEGcl2OHtd{^nj+w_M8v@H` z<78LsjxA19u5G4(KoXso{&fUceL~^GdPoPEppZZA9)*w)%mtw#wAo^H;vX$|sIpQB z%u)-ZDMy2I5~VH68A^^OCm|R74%Xp{rZIO4r=>D58G=PxFi#5?}4e)vW_G_H}i_KZ7sio9M2i~@v;p?p}6L&5fU5w?_ zO?#nvxs~)%9_p7pu{~0ZhBFCG+f$Dqht0lzAJ20&b`clj)5UFM$v^+Ta_@GeEetNx zaI{y;^jljt>Y#sP`gT9_1K$*7)96O=!H+brf)3sB`Dv36m`6&Z=PQfVe=>CthCgT| z=9emeddm)9FJqyTF*h!AcCMBLt@R^BIX6;<78)Gw?QI|NaInPkbFwR=rL9{5=llTn zHQjyQW68I=soJ_5bi@f4QnN%Fy>!(-J72{HYCICQNQQ~4sms0Ziaq^kAIJpI-ih(ynbG_vhX04zBv$!GLFjev)`B#E~ZC(EQoztTx7>4CO1 zT)`f2#{>Iczy8bSTz*fgc>3LjJizOAx#2qJfeY*AkSpejfR@j%RUBB$&(&R3HD8o>&XQ3o$ zq4jYo9=eL-{Dmow_phvMl)IKZZoDO*bFQmYI4^K8Ghr8pmDH}R9W|-n$zhYr0xtq5 zyO`$HB}oe)^$tjcGydDX5?B%&smJqR5c+Nc>Jn9Ue<9-F6??>Gzc|7-VDTRtLn z0!~NgU~AiaIH4lL6)!+=0h-bQzy5CIY*D)tV>EHgX{tQ?^ppPG>}Avrjtczi6C=q= z9!Jd1Y(7G&Yfj7Bd*#(}IdkpyUB+#ee;cSgbAMDj544S#4q0>jyAs?i668N!6UI6) zp3&W^YJ3ZSPrKshN+tVy)1ItL~Y5=k&r z6S5wSicHu_#VbhG%%vLh5~^8b>Sv%~9KuE` zahOl=eGr?R%q8JSCQQx~tf6YZ*;+b@)dbYHM?9YcnIr@DCHquILX#6=W)jtA)iy{_ zjcoLknA+wvlf}hE$AFBQ6lL~zq!4sEW->pT>E!W3!_ywDQ9-pA5d+oV&7`dLUb1Xr zOA1gQEs^$tidlA_Rk}!qzc0r?fH2c-Uv%W~@U=j8ME_dKkn)bKT5WeI40v@OiCEXp zjd>AH!V)y`IdP(^;3T?`EXUo#eYwp3sA3R;bM5v8E|d1@R~={ zSe5LuCwjw;xGKv6}ocO2CfE#r69wPSRR#c=`8lOO^!w4A@hF2nMSu+eEGGzxS@rD3Q@ zew^qaCPU*74QdUh-C>~kQH=?Adq`H!V#X9N*f*KYGGBk_LgjP)Fy(uoZuw42(SLsgb7= znWoz032^LDMD@bW=Wk3G9`!Y8apN(dqB#}dT=y_T$R(Kq+2RPgq1|IHbSr0s-JB`P zmo=qqcIq!gLQ2*#m2FuPUS~BWqul6BxS^v3(pT?#GX;A^>!N0#*;OYA294?2Om&vYAEff!shfl=Qbydr zXX$a0TX}kr{MXujS9NR4r;_EZ3L>c{q!cN^zdu ztgvMT@?{Ax*Y%-)&Cj}!8vf$)VxM(Lgr*?QT}?2sifMo5bR(YFsd3n1NhS+$oT z^XE+Rw8&44&W>BF{^JGL+k2*x5 zzJU1(Vn4}>)0l5Y@DaAhXV|*t-hy`H*D0+l^SDiU<;irAy z+~hID4h)iaYiWJ&c^VTF18k5BQ(XP^4=%^=nXBHvODm$rmf`*2MpxX{Mi0Xbl`)Ne z4p&HneM`e;N3%hNg@k@^&{HozmP-GJRassAJft7z$``+#Rw?h7I?GA(!PTIJKxBRz zJ#lwceRB*y2W!1)cOT$;^}`%BYYpAk)PrG(!&YlYqNp^pFlbTQn?*i~Z(*j%QI;W^ zEUD`(uD>D%eZR)`b}Rj;7G<_z$yDK3lYzl0CwKQR6%t3cxCHsx%VWxwO90(9*O0A@ z{@faNNRRmzW_IkTm`m3b*6?fB9qN{FLc;-;9HnZ#pLAL?prL2rk0NBhrVyq8VSzG$kp zTt~#r1+;xOD2}@8#rb-YV7*@`?MQZs zfvB@fckm1xV(4ymEVt8F?^khj-7xsKDergAehEBa4PG z+3FDKKGD5A*`qCc|M+iXalBl59nI~)^Mx|)_@Rye^^T}vm{6A$Mn=X)M+wTPi}q3I zPsvYH3PhN8x_PjVFqv@vu#~BF3%?EKLO8RUnp*Q90GvlZ>(yqbVc^$$dV<<*snttE zRnCQL<93UOn@I8A2p5(XE#U!P*pD{ za**PolV5U8{>6@6`>i+OQT30wd1t;lEt-V~p98JRMk)g%m0heUW|VDk6zuyJYG%ZN zzU6!C%EOioT-_%83x4&2iIaWyA2QC%%eMybqt3~jg~ zD3eS<=}X`5La%5mFyGtYs8Swt8$9Ttqukr1omrV#0S?uk!EQ~lR6vj7`#GDrs-`7V zFqI_pvtWkFz+QWbzwaq1um%&*z_pJxANVnKzWG1O%+ASa-|wS^{h;M*uG8dPe0$L5 z+7ECdur{udNFZF`M1wSrztM|`twYcwzT%Oc2ZM~^}4 zYDkW{s`Ng+%}3u7L`tH*0l~dI0<186j6ha%Ls$~(=uLkc%O`3YKEH%;xEasu;nY=c zp|^i_6w|Khj~0DVWa+v3Ts)SLj?q3~8Odn;qJhE@5wrhmqX<#79B}3)dgkJl=qGe%t*0!3l^ztsKh6e%|M7XDCH_9L3wz)$#UJzED9y zt|&N3*^R6qB#iC*yP&5bSq4D_>8or=3n3$f$iL4J5&U4Rl6UX;E<+vOzL+TL8>GKp@1L8PpMGTNggq)a5dqWak{>0D^-G$Yyaa1{K1lh{2lQ=uodTbKTn z^ruIUcIHFdL~Qm#5DAhy`LB8pQDLPLcVgG(qS6?#4a=3Bv;kbQr=w?ek)dch&6o=-7g@QO( znyhv=oP&b`mWL-pLZT==k;SI8(qOo9KdSl5309CQ6BgmeuQj{K*qJQOM8f~}-eRcbUTW@PdI`2FS;c|0BBcSk7-(Q> z4dM^-7lbZ>kAUNIgV1aD1>>Ojq4Cy7{2HQ$Uua0Eu2VHIXqv5`;zx$Oq%1M(^xcGV zdo;4MaSs+?6hVKHP`8-k!If~fMHTcs;A31;vF{6t@u!1H%0+{ljin#*$Q@%pV?6$< z>O=~|(!XrEc>3z{lYfph({US;Qmu#dnFtN*DmI;_joG+2B0>4m|7nS4CyapsDKMluyk%20a=+TLIJZOj|2hSrV6dA z7!;(8@&HIq(jbUG`ubI-K+r-jbv%f;8%ZF?g~r40HRFF_bRqD4JEr&zJS@7}Thggi z{PCzDNpUGNY)b|^^eicd;L)V+$2T z_4Bef{T)CIY;0}+{P{CzRSOO-Dr4X3HBpcPRgsLculK*X1U>dw|FblGZfo;1FU9 z3|C2M@4{tZY%f3`jEi+GIGjV}_q3BUy~njxb%}(Fr?nxO?{-dGQZoc1^+tPi%lXwp ziVMbSY=6Ih^@ID6K9k*^^Pj1c{og8SW zsjpw7jp-!aYg#`Q#L}el3>$3E8I=E&hhPrj?l0M(Ug*q zc>Fk9smF1FXoKHSL%p-jG-z|$x0kM;nMIG2h=`~{zxELiHmrB@S$}=Mf&wTni0VL< z8v`pbD{+uW-BIvc!L{foi!*wYT)fCv31&nc{d+3U(lF*xSkKYbJm)hT)6m$+YA&1B zVw^UW=2pAbB8^=L`GM&%o^=$aDu+5uNccI|>{IR`o}Em}9mE*Xq|e1< zmF8a`IQDtDUHJlkIuwgV@So5_d3mA#rB?tpwr-}^Y}~`B-z6Ev!L#x|J#<(wF{pSu z*#4Y3elx2TSPe}+rl3GgGa@D+7fp?C0aqH1)u)y`8kSae>x1Vf%jA7TCj;oE!O;zi z)h47@RjW^zjg;U1^?kkH#dEVFP|Q9!RWLv0h9^9X_-6e9h;?bLpJ_Ja%^f8sAjqnB zx&bkjejxArKJzuw!QOVR+HnWCP)%Go;OZLc$@mwv&R_U*N8eI}NsosQ!K7aATp9nU zcYEV`nIFab=CZm!h3H);870Rg*Iy)q3U)BL-LTMPG{);;NMUhQdufPil?6Tihw2m; z;rm!sq@}XGTQ4UjUiEB3q&urJKKIm7QwOR`md+mOD+;7%Wo6Z6*$L12oh_Z6dKs2U z+BrCJl!K{;vnwmk-%O(k)?HtHC@mm@K+b;%-`rgozk=tUIk%c$#cb8J=ZR2PU&u*V z2h@4IxzZ(pEc?CM882FaAa(F_#pAKShT9mk9?)cY`ObM?;NHZngUxM!F42v#&KbMm zZH#fWP;dGDs|ms z|NP+p$bF-w&qBV(=%`EA)OXnnaSGmHg3&iy?)H!-C-dXBQH`Z~pI41+ZI1uTlVysz3)ZwQd6~d1l$;`b9_**p>TfLmkIY1H4D%xlWTIgPO zc6P45b=B45#O#T&y`-kUsUq2DJ$AVHI-YA4WDgWFQYuq$eBR%8T5x%0-xo47Uj<$? z<|j|Y1yI00d?CA1n$oZqKcoNfm0;DqU(p8D@^>vB=5lgL=H@{JnKS~6)daW(;Wbzg zWZ(CkXYJz0er}p!@6x+$M}R6|Kl8a7QKrT1xYXj&9Y&aS?Aq)wHKbF-zwaMAU%(Q~39&0;Vv zv?UMsgYF~0=vR+awNHI{`^CIio-_A&%o?46Tv&B=4aem#7h$wcAZsl!*>$Zi#`x}X z76dL6-_KM1z3f6K7uVX-Vr6aZXd3Eo!k!35Dtj%u^n2St+1uLH zIsR0jLw6|xQU7EttzT|Xdms=NA4uXl44L+EUW|7LFPh{^>LJ0#FgL+w(wJq=6_cJI zpvJJV@`=2M-_*^5nfR!mJyHsvnz?E+ds?rbI^0)k1&rrJyp?y~zt{>mc)Rj;bhxpH zEMgB_Xuvb%Hu@@H5?npiz#VFRwW?skX6KW6dLHZE_1e|!&A+xQh1z8!4YkF8Q}TN} zVXt?d(sy{-Zt-_CIo4G<)?X53yY3*3U9ZD z?PKJ0b^08m4eY7DRf)K>dupVX7OiyD*&nY;Lfl1~a^KEoR7y$u_OF>!ouYZctGj8HE0z|pxth;; z$wSq!;;E-IL1FyGW2rHhuH!hOdd}=eR@F*F`=1-C`q{*FqbR?hoApn;owkc5tPgzr zBUvjP<8Gdal>1MXnj^2pw?#1yfnZ^4YYS}Q8hM&c!1Va*8h*6=;YSZ?P?8|-`_Tfb z1BF9p9Rb#$}|2egtuKz`8797Z%&=j!s~xm^cm>-XR?2PU7EaQm?wXMM%;U6ibRPJEmOl znPS32q~)RCC1+`XL|eW4uTnqzn-D36K#?#KM?W;$4Syr5)ypS`DyC(_EEI2fWhGaM zV|Y5>qn<|7epnM?!<3Pk&Opr|i%M7Rs}6}s(3xABpk8wB96Yu#;Z@>7^B?fft#UBW zHS9S&DoeJru{o4Hm*S*O%l-=~BYtxIy4kS7v9+V4qrMs4(eWfj8C&L1B;Z(thlfYOcjWj> zMMVW|Wrx43t1HO=0)0{NvvPad7;pt1e!3p|J=JAZsICyyw3l?_d!LO>&1G0y^xcJqVSiD85f$?Up7cHNGINqpuhPKGusCi z?dy5#s8;-f#fSH91~GUY(Z(bHfF1JV`e{(s8yl}!38xR*-aBGtA-T1K)--UN7z;LP zNNEYb2f_eZku2-P-^WsYp7Z$a={_StunE|Lwz30mmsW0`00>l#Fx^5xk9!>$d4A`9 zCcRA;yDKr*%P)C5Y`ao4b&^CcNZcXnWm2>o+QQ}3ktgCa*<9Wh^Y6{3`1U#BuYVLb z9N0rOvh=PhN`!)f@AIp@?F}TDa0AB^e){^im*kC;zrRWWN=_JemSh)F=+Eb{i8Lj1 zPAsdrSW7Pt55VJsR6(q7 znmDKr-2MiN*4#@b96vRuXUC%jA;JQZ0-daIx@gz} zA~5V79HJEpLS<#_>0=aP%AH`?d>VG2GVWE$e;wErr;JM1E`GYU|6$`EEG#c?Mwv@~ zHOu}Z6ZG$euOx$4KFLTkYJL}tEl?RabvD~}_;m;x(I-4xh9o58+kiC&`CPzBiOb+^ z0uBT4B{WoRZf&V;0Se*2@Ou#G^uDO*bbm=gK)|do=|9xa%JS!of%DCO0g>bPw)U3V zwty-5c8U19Sb6nfIb?l(s)@caMPabeOrO70p#u-{330!RB-Ju~nr!qq!~}%OeWA;p z#S{vH3g_}9M=U6ps7}c0DU3k~G`H<;#SoueXO3|`2o@%D$n;%8E6LPQA81* z>jfr;s5%=|&Y!?POf&9nhatkSa3CIIt?zz|)@kCPmX`(}6Q-*?FWM|R;UyF)DEvt9 zadx;O*-=`_mzbxlXtQb*7l_07ky^z=$lJ60|5Z#*+5DMo&?<*V%0KAYlcf<}AWbpdXifh09v*%nQ`7O2V{6OF;btIxlBRN+_4UoQJKeHAmjFi}2( zc`G_pKvSP3&xB5lRUpbtN%0wF?y}2wgh*P=g)Tr3$jy#Ic3K+PGcq%To=Y-_&>NI^ z2fLL|FMhAv`Qcd3L$+pqWaIAOzW#S;dH2W5W-YezE+$S&d}x)`zwO!)DPSJ@Qr2ev zuXH+8_SI|3Pl0-xhsOy`a!jo)J9uBz_myEQ{B3ccftB{^O0Z|D>qG37ml*K7(+bT9(Y$hC< zQXkcjk7bRP*+G29uQ@_2Z81lDgeb2XTibziezrotZ8HdrNZr4%J|iY-KiE7IO9ibv z=(=u$)E~<;LATo%{WbDJ)8}>~d9mO$d<=@hOxl_j=?=AdQD*Es@`e|P4{puA&c?<9 z*%;(`I%2P1Ya&7D8Z|D??<;>vN>F-z(Z_07hifQx3}-F>HqZQ>Zz?*_WU_eXi>bts zq+HV6{CUeKLKlEz4iD3nAf4B~6~BCrbd!UmIBqJ|HcVaiu$xKFxOJ{k%{BfvdeY&t zkc0{CXTE&{d=z0gxMJ23x^x(#YXZpwx*SPF*CtXDTR!df66$Qh(e`Ngmj1hl)vvi>7Qev-=hymH7PRislJ1MD!>~b6QDY+& z1nA}Vmp}Pfsn4s{-MWJksPnK{NP`y|2<3COo^i$4h|zU~Sa5x}MySBkJ(+uC^`!Xw znpWEnXbmui8VK(!c9H1vl@O13E=hjNdlchSZsgiv5y7+j0s4 z4um{L``^7!<q>QS8v#^kmGF!_kgKjJ! z&dgP!h~yw?X=(96x#3R{v1}=+%19xhkDHrqO?qp5Z?3a5F51THgEQ_WaFh#g4M->9 zlT|CRkUXS3zB)S~{Pq+g%{(vOGQS|+C2dtJ<}{b5HPCcXW;?DiJ@(ekee>Y&BbYcl z-Q;jucpb-rXR<&UGti1I+B;m<6v!KJaC#u3i3v|R=tEjxd4H`hSLOaAp1P`}?}|g9 zgyRpiC?IR(=B~6lkA9zGv$5Q?)3+~SL&!@#KP+mPso$A(QTc9Fo6?CJW>Pnmryx&- zQ8}eL(y+&*o9vAolH<5pNcN=76L>)=g+zX=&q+&z1X>8#x{CU(7-#T~P)+pO=R4I$ zO(NS^Z5S}+OfsZxNgM7Fq_D^{s1!~Rs-==~X9 zSp_o_*n4#<>HpbMWnBj)W_Zz&cS& zDp@wO1XT`J^dhLcO?mG_*eu-)7C-=JG77{Bq8_4^pcqx6=8r76D5K`?=Sd2_coMVc ztG4EypxUR~jH-6b#M>EjNQErSOYACyb<=AxoQmIkTXji{eFC40W zm&KiaH$U6nU^ztD_hVAyN%rU#NJpf){du5f4T6H@3&!2Wm&V4%rl!_goB+0sMgfyZ zs`=>1NS|4?65GVWf;HX)5{+K-XV_704<^U5)Enhl(shOQ^aoY*(d?7iv5n%A)5(7# zpVDG`4Kve?Ulh+1S5m+dI1t{-`S%J*`QIn8(L-#^g>Y2XXMTTL`6`~u2rJRzX8sH0 zN#KjtPh|}WmuCq@U0fgYX(>y@zNjEi8eA7>=i3HS8#pt_URwy+&Yc@Ev!aEu$b8FQ zzTxia@|8LShV+LRfeW6R6?BqSPiSJ~3wW_u*b|@uSW=yu*8pfh@%I@Th^i5~ zHD7%F>KD`8SFubH*aN54Z9H9Fy}gjFX10`wrBHSht4QGTWEppDj`kNmgvTgQW38NN zIKMD%6)hs-VaW(_F865urOllZ)>o8zN@N&b zO4onpM;+4DFfk~~l7fG6^H!w{=aE2A_y9>-Z_H~U4CD|FDtqa1>>6-szR8(gTtuX4 zD$}r7f2&fHoYQse2yXi~!NfA+1EL#QxX_LZ|9SQm6%>HS3Gf0x8%wml4Ma~j)#1I# zj7c+>JU#WOmzO6)%JU*bx)A+1z!mBa2UjNkPn(|%f|KWp!n$XPgfSuft0B5P1g3P9 zi2g+z$yBBEDF(TbpX6e0F%x{x@+xbN&{PY*4EpDMStu8(9T)naT>PPU_)-Z?a2C8bkMnpZx4&-bIqv)S zeC@y0h^5Xy?kIrBT7i|b_M2?ymDiIo{*W`js~lC8?g}HmlgjN5phEk6#%%DYxCmQ zn|J=r(X!Bfy?ReS@kvoBvB#OiE<>nD#1LNh*x`E{A)2^;$Aw3|EyZOCLs*Jr1a1sG z{lio$wR467DNcL8g%(>q`y!yyTeWUv1qIdKJuY-)39nj6O7#^CWT8A1EJaC!pfIjq z{?|3LyGUTJN!Es&gi%J$M3p){GdI1`h{B51P``&_rGk7+7APLw-6x3lrv<}3uz?NO z%iP=?jY`kWoz>5L2qOVW)q9<4-gE1Z*1Agj@gBX}S*cgjRe&R2N^5#lE3n$i7Hw~|4$*J^;!9CReJh$t1s7z=o9}MGP6B*Y zi(oVR?r1n?6X)Wd5#K~%GddKzt{+aK;3;VmHxs|J#Q@%T2&;YOL zdkapR{-N%KacBAU;CnKihxKY*6kO}mG>-B_oxY=dltbx#MGdj)W8sSo42wG4>pCYV z=l-D>wx~W5n$+YsITh{@Y&HGNDyB84CSk^f|5NCAy!s~f_Ynqs%*x8*(a3(tr`lGL z6o()GevN4U(PAkHY90p`n1OP$W(z$^MZsL0f*cS1`3wF2qb3pLzR#;_UHAW3rX?36 zGED74YUD%)|7Y^Q1>Lv>{34VtLClcK`4Mfx))-TG!pp#Dw<(Bn$tU{fM+jN?gNYB9HX@n7`zqr(>Je*48EkYe}MnttQ58>QE(V`Sxzr*|wI~MSTn5 z71N39Vp|Vie%4fuiH&WkSeTeFvn!49^Wr)Fq7d;@_b>MQP}&6A2=5n^qk*t-V5JSPk=;HPn2_aAwwmE82i1zH#XKw)zy9Ey$pcb&g7ynIuu%qARwTCIV)@`a- zw_c8}i^} zzA*WoUX*`$2btq=wn5`#x9D4Av$yTn(ooWm>nencIN7g5XENY+5NS*^NMw?{2`K_o z!JFl2ocOC9q};YJOfEiHuh&cD#RMCI;PJEQp=G7iQHq z3Pfvfr=ws%JSc2_d7GPiso}hPo-N|RyI>qHzU^J_vYz!lq&Zav;>)j=>|*le*ZY*n zxB+pAmUsh*=E#<{m6h2Ml*N_@&%OM0T|>fT6KteR=rc`r+0#K)&S|!NPfyRwly4vu z_8TaXScBy`+HQ9VNkqgmvnTZx3yyRVGc(hcHNG)6WF*Ruh*GfakBxQW&Pm!e|KPK}1CVwh(;c$i^`Im1g9xJ^$Uk$># zItzVuj}p-i>4ZIJVJTmWnA)Dk0`8LbgVE7ZD*SuQA(na|h_d}abmZZJ!GlnJx&_1$ zEWuI_ka@}_4v%OfkJrE^{7iJMHy0xLhnDM)VEwMY!G2lAlL5?Ueg!~u2_;kJo;S}L532<4)Hs$0i7>>7)k&)2?=EVJ%80idlNRX)tBHL>HhA3CgK&qr4 zPiyQf7KiI??oz$I_lO&h=kYzqfV1TwzNMCZzREumWvmr=`@X>b8y8J?Qx0CAgVNC_ zjttIsSJqPASEp}ta&Ogy4m6pYwvRP5HvN}&N8(o6wsINhAOGr&^K(Ai3UK{+>O82^ zxKzFNuJK?%XMKNgLOVC$GTYea72~bo?HMus7x399b#AA>D`&yp*2yo+qFiDr-9bpM zO(y>^1s~GT-~oMrDWA6mzE}3OBYB~hoa+w#vhq0L($X!IRN^ryhwsr}>{!rcT80nV z<@!lU`aKcjGZSxThMoxEtb~cHDzCMbO(B!2xCHCGsCZ_TS9Q`UAvf|m4bb7d3(AA+i$DfU;oXT8srD`qpE)xRGU~t4tg;AywTQJj)X18L!MC4rNreKx) z^`b+0k%fAnr`=B%Axq2X&^)$$d6ooaw4LY10~>B;t@;f-40s~~1Z*f2SW$%HsnaO& z@kV8lrl$I4ZrYZEhHbU(iR9?_*$>;*^v)7!)E^*)`~cIvfBg9I{ky7;jt+N94Z?mX zm1kVn*OT`lA`{Z+xbjmx0ag9QYOe(s?06+|f*oK;ga}P7;_d50X#{0s2tY$~R$ACI zho$~T<+7UPi84k2Uap{SOFr#jc+~mGHWW zU_JjA4JL97Dn9^Ct0=4FvB#Ftyz0exY|)h?@OzuYc2Xao&tD*@`2Gca=Y z!;v4jY6)NO#o-?3IB1C7owQp2*I9g9tgONK{of<`cJG}QV#7ru$cmqp>yXmV-+WHn z>eoweac}qAuyR}cr|`Om9`}d6?}kX=m`HY7Vl(dmqtfRPfuMP!c?AA zq9rFcc|$BIT6Oz*Pr}n>DE7f*1MNL4!{l=p+Xeeewsuu5z1)jp<&I~gTTz2r<}D@n zAZpyA!7l}vc-pa? zGFS<_$K;!b^W*S#-NzTXm!9q0Lg z;(fe6uOQ6(_ga5y$t4TS-=Q@Ap8nTwrKi(a;pLE-#VdPhSte?n4OF!j!aJoVk(ozm ztEYYgcxypPM0|UG%XoL*f6%evSN8Js-m8l+`<0`~_qXPEAT6f-gml3SjJ(_zX*=o? zF1vd6-nsSH-_y-L#=FCu)UXphtTOH2|2(};Du45ij2e3mvRjuko{!(0^|72TtemD= zu%Ng{D~&o>dPu7$F5PtcXvhD0qa zZuGz>Ap}AI^}>_Jc(AHOQ^q$_?O?jlfRDCx>94LsQBoy*GB5SFfPwO{3{~Rp@n6c# z-0orx-V;!#9aVW0R{4D%fZZNszVs@jhn$}ka~y!(w0Dpc;(ItzAyPR4>1@oE#Hk#S zFF$^hwDs@*5p|YPRd>?0tckK8|m&&X{7TIA|Tz}lF|**9U@)t ze(oK2yo|#K;sde&d+)W@obyM;teN~YZomIDVY>2sx8+{%-TwmZ)64Yr=Qh8!o7QV# zpg+OWjyASEk`riW*1mU}a|htX!WKe?v_l^8FI#;kEwSpf8StOR@M+7FfFx$j)cu>s zDH$9K;pyk}v9u=6Z@mEjl*S>4jnL4hs)ri5lb@h#BL2}?kgjf7;=0Tr~x%&}*Q_2BJ z0co#JaD~FGf)5d*V?{18i2sreTg)P^GY&?JQe28l5sd$W#_Rnd@HLe{Q{hP9@ZjS11~pgT!C@g=(+TJ%fx zi9^n#ND8vL)_x@%B>d->`iHxV^iUAufPk?{gBR)xQymOU!3gu(_TE#+ELEkzkv6mY zqLcokqEyQvI$W>mU)S2bE~$+elK5xZZQHSm+w!sszk6+IsnCRo8~e4tAEu7yo@SGq z(qzZZb?5XMgGcd}8tph`J4koh@0+ay#nk3!V@?|}n|@;xOvn#cKc8q<(hkxZ{e7V4 za%B9)hihB6dK+-)w9P=qxV76O^ zu-yE6x)-DVaja0tYskBNu~(?1#h!nz*`)DqVhNB7Ya9E1(qRt4)v(v7OsV|0>tET9 zuRK1U>bq>4*4tw3sap%FNE20}X3q5w zI^O$OvAA6>D6~&E2yZyz|AL%=|;WWI_W@y`vUiA zvop48L%7vX*LqU#?haPQ{@)1xE7K|0^OM!u1Na!tCdXrF6*Q0%d*gqfIxaYoD<|f@ z3(YIN;K1VS!edCQ$RZ7xf%&!;{hIdI?k>C05@%8mmoO?*D~D%sJyatGlg%AY_Z#`~}E5PdxB4>lAs?aTc?Wp+q z!@^@tUy1sEY#msDHxSk7xuy?LS2h%p`_6*&=vexVIW;n5S*J9P{$2IW)Y6Zc3>*Xa#1B9{Vq^mu2+JB46*U?`2_;Gcc`Jm4tCfJ2`gm13Ga zY-#|q0a3*ugWHZE0vZ+7X0di3uxuT(O3=G64koQ#7@VTVy&xV(;RZhAVUPHW}s9%9c=y|O|_jViYM{1ZKMsg1biT`myNSFAwV=mnK zLQoURJ=BaGT%Z0bRvxsSDvoQfVLXS0y=7YQCD~_wdhApBy|z|;GR6I4S>W6KB6$zw ztlRzEPr!Zs5r|N3^J0iwik|=A?tbufz=6C(`z&7>Z17*r#e;~Bw0<% zy5T#DOCu+4S1I3Kw%+s}w=t@G;ad)jTfI0rQz|qC+(?+q;n+sXi)h&nHcs9#-l!(! zSfux{l!e|>{^5Zvd#9&sZeIqm-E;h&2)OJPB@jUtu{uC{jANrTDf%3!z(fW+>!mEfH$amxOhmzf~MO>(EuI}XYkwYa?$fKdDSPm%LItysCs6V0yHg?3R zY7j6$ia-!x3$0yG4FyMxlI0)s^oQIhr5A8&rm%SG2eJ;hV0h#fUiAQHOM{CusA?dr zuy?yUmg^%FY8GSeDk@mUEM68=`hzILb+%nqbl4Oif`F_41qmrBDa69{=Btq{V>CoB zt);5yi&-|FcC|c}F^@UNdly|0-||v4P7Wro*S4?c)H9oe^tHi9D}T8B9VzCn0A>Vl zY!BWP^!>m+_?sui(bxy7BPmx>fuP%t&zR%hG zIjBjWtsj7__d973&kGsfG<9L!gM>GL66K}e`QksA(_VLt<#u{Ik8=ihtGiuw60cki`_dnOBlQBPC-w4E8{f&K1yLUF4|O6W*6K31l7r@I2p%?Jao z00VLR4sYxFz1CoAdPW9$1fs>8T#-1_R*_Phg#n~~KAM3A zTq;f~F(Zh~NgrWGu(BHJm3dT19x5>G(BMPh(4)V8HLs}wYB~_8b|KLJ?Xa2i zXu()qN#_LyYoa_SCx;deF#-MuJ|3h(9%<-%nLqG~vyuK$p*yn`*{jatQ+W$V-g$WF z$c701$k<@KVjL`EF0m1T%r-|?2G=Q5X<1J2{yktpMpytoO~z=tLyyd?rR~v4^3V@n zI6*F(nv@Z-_ap5Pka7s-OR<~t^#oCU(btXp-sLV-iK4x!J|Dim0-8n?GCG{7Y;~?M z`&o>_q+D9ei21;G7a`tExS@ulcD9yygsJYyGoe!<9E2SC2p=gCzA}+lKDIayc2l}q z3=;(BVsNm$kvHa?SYD}NiDs;faIB8NvMFlEL3&XuZZQ7m>m`;|<@|vp}`5o^HXK-zT3>iCA@ZI`F z_vYkRqn}R?-Po5kXH82!*|&PHRi}5zojyQ*SbxpHO|01a)!0+Bx{!tZKSrfP8DDXA zBV8|>dksUf-Er(7g_RkK3$2p|V^&CQkSpUmB+0xCR ze!Bnq>UnPrH=FkxJ3Z1XbGkCEGSxKTRQeR$v0gg9T6<7wufeH{WcNH1Ke-3_GW0!~ z_W5ah^@y^Jz4DUsh;NL8P?kSKOH1WVjPYjTvSXZfw<{+}gAJ8C4U9}u#w5}xum9CI z+IFAMKc~Mo(8)y;#yi=)LHpXjIdt-roGbow{@=~F_&G-%6p^3`C<(N8Tp-a2&{wJe z>F2B8k+I)7u3r_{1HO81k!PO*`L%GN4tKft5vk!`+o_3`Kl?~PbpoF(dKm>@0UrVOLPXoQBdk&W~9 z*s*VEI4Y0$B(yB9)+`f&1@a++(o6k^jfKrQf{%q+`_YT~6gHu@{-^gbLfrdg|OzjO#%N&zz=Y%&;>FHuAIP$X7dH?4*F`7zEa;fS-1 zuVzEZiC$oXvBuMatFG~{J7MO*d3FcdYIJ%o&FRZRyJmtWh+>KcXq z6qcrRJ%)x88uL4B2RVGPAxd;LNccNQ{#q`Smf2}^A3E-Ol|E)gNPOfEQ6gh&kF0w=1Pi+1PqLZx+UNCA-8COi$I`K;F3K`C=4jlDcegj~w;$Eb z^{R;vN;Z?eY_0s=SM=NY&wK^knB*x|Nbo~VFFs;^C1K{492R z0fFp>+}?uHS%Pgx%I2+vT(=nFzDZJ=zK2CQoU^*yfZt=~^EScSLvcgfG2J+QOKc0s zj3m1|0;_oi*b5SKZk!eM{e<+RC5(j|cUPr9JcdxL%+%zoo{LLnYDXE*9-8<@6v`BI zD*c}CZ9JAz`*#J$GASbw$WHd6(BHt<&dkP!0_SVtlx2a7eqyfvcW>XnC8gdolc5;D zuYJavUO$F9SGU!{z5!*3xtqfkdWaAi%h>N;7S05C$lGqMDk~RjuUDk}9Q@oFqonz^ zEk&-Lf6x_yK#-5+-;#vC^-K4n`PJYq#$hXK>tPc%twT@-EY%OK3{Bmh zledQmW&+6G_z}H;jBY14S1z9mIJ~dvPjzI(~WT-bCLapO`|&PcKh;pnJ2xt7n3gWw{%s zUBs-Jb^GswQN($@6OM@`>l54e(7ZUt!3>0A zb;-7aV3sY$#32gI2!0@E7H&PR2dGGboSPec+oijQ9^vPG{#Az+YN7Mel$3fCwyEXW z^TeDdn}G^kVy}k?uaieo5(=p7a8kO1>9Q*b4p~1c~g9HyJ1h2eWheZR%92R{TChNtR zRqq5>=>A=wc(C%b7X(?sx4y1Rde4i1Sc>jnSMO4;S;Lj}YwO~+G)>$W59mrZiSBY&xhNzw$#%XC?5scLw4OyGm6DSBd)r#Y#13ymO%p4^wxjg2 z|HHD$O=8|wxIElV-e2)|bdF?Ip+z{7dlE*X=n@6WDhgkm-7=>y{Ujpc;$C;lRZ#@R zkt38l{OK%%9ihZ~C%y!B^x70(m=4`mo1^S-9QhZMLXIA*a>p3ej6LVk8E;XWuU52& zb%XV{*WuJr&mT&OUHchnpZGKeFDFo)KW{ykBx-m`l8<3~Z*a*7zxzYt6DO2l7L8GT zu!p9^P2lyI%cUnv`)all44{G1Z8f0F$G-JOjB%z&A>-S}F))qz?OyU0Oe! zRaxI{z9s%&KM;`3HoFv(yb}b2nemfFm)*@x$l1w-)>m2nUAaFhuN)PL1|N+Sum1Bf z>`F`f?kZ%-s#ECrj)v~|J?u|_uE&JUcE_{(Pg*2T z?hRzl*2dSN+Iem#A|li8zOp~mOfNqrnDn7<#s`b{Iio{>?ZqQ#$nX;rx0EpVef`xf ztcoO0{Y_e-usoLU6Q;CWrQpSKjoAEG;i`rD<>G9Q3K$GlS~|2xZ_OA~9YLEVT9dN4 z^*NsF6;`NWyM~RWts+%oZotx2`$`L5kO^Bw9sI<9t}7btsle~eAF^0k_Wv2;z5dg2 z>T}xkrznGpx)`sa{crOBu*_|(tZ1=cr#aJ|_2lIt2shrZGJF3)8MpVia>}`1KBz;$ z)pvGiQXL%M)uH~5i%|R?Cz3ps9w|W6$jWo)+5B{Llal_R<_p#aG>3 z!*`mJ4gs&aUXa@5+UJLVoc`9z`dfyhQ9@rb=6z5r=7)DN`QO%4!iR%sNUFm(S&({u zxMj3}$#g?Qjq1$lZ9%h_C)c+C{2lnm$A2Tm_SgG-E(g=R#lB0|hxdQJb6RU_Er}HT zWCXgiqR+iNb6TS#pYFGzAIYR73Snu&R6)%jW&|ev^N=5Ai&d~CqYHq;)XG?Mh-Kov zXEPsQNu8Z!rFpm46jQGz{1N+>L%pI>5{Q zuo_C!p3SLS9Lch2Sv!Ckfrzo~*aX7*`!>)2%c5bzNK3d6s<#&)xqNM&h-$>-dXcx_ z?_`)iC>4yTP&rMRw_pa6-%ayAUV&ri}Lnii!IpSS6A0#^a8Bqn}{1N_5$D7?v!1(I-lL?e|_34 zUn(rxWmfcgdUJ>h)AZ}N{itzhWjarNMNOPRM>NRotMnx_r`cvS)t=a6uHi%M!b9Mj zWA*GMG>E;2=vrOFaq|HI+5pkhU#!J7PrGNI795B{?#$zssdc;Kz@EbO5wEf2L2I4j zh(>$|&dtQq@#Rp^ID*Dx%J7{UH z$slhc)H4=K5(C)5v?bG>m|UFY`8{*B>Z+u=fo}2~+P9mDVkj*)IzEoDS*BJ|CxDAo zU6WYQ(=wHoqDuBbD!_nHWG-?B1A@o;1`-DQdBzc#2V@htVkB76$V-k4b4^!^=f^&zk%wihKf`^hcD7>G4uYuA|BP`V`2T^%dRV4BYlO*R!REe$OVISvH=7y+}r zyaCbvRr{q8`$MHBY}w&W?(2Ua2bJ0Lzsp-e?y179typSvaenlsEf6*w2LuGDYQI9a z5;4i;v?vcT5RuSg3vD_&y4edyeH^=bORDjCBU?2q<%iu}x=iJ))?su1LqZU`k)55L zv$Hc08B%?+TXM})TF>;#HWwSHI|>rlOo(ywmpT$$Jt%dD@!wIgt{HeP+-bQO7x;WdwgE= zJr#;UiwT0&QRKn-W0T~YRLj38OAI3e-V2hX7m!F=F(1Nx-nXx%P$4{q9!wTde2m8u z3~>SpI#%k2(f6<~C8mt2^^;m(La{}Y^+%_@5FqSuw&jJgWFGUB%*oye1c_$vgIa3M`_bmSl?6*3Of-Lu8Z)D~)W_#OIXIgK>| zVZ}J0+udc@x8DLz<@1SKhtuu5RA!SJEvb0a#`7z}mnm$lwpinAwP-(h4{YTWg#Fx4 zV#_aDc7OR6E@53=q|~+UOjnrNhM5v@|CYc~eCrJWF6aMQ^Fs~)({((6rJ@D;QQ$P< zukhSuZ16s%7JfRFAal6gwvUrboE^m59jRu(mlD$`tb@LWgC)6B(7jN68UEA0GXj*bIy7H0~X=~0z5nd0-v?})$4_E;8mkv zOOY*Z{|ECEJoYHQ{P!=|5HAEn+-#{nL5nuRKYN$%b|j_wO%Tn(B*5E~)7ma6OF%Tf ztAgT%59lMj?n6v7uuUZl!YRmW=a)zR-Q1KM@|2onl22&~U!q$we%GwKy=o6Rcx4vk zd4`37@y%3I8E?D#0>bxuGB8}3BE%rm5L=FvhwK&NxI-eN?AkRh4h|mMk}HpSQI+TF zz$(1HZL}a$a4x0PzRviLNUys9K$4?`h@m4E$t}C+CdS((AcZ5Ll_E7h6RjKYdj*~n zzbdSw6`{e2s?uPHB%?JgjjJ^6J{+)Ym}QqxS*_-7d;`giNPa3*Hm1KSXdewB z`WIc%W@fMyENxakk)-xpv}(Vlc{&z`ad>W(C+!URGa^J8k0(~8R5jStX_zU==Z`zP zWK*$G>O<%23xZS^N{`;c%A`pe>>4-`rCxtXE)KH3R?t+h@+&xu`1MQ(ee$na>4pm3 zwktsMozQBj04Z?47ZzBXz1;l#PK|`nWFCI1#AJVN4OL*U?S+}g< zzJ8=hICp3GHyj=RGm9mXa48ysd?aC|{uo+X+t@h2us~!l3ul?& zI5(D+y;+nX3qh7)i+&poZ>ggd8Y#*cgO3-W4CcNNfA&v)Pv8pKEw`}Y4(KQK^+oz; z-A*3>0v8aP{cbmKKk;rSfjUZC4quT%$o(>`qT{JKlK2ZLWbmt404i?{5p{>g7u#KT z;tiER(+iRx|0%Kn106To(3Ocein7`Bj$tYErI2?hD(}m_$=;g}FXvN+NH8ri181;0 z2n@^yl{4N^K@}vF6nUl0mgW!m`ouiOvjszp91Lz>54gZVkZe9$l-AC6?{rEsEL58v zhwAdX1^e=5XonB9X)uKP|Jp0z+!|6jj?@Uu!xOiYmWbWdNZG!B`p+_qbGW~+si6S@ zS+xwqY)LLIZ_lVLoN_wOl=KN78e-~g>)_xa_#lQ&lP+0jE+#N?T_9ta4kkYvy>J%c zSp+BVTlP zECYng3>`#~qLC##@jk+|eIF0?kx56IDdS}r^s5+lJOR}^>(eeywOY+XO9WNAMSg^F z=;P?=e-2XfOyAiEYTL{fW3#ymU19)XoUPQ)8LDN+t|#Y_j{lWJ57TiSbI5F-1@s!% z%uVAlS+Gl_Krwr4xH9Z)4~g&)Ataoff|_*i!a`HXOIfBXY(GC#GsaR8|E-epQ65u9 zu$W-m;k9r1TOMn>;xV_F{oddifq23V^66C{@5f1fx=D{H8C#l!8|7*oJ4RP>63X zHG`~l$U=y}KqM(@uis#cvUbflRx7lV>Gi5#3LOKYJ2(4Y3yM7E(f+g1>3+6-^-0y5 z9uk#5f%$e*=VM6tAR-c1t<~kxzv+Mf{ylW(C-KFHBirq#|5J6zX4$l3sofg5>5N5} z(ip~$q=$90$OF0Z@i99)dyDHaI0~}j{n-1>+x#E)!$9P<CGf=2i`^IdDS_1WNTC_9!^&8LA4Q}ZFl>$GpeoUyb5e;tr|3J5@VWp zA?Ff0!kpE6)KZM^ob21(FP$Lp{T{Bq*+{cLbi*0iCu(>8xtXed+D)(ir|W5?}f7V-VwfX>|G zh`A6stQEM>h0d;t8L)8*NRIX_+yuv6vuGlhziA_T$9hMwjuNpZCBzzAD?sIz9B}_e z-Fh2ZSiq_b>ZrzE_*0eRiIWI&u_XZCzZqME#t5@ILl@$%A^I0P34e#2BR&6~*LmsX z#N4-p_)yN7dM5Y*bY(13X*OF%0ESAt2j4H<@%=kz2=& zk`$}9{fP8&PNNzwSFSPEpgI*?aX%nvq)@_s@E^%{H`y)$pDHM2T3Yy#;Avrh2z~kZ zzW&JW)OmzJ;P8xWBO`&-n+C`l{htK(3sX#@rrA2;o&hB0JpSv03J^0Y0-Wgw5Jb`O z6vFHcxM3RIi+?9lTEJSe*1unSd_>UI)kVcO&p%4-3lMufPBTd3XsoyXYEW_k4ct_g z`1!nEz6|(oMgxJMvq@>0o12>z73&OuUoZ(;m|XSp&}_Ut>a@VhH>0Le(O3p4K7r~t z5IL}>gbyf{fjFg~&`)*s@FI9Gbu^IBgXJ`$kcC*q!RhG zP$L$OkX?_JaZ0E3!hiHbsQ4qfZ7WXut5}#gG1GqUHg;fKcST?u1n)~ z&HEYJ^#a~&k7##!t1F(5!_0ukgC zL>2+<-JnArFo4rKBtfzRq%iBsM;*SbSg|2q;-#A6wz7-1Qy*aQT`Tx%OSHuP7FDHm z`dp~J__bX`v-iL5ZX>#6y>=r?bcFR#q*k+z-^#?4{{TUEe}0_E}qOj#M9lAZ>HSQa$=w2|KPzxlYFGb8Mb-G zLSaIZOx3L+u&}nawz&AcZfy6$5HJ16VvN@yS^H7;-;)M861>XvC?5N{$#Av6ID7mV z3o7GqWS@~Co>|QTkpCy|3Z1=x)WNM@_r2Fs)Vn3bh;cJ;b)9v{WI=r)ZtMQqT6X2t zl2^|M0>=(sk}x_r(YE{0+g4RNMy8z}7K^Pd_77=0flngnY%A`Oa54Pk;U<(wO{PIV z5#FplTrqYuUbua=S)#?Og<+PbB^@?@Y7No+;FwouH$67d={$AdYv&Kgm-5ACIF43I z6i-qa9Z?j92&u4ThcB;##xpWJqV7`K=KpsYF^VvL-n$-VcDK~mA2$;6o1~@A@}8tk zF{Rc@&~G}qOKm$cjgE++wp*_9krw!{)Nb6esa1F>;^)_->Zq$YWUNE~SvT>0sN)ZZ z6ogG9N5@|-ZKm{U@SB6TM@L5^(I68{?ypgE)lbGNL zHuZfnXYL8!04c@xmG63Ug~81Rn2MV+dkm@DH~y&t(I`je4WLsn%x$-v%em|^r|UOg zOUs|r0;KfgJQpKheIAU#XZ923bbd9iXAZM?OW_K#g?6IHD~yjJtpECK-E=HRiElm= zs4*$R_xG`MNDyQa6mVii^_gI^_Tzz&HA;yfzJEe+);tN36XNgJ5j42|PYdwTtbKCz zb`g(sjt(<3!%D4-7ahZL&c$|#7CWjb2|OSdD_U*vr${e%rr;E*=`lK`cy0dfPcMNi7gXw%%jJ#d!>=3Pl&y+#WB5 zG2hp4!(;V1QsxZDo_ISir6_1WHClRlQe|X0;en=yTA@^d6q3IMc3;Hj(z%pbbWR6s zQLT@q;D{xfBPUY;+$Gy39Al}2@dtZ4rMDg1MKwPnir);7-Ia4ZZYVAg__ANktVORl zkM}YY55?{VuGUU%a1M=USZv@K`CTk^PgEuqLVYQJ+JtG(mN%>}E-YN`2zMB5B2zzH z6bscgetZ500^9B`6s_%T@0ZPmGi0dvTbkopMPOawiD_1*Vn%`5g$hL^@FZ#BFUUK| zx!ibvPM{gtp~lIU22)aykeWE5bk0wFPhNHv{VrEp>$N*pKdUydksHC`&>z7;hCVGu zRZ`X^1HwtVVP;+kovR;=%I7h@8>vvSCbJjSp&|&srW-uVSJ&~L;%=|9n)x-?epPqd z2ee}#eD`@Hwf*7Xqn-*w@+aQQTK?1arRo)lkHZCDh3Y*o(@n^fnNpD_Ty-eP%j@{-s5mrAfB$A4OTswp#EAe;#qs|Lr;blb5P*p?34eBYK9${WBNp;E|mAF(=|y z#o=PgnU8Qrmb!ABl`I5-C{&`8M;t^Mvc4Q_)o870;ZN0OxD7}G_R!F9i9k4UB`x-T zg1Pu=rGAebjh{#|36;Zds*e$gwH+NB`O?p`Nu}GtC3$VR5>2(6iT!Fl z8rjZ}_m?(uXbROd;t#dux8c)+01?*to?3lopb58j&8?)#fG%1yhAA`I>uCb z*a+FElBB?gJ_c(7QaT2v7Gg9W>j_r;X3P=(^*5*PW|s=w;X)&7dkvq- z=458y-}}czD}=15`LDPim05rP{;e=mVfnIG#3=zu;#IU0);JX&C5F?CwXTaUhGjW0 znSIBOWJ|~-72k@EpZzi~zDo?g=0+S*I% z9iERp+Vwh4qtZh63*#rNZBrMm3k#ZEN4V{FgU&a_O^Z^2g=40^d-q1fuu7A@P z{mVy|E`-ux^r#Tf4%4hMf)RZLx2~h*dcmDWhw(0PC?#Xx^fLJi3{tC!^l%DG2+}YN zSbSZWy?;l&?t`*nUXo3%qqQ1*EFlP-u@>L0BaoM}($b-ko}TxUw#P;PG{5B4VrC|$ z43co?jP5!;wzWwdOkDiASvS~WLI7O>ow?(mS$%zdA-BBvcY-TEcHdw453yjTP$H^C z#*wm-!t~s_BU)VT#!Yv5cFP$Z5LMYI$Od9U;-m9R(o^+R+I4?LNiJ*Gq5-`Ly?TX2 zuN;Wc#{*##dsFDofyw=;zdr^Yk5$B{clvk$4>6LJ z3R_(4g@k+tiD1G@1DR+9a(D$3CihQLF#pej$R$l?5dZMJgxEuQ#qqb7OjDvapqpgs z!HUQjWRTn8ms`o5{44XSRi(y>y&g+NWJD%xPNxfEL+h!Z;qGae%{g=)XF!}I~6TnluDw6cl+#ec)fO+dMXP`NY(QkDi*pd z9cJ!$012ZY%X*bv=m{hqJrfJx1e~0V0X#9thGHCs{$fc8AB@L<Q| zwZXyrI*>T0>$cJ#bEvI7HK*^Fwd-M?bh>IyA_pdsL!&A@L}k9L{kdX1$TAzzm(u+rnC@p4qn$;3wG2OQzq| zPS`9Uhl#awW<^pPnkTE#4 zdjZ7PVs7OiP6kvQ#OV*=1v7~$DJe}&yuzr_^69f$1!gHcaUL5(F(hi6_KQhf8Q03# zlFAgpUkC?~__$vC6Js~0ti1i~3n!TychSZRF>_P=o~VfNDpvmZQ}s0#*+z7Ml!SzW zNM``O62xnY?7KER4aw*TEmcK;l2cEvtcbjSH%qkZ>3iP8LUt_1`fWaDq31vwuDPYD z%ZVc4<@?Ul)JxZLt>5~z47Ei@fntcGGVqpS)8YM5lhcpBcKJ^fZ-!_P%}^5;;dRV&t}Wm47<9Qs#c?EI(c~;>?8~+a$zb+U`tw= z*$J(r?}KL8q|P87d|7W7*_4hXC0U45$AsSdhI~SRG5@vYU$5{YFwpZZ*O0v zv3#{R+uqeRR`FpylN2tX=sU0N+ormLL{=_AURL(hnB?X_g{X9vF$Wu)ocq;kVt8r;ogiM+Qm6Kia zm0P`*;>d<~Le6NiJ@`|z@WWIS1|4$99N^b135YgNv=mX0&`Qiptt99G7p#@k=EDIJC!sR6O1SC_4u3N{(#!43g zspL(yny^lfFY4`L$~8gDp*W|yG0y9f%9kp{MkjHp^F#cDLv0d}fvGx(aIF?WV^9&F6~aCi^vhhhLqGkG>fZ zn#GLPtf%@v=~mu1wEJG)(0@7^?0ws9+G6tC9eX@1MThq8oY*|J;C7|;mEhbNPkl;u zb{e26-TzX5I(`NAH`}Pu4DQDczsL5`jE0AY`kbfX-TyX@#34lVa?J);@O)#bu!FiF zLIR#c#n2xWS=Mr9uc|CrgJAe(FooX`ud$*4IiIGw3FxFm(aUvfFq>Y8i1vXX7*KLy z2PVtCm~%;`dcIJR7F>muy&Ibm=9M;JK%y^|Z}!VQ1?TbQNr(4tnV!o~k2aUzhB0y5 zpXZJz@;UFDAmX;2V|Cp+s~NgE7knkARQlAY|5ouKP>@o_vwxpaLs0GcJir~FOUG}5 zsTA@i{N36(E)L_s$-%x0mMqDn9P1cd?K)B}LWcmCKp-LjJcQdUrLgH($`rDQ?9hDtBV8)??2j$M!R=Y1S&ysHZqCRSlz5**VXDX z6DunxWwImT*YMheXjZbkE#;4k_6+`&Es`T4fCe6zTjA}?bI53`!CA{CE7gmxgkT{y zF*v^}d$mR98;keVZ+wOMrJc-Oo%9pZZ{bJcRK7(0HSJvyeFb$fV`s!a&DesbL8*Wu({gx+f7lc5^s!pVBE-6S^)1&ofRI zF4i*4;S7e|{|K-8LJRl$Tl)RZi+RiUr@K-*`1~}rm(!UgD_fqvo(kBn3;S|A^eY{R zmj}mxC-6@V-#=RehA)Y#HmgAigcd^lEjGE&nKfe% z59XCCwfmy~b-H_{D{jwH0T%c2a8BR(ysu1+K@m1d1h(Oo6|F-Mk?;~~O%yumlB$z5 zzqLmP``)Ej9=Q#r3{QE(q)35jMqu{0EE%4Hvgh}o6|JG!+1fs3>(V*_GODFblpe&2 zBoH-3W6a*)+}v#B(C}^ibg|vX(C)2&bW7e9RurogBFPWaGPO5M1PQN;i@_Ke9s@s( zzK5fI+8g~<{#cjU4-l#l9S$ZyApSH$LX5V~c;M|Oly!0aQsB5?CZL(pM(3SbZ>*7{ z7vpGMdZ1oI=cpI3u9a4*(kVJuTanKgFdp4wu?wbD5F{WKD6wMCyLYI)e~*U9Nd}kR zZ7*V^G{rs#dF{e*azGQ!J7!whzGdFgNECdLpQ`uePhTY;Febjd_nNC9T&&*jYTA$R zcCDwxuS|L^k{%$%Mlt{Lh-NH@DqE99plDpp+y`sid72pgK6y*PMV{dX^0S`bx8#kQ zOFxge4_<@RxRD^O8;>@e|M;W#^{Fe9_uf1D=VJwe!hE!6gA6JjACH5t#!(Ovh;~0p zi`nqD5<+KC&n>%}s^piB=ljy@Hk$>-Rky{^)m~gb-sO2;n*GPMrT4UV-2`*bQ)TL_ z4fH@+EDg7=h}Ad#WOKc3{?Gg3d!ms0?+GI9-P8H>7yi06$zLDc2j~?~8vl$deqnrC zAM6rDl2f6aOqO9*+X^C&5_bP`cRQ@|b&3J{P}Sf z>uLMVp%ZMc$m?oa`za^Ptn%59>*-!U^K6NzsiR}N>OYl|*C`)m+}+MS6=eNs<@WFt zukAqc@%bqQOYbM&gMpIGw9-h|nG@7XEBT0ixwqh}7Iruf zmF(V-pzHXSk)5d&-+D(}>3hw;c23Ogvl*-ZL?)cmw(+JiCnG(&o8_+$WbbHSv&pdz z3VxC?hDRUaAIC2Pek#x0G!p)R%SVRhP1kBLe0-xTxKdiLCh|$bB~nZ3ePMc5`q(ax zmi83u+$?mVJF;8p%sluOD9EuT|I4r@l8i@1(EifJQj#>qIOJRe+eq#2mqKasP=eC; zd929&@m~(#sdaHJ*J*qC4T((i`wbL}r2Nmi6N^lRLbUmSh4!`^&n9St5)#+yVH( zi+@zFJCOo-;*ztbMw{StB3|*{oUOaXEsprYwNdyFg@MTpz3^oJlQIuBV4}_Yn>lbJYcbJfN@B6{E zmA~Kk2y0s4ki*o)lIf*8Je{BHnKWE~i8z+@wA>|&dpUMJw%~r!kN33rk&Em)u9i@- zr_l0M9vg1`x+lu~hfD?z)AD?K1+|?+>sC@l{15vhr=Ydtk?mipi>bUQ-*1n${BlvW> zI-hX^o={%#et%LeLUPH5C&N3RU1t7L;iey>_npIGR5%Y|{jZD8xwC&e{S^V-b#J4t zYlhiG$2<0uduE;UdfY4GFX0LdmV|7#nc;|HCAGUe05DpTw05n2+V=MsJ&5U>9+4;8 zVI(F5_yLC0sL)&uo~o{{?V1X}*-gwCH`h|BHw6NLzCIxob|cR3>*SjoG5Lcr9?CSu zRMgs9(BV|(S1&pZe9elKXlm=~()yaIXkpV@j&@x&@e}m{F9{7!e`R>DxiRFy#1N;q zJoTy?@esS3>#WUo&D#G9_4=d#BuQTvH+&3Yae-#ba-5WQlacXo))sHI&dHT3LzdFG z3eQ3d8j`PNO^RqN5BE7RSAzir2ex-@OME7ChA2TDyZkS_nfST*5{3$Gy5z;$XBS<- zta%+j0pkx(Y|>=#9bD(P)S`OclO{XG>xciQ+_qUOZGvq+5TH6FVuQ*7z68eCfw{^x z9#)~u;q4xl5fiq0+cFs;@<4&hCJ=AMxeC&aRgEe&s=CpG>;dZ~>(lkWf8V-;3mV;E zs%&Y_wpBlW8t9OQ&*!2&tNtE5R(0c;9$xtfOHh_>u)RlCRI4NUf%Azt`9x5G1Oyob zB`v-T^=hltGEVl6QHrP4rzV4<;s;6@LF5t0r-MrZf?wcRb;SA2gglqQy!KYh0o~hP z#a^F#u4`jtkK5jT{UJ5GCBK0hN@|Ipu;CvWjZKISK|q{9^pv$y8MR%}?%M*BO` zoRsdaR&Wp@^m5v|%@P;#A%hOC({fmA^X#bgJHW|4)#>|zM!Q_5! z{D;+AyuTqBx(h0|TQ2n^=DMQd=yD&^Um{ZEc>rgLbanEIQ*svj_V)1y2fK& z+Cp**W|R6fd%U74{vS_o9Z&cF{*NCV9DTH5;^>;rnHs||UDMrT!*m-*O?R8l9VRBH zr#q%&9BsP!K40(8?e{x>`3pB5kH>Xg_v;=gzib;$f6JbvU=|M}^QZ3=D^<5c6eeb# z>Z|;_9u#7??mLAV5d<|NWt*4sbpb#lnTV0Vt(W}sU+6c^w{ty+zWnsDXRKVJ<|ODc z-#-=URg(ni6=}(8!W8Lh`zLI$wEZxoU#!^mRz&`fgD{eWA2(+K-95b8={`7o|8^ll%JQ z69z1oF5=j@7^F}!WZ*UxFBieLmn>5<&}avvs(+TzWjq@YjWDyFr^OC`MTa=)oz%Bn zCrwgI{9*uR?tSYm8o1S5F<1TkISmkUN!eNVT$9f!boo_!i!T;Tg@=)S} zPXe4npnL(n>NX3r(;_4xy(K*Vh2%kXTBu8}s7I@3n8DVDITWncvZGvtX;Eo^w$IXS z_OUby&I^QJ=Nr^yZs~2hJ14zifq`Un9tJCimF+_`_D<%-zj9CxEk6rP`I|?~PAdW> zwHi zu;Tud?V147_S(6oaHT;7Qvxa;Wsr1LdzQkCz+!F@K{PWBd6;;Yp@}vgx@*KMO&SUn zaSl@vlRTaHA0FxbKv?GR=9=xBjxpo($H(K6qvfAG;<~)j%j-V}pBvQWwmP~`Zh>6R z+K53egQi2oLfR4M^Q}*P{N4v>lek#_g<`4FD14yda0ISgJztgJ@}q47gIVr$ZY7Q% zR{L=xV!e&)@`O9HMxe8JqBr1r%!yksTQr~hWH9k%hu?9Jbc@YNh{+I}YSw(J$iK6G zyII1S6>Fu5mX3>(YBJ<-{<$az|6;LH$8vmyb01X}8Rn6Jo#!IX-I#uT>bkFFJ%6IN z%i;d4^@dN`fkqCbC@jMV6_ir%wd&PBaCJ1e+Tyyt?-9G&V0GCn>G4EU*-710-5XBE9Bb*48>ML+;D0NkO!I zt$^E`G*mCez0|5AX;L;zd2Q$;wd}N1g4@pn@~ADV5RO(oRFI|G%Bxm>n%I|LjkLuo zb}=N8p9UyJCha30C_xlEU%q_tl`vud%i*uM3&%O97LJb|86J*~j!q&Ymv%69bg{L) zIo6e5cN|TqlK~} z7C7Hz<)>>nQm;&Fvi|v|L}}wc-0}wrus}T7lAa%XdbEc}gF{(^lb?WO?#x>hTZ?i# zrwz~OLa>?p#pMeViN9Vaf6^Uaq8?qE3R zpDs7m{Swveg^eMoX*cIp$Db555W@)IqXqz8A|d?Y8h+2nQE0L&FI^{6ftF6H4?S=y zwL~c9g+yzKi+R9l&*R^3iA6phT+=umw6q~rD+&!7*yXCf?nO>gH`JQ!b)B@qQuDg7h31WE$7lcB@q>`=C}h=u z@4o`lxi+uvum8!L0%YYEdQN(Yx#r?PWgjMZCsBjmapnL283C3(Qb0ClFoWlkyZB;8 zPR2YxUvvsccCi6Scp!~s8nOy_(FlFZU`*nS-M}aY*H;fP=QseRs?@{Qi<2$>LP%}`|sn{0`oaNI}hsp&d(X$N%a(0UM z(;OU+Ah)lgV{QQrHzCMUOiajeUg|gU(;3bextQp>YiC`L3u5?I!S-U)bC;z(9@}d;_VHPQPNZACubZ9DrTXjji_W|& zKke?!ZF(mhj(GUbY87ArIZR7W2ZRUX(Lm78w1c`H2=e>=%NAhqoLJ_DI8ap{;W5Kn zj4V)K`(&tVXH<4ABW`gnlcWK}Xs|IAxfyu?S$YUPM{{$45;Ey-Gz$20LI4S$Q=i@| zM}Hn$kRKhv7g&`-=EUb#PtJ*r-o&ruR~w2lG;FZSPbln@%K!S_ANSYX`uk3+eApD^ z2|jekS)x|(qj9K`PCTibmb76NY5ZO+bSbbo&i}JPI%X{rg^m{m#`&e;U)mdxb>*(w zm##NNvQ1Y7a^?!r`wy{0TAKz-mrG4a3!g1;wm#)=>?<^Qe#GG|PqLzLYw)NvZu16y zWv&6O7adYfv8z{}c)G+&*cX_8G<>xLPN=0`eb6$|v7^HSgQTJJ9~=>Sqg!Y49woG` zwyf*_BEGC03OoHg89f=XKrh=#jkSE*-j?t18Uusw|JWH}M*5@u@?~od@OT6U@Kwhl z0FR2NI;OrmbG?0U81Hr?$MV^C_bFPuwL~PL%J;UUWq~-Q>`1~-ZZBxr3v{6L60PdP zuyx1cPnSNmTbEm}ZMAX+yMXNmBL@Aa{FAQ#ltsI@4P>f}hP>jsIeL)Vq8$#8XrR$k zum^c=DLywSc`LjsESgTx{+94kt!+Tj6~;)xE}kZ;`qI{I_@Oy}%{|UP)1k&#aRK8rw$Kh=#!NS_EBf-KOuY<|B`vway}iNz^61eSh7jNAa0`Cd zXL~vy4=G4ru|A;Mi}hI_8W^Eu_KJlZ<&54O zbO9R6ySqF7!^6NGrvEl+^UdxKA0)WNzSsb8x}qAWnZ~8!8v^{mT7cjq1O1q7KPJa6 z%2{d836h4P{)I?M;XP|r^=NaO#8YUfl_<|#wwXg7 z)oX3N&D__2diFDDYsefSLKh{oTI)myto&x9E%>s5U=_{8L`}`aDb2dW=T(4N_c@Ra zOilL1j6|*}6s;uYpEx(}>&<*6Mxw8qB-meoO(+jnVfXsFDbs0u509$vd$ zdJULbijSdzx_hd%Ej>r?V^g%mYA-U| zQg4gRlj|y5jp}`M?q8(wpAqEZTUSC+Tb3 z`fuD51+*bVYwIfMGBJ)$wJ@xE?6tdg(LwXjZ_ucyGG>xwjf;Dy<+8y@*Kc#ZsoTU~ z=FVX3u)}!{6@>ev8ED)_bdM<7fN}=F4B3qh7x1txwGp8Wru~J6XmZKZki)lAe>kRS zy=DdhxK5tIXlZjz&VdiW57s=6bDNHI86KWpeXB9Hx<;Bbv>yUv$$xuvgH_jZ`k=eN zPY1X~#;b`553A(Ozq0V2#G3tN(5?DAU^B-X@CZsU_t&)Ejop{clZ@ zHT}M^-pbIxwrXO@03S~i!$L;cIvGHk_|I-;9OjrTKK}45(pzf2h)>&RGS~nN#OP7t z&8Ex#u*f@v=Fsyv{OFF2BSb_guRfbBQOq%;_PhLlHIa+c3CZMv{=H=#M4NMt2VP zU_1HOQ8T9VNJ=fF)sKPF$$4@n)Rlit22KYd zBO~kL`QenwaMSLrON?3marxHA?{Cn*hw=x!C%H1Maub}3XxZRBOR}{v4HPu4t~k<4 zMg;@K7o>b$<;vtNc>RwDM;?uK;-%ikOcm%}Y6ZsQ4Q|w=EF-WtrqX4#Q0Mv|RBt&V z;c`q8Nei~<_$;VgDwm=ts63lEDYyc`Md=vE5!V3^r@GUBDyn2v7k^=K+%1G2@6;aO z;R?tzf0Kd~7mSlFT{C2`ua2=D-1%CnWg=v!XJ;Fl;^y9KhEOlBua4v{J#<7c(_qSi zqZwdG9fV%i$bbJhAIwxVng?;gvRx#>*fPT1|H|-Btea1lKd>~K%UYSUS3@Vf}v05EngW4cL0ZlXNPZYVQXks7^~OvbAc3Jxe*5+<8eyrlR4c+710NR9v)K2#zs%Jvt=^?- ziYFvgLo^5(*SW-W-?g6EM{&((8#IVS(A0FhPBwAh?#`5uW>( za+??B)S+6>$@taYvzv}j%x>$={yjhV{Tr@PUe)%z$y7ORpvnpr0z&zcZL7#_(r!MM zbMj@WU{>szY8t>*{95q95tYJhj!4sBkA%T$ov47S09Yz%`ITs}tzM1XDKitxO~f~t z)U=0T(8i^UTj%kmD+7wc)FBO}q1vxHGdxIbvtIAPFhUw2dzgy^o4L^07rT!zPZ5>3 zoR)D|c9Y$%avdzX${>h_S(I>S?85Kf^b>j3duvB4CAX?p*o&;1C z2#A_cou3h}$4!u~jF1Eq4-CeI6Jwhq4qL*I9DHw@n&L)c#vI%4zPi6&_RHR#;n1C@ z79T4kA#)7-6{z(icio9yKV#POKe0gTcas#TMKly|Z0G*oS6)~5cx{b$q2Ba5GEvO< zqeefkJ#d&ZL|CtZ05f1t5z55t{s#mAf7hRROK;hyhQ>q06;@E(9BK}xeuny+ML-(XdfHC8Y%V;U|;J6#>0TPA&qURM+-b zsV&;e@0%U=tBXrYY`pbkAv{90p`09!I1CH}pF+FmJGr}d2qJ%V%`4=Ln-GV6R}--W zV~4+fV`fHRPSp*LisOm;H_UUcp>1^6rtQ&@e#3>#y1Ix>Oi$Ks8-Jyxs_lU!es;Az z;^Vx1GuoJqG|I8@C`pfwDzMD-{!(Vojv5#l3iVAP-)B(`+?%~jfhTFlLKhl}2qH|k z#o5UT4oabf=-s+HI)k<6D;<{$4sFKV))%XaF}SNAy3F!b&Jv?nfy(VuVwi;*f6aBN^Q)reCY*;W=au3d(O(28T)Yq6@uTy zLs3H-_Xy>nBm+K)m$Ux+SHNJm-;uu{uAef~=y%JXd(*=rmb`lNAnAD+Q(2t>$%J)q4TTpQNX8+HL}6(TfUU&=jweQz7*r(qynb2MiLI!+NtFnH?|!IW}MxmjUHYPtWvL>V|7;uQd5PIXK`zqy#IVI|-u+K_uG?ullU5a0kZxs2Zqncy3ye(I zwzjuR7@A;8!7P-Cio;~3^5$w<2@Q2E%jgwwJx28%&~~OVpGBmnKeNG{38x%B$l7nl zC#e-ED{T6}^6!72c>-2g8f%V0=_yyLRB{Erl$vxdbX8oSO=RMAdo(qt38GRlj515@(QBnPh zo~1cj3YhFRG>>4Sp<4NKb;s4~dFK0-09B!f1Vj>7sSU!TOjHL2{XQR@hEmfk)jWB+ zt#_ekS}~8k5Px#_a0ZgAuHLD)#3V~>COLmYrKeMesv!vd3CSx*Yn4w|kC%HcJO@{Tp2+vi0)2VqgKh(S`@>me zuA{$yzvLRi1HyjSKx5(HsXSRtZ!H!g3UNQ?JbCLyyRO)b68?0cA!hw z=`%Jg0hUd`B*f6Z0R6*nk5wf)W@b zM=dI9sEhy;KO7AC^`qe<46zHapF9Y@cJdID*b(*O;}OH`J3|uW&R+yvZ$)J8Ow26yad8NKu`|b$O79%A?qrJx)_}o6JXxUPu%RQob8gzFA+`$ zR&+uI<6fzM|LoR{t#kyK%>}P8T?I zagTvBt2oSqXP{uL2QApUB&`tg_~=hjifsmqIf!)WbA0MJY)q0O^a$tlSsWEfm-YSO zE}r(nsX{^a$(I4y4<_PQa@yzxZRm6b*c1YAI0`EdB;%bv=Z~ZWyvX_=D^0Dr0xmnH zR#J8mOwY;ocfMW6@v%F6j}XmhVpMEJ5Fb17YJGp{lNdAQkT(8jYOBo$4SYMPYy5I$ z70q@uceyY%=d~TNQs`btw}AR_ck5deEKo|-8ZBn)H+JlTtDLHjonx-j!P z@Hn&Qypjhq^UYe@)dCVp%GgOpl{#E#g>eV#VE02vwcRPFVuF@7REksvGF%uKIqpu+ zT~5{bAy@QlIAUZG@Ra3Hfb%wJozQ6O5!O0WNF=)m%$E0 z$9`5tIXkw4D6;YBFiHFPzE=qwZmIPxS`-#czqI`4r^l6ba!Ffx54snNCs9$L>g$vB zR=4!@DnYvho+%){CDXgMmQU82RJzcM5KM@ok%6?DIooJFURKiNpoCaxp=Wy#Sq2gF z5wi6Zp_z$W7xZ+t35^vqpAtyv<9O> z^4RHv*>~I&f-#6cO}`U6U@cj~s6astGi_yFS$wBLht{r%uP7Z7>`lf`q5*~B!Hh#x z_)uJoRT4ZRTkbG(p91_Z&P=Y|xBgCUsXk4PJ#CzvTyLp%oTfW_ZUF@S>)fZ2sFLmi=Lp)+)0<)-H({Fv-{gjR#5MAB62LdW3$+G`umZWpS_MeDo$v7vE=cD=k zzJjq8EUTUikBpAK%Rr7vK8aJJ!7gmwF7~wFEYFMI6*igzmDN++6ZhQ5*jS+_P^>1G z{*5(dC2lMLMt=Q@`!RLD&fbSXm6+cS6QGZZ5 zUGTxbqnhR0ruxi&k==s(s2&G4uX*kG`)VAy-CO)v`70=K1)MdMuH`PgFU^(w1+y0l z;!HCMZq9aLDc)Tr;5(q(9_q*Yomp-fth zqj%fN5kPeZxT~5aS+2Y@Y9w;Qa;jTR5ti13Paj%7%{rZ|0se(NeU|!tp(<0dI;z7e zi@$yp+Sr?_gpsnsM{o0zb^8|ue z0q$d7aIiF5SNR*llDc)LbE2r0bPdvyVlqQV2g{La^w7by$!?$0#L3=^^_SKFru-S+t1JUV36bE6Zj&_%Vjr0?ff=-Rz{B|PFTnI9Eg#I z5Tdqj_=v5*pG8UEo5Wn01>NuK>z(ZjhiBsXK=TPyea^jaA-fF? zxzvlyslj-yEo%;vVmyAu-(2mt88g@G&e6?2Hd)%5%&4f$|EA_za#?CcIOpKhVImfr zEU7y|Kq;YTp)g1Jv&R*&!&yPbpvs8y#O7N3_f=X;MKPM#eMJjmhu?587T?sd&#!tL zZ(~)93eT+2--vI9qWt7?h~{Sds%1cZ<%%5b>+1u0PMe<*thb5JEKIG>AKo3~JIi;- zF{)@fh%k>u6_{>UyRLYdM+ecTX*^tcmC}KvAnK_r7v61p8xsO}DuU}t+bzcG(pd4t zo3C9uu~>N*)7E}5raYR( z>2>KIM@C%F_Lq_beLO)p``eo-Q`ZXF_IRy|L45Y3y7v%J=`SLwm&n0#dAbqLXz(m0 z8G7FPvdimJj@9!U?)$z8+tUq}7XfEB5)Td?_h(jbxdWD6q11NJxk%?{(;i>rtPvg8 zaz%LWez_o0 z;yjt&IGH%M+geY;Rn|;~ue?NMJvEdixct1|Op`*&j0LT6a`Zg*I69`&$S5kXcPt2W zUp_db5r691Dp9l; zC&y|tMu!NgR21xFEiOvBNN8z0zwe9SUw53*r`<6iV-nHa@PFA;yfop-mor^5nq~Cz zBOh3f4^&zp`%5`*ePy}j?&Z~-PIyT9=}Lt1U1DzD;u5imKi8Y75}7MFk?+43Lua*| z%kehS9J2ktoxoP3xWaug{^Kwqqr*RK!T0R7y!r;ZYC=0fidWsy4 z5aWtU@dhVtZPYxF+#iRQhC?xPi)fU>H91CTErJ=2 zT3#AT2YTBRT^SiE#*iWQ{607rU9P=yY7LuC+4U;$I#1cJVFvUsB^sgqQqVt?Rq-pN zC$O-R#L=ngk>Pef@!2>tlO>GxCXbnNsJ9zSyy__l(FrrRJsKOF5`Y#!VhD#0$ga59BSkLl zea~f{^{A$-mfT(EM)VNHV#db!6C=v^x>ejl(+bPrr84n0egD=w*FD84lU~)51>SL> zISemXaX~5Yb+h)hTs%AgIOwn^oj(vlztrsK>gL&mXzx-Ubw}9ohsG7#IgqPrA+1YNQ6s(a|caqMJ=Pn{KEQPGw-&i0L@&C3O`78Lt$tmQ=C=S1T1lWNXV%8 zNjzt1by*VOwKvQ^#twz5W+xWEYWx)7vwvAd#R1f*-`XX!Zg7h3zS)KAzabeJ9={Te z{N;SATGM`OudQvD(I?fpQ2mAGdz#oHDR-lhjQRX*{zIfJR^XhJ;@Mm$Ka)=)fwHR`+7Pet)3vDGQWENsR z(!^S+Q%qA}^rTgYh{sY_0HI44d+o9Xq_`x{ZHmbO~e|1B2JwjFPt6Ehw4h+ zJwI3)!@Vhf<4%|Flp%mX4EQaSO5k9=*uCn23vO)-Z1^u$AEmBIPnyCm&mB- z3gx#Pyo4yqRz-)B=AnuwtQUSK?%f= zln`5Jc8y}JtihLNDt^Im6TL8Z*0ou4qAc-eOP4V{s(t*V-S}@h&R4i>ujm}@oK9xkt#QI1UnB|_b63D?bGCF>nSo_>N6 zZH;Vx42A<9w?nm>CGVEoeC9-TQ>>;b!qbCqUy`b|z81&QrtJyzg_?)-WbfB<%E8d% z^hm&(1-BAnF@z{|p>d3gYMd1`ARTRI0ZMIcxjxoBR~j%bmGw956(7bB2z){(I2eLK zglCCnDg_DTbMQ2##zM&(6>lSna~rLQu-3Y_&iDNPd;zGp4}5P!3E{~Kie}zxghVKb zJfa0(^WNA_z*Tta?0Y!agMu)q5MNyd%djYAFh%k1cHc*$qhqLRq3ForK|o=D8b<3> z;D?3P>fLW@JnYYUdWTXSbPK)AWax1l2MxRgH z$Xj0vjrrtSrSldaz9+1o<>Mz#)^_*xb#w7dveJK_6ewjWq?+CCcbB4k=A%xHR~!Rz zHVJ$jw^4b?jRM*McC^d`FATk34B%kBbtFwnmqTT6GjhEcq-xL3S`jycO3&!wsK2G8 zqai)6Hhkz@A9&HRt(BOLJX{(E2qDB#?5Ngu#V{gE9*U!*gBca4KbBrXOotR$;zYa< zka$C03UyzLWWTY!p=8S>uJTDA@NsdI6!TKCTv}+dR5)noj^QM>8zc%8T1C z+bgON#rqYH0s8kVvQT~EIYk##j2!JUQ2C+lH+@u?n3y)BS>^@MV2>AyM95})t4%EDU;p)0Y5%U1#!$#n z0cKfXUik)^yfInD2M|<1MT5Y_XTO@jzljgh$>JqMjoX(vkX~mKSu5K&E+|~xvFq3P z(fqYw;M)XdL?ZuemV9Sbqy7l+milydZ4lG8hQbT63xeUw;5>FzxPoDd)#6W|tK$$` z=W!b$kjv@cZCf{A&+oCIun1@xB)(E5qgY!jlaZZQ9}jVu0AHBZ&x}K?U}}qqP>Rxy zX1A!}g(H$)T`myOF_aC~3$NHRf4fKy;#K|_h%?Y4$1uXe6R+xaQ_tGmuw(cNFG#xe zPdLSpY1d40a&t8hoZM2)Rolg=Na6$+by3IbB-YGea-iCGTBN3?K{YkUqtXGzr}31` zXM*aId$R5&**HhhhVjGn%|-=yX^i^Ke-v;I0UXY@wzdl0n(CSw2J^*+lLR7B*8{BF zx?7J2Q`AsBZ@ja63{xO7hTKZdF{1%zMc+a0+vzhx{w_3U7YpS%cQ^$m7Ra%(Tqv8i zy7JxfM4Yu2h2Ov7ta(PoN$Czr3Vhtm;<5-<1v)-3#p}FM+bU5SS_TDsjn`zPA+mC( z>Ak!`d8qjX*l@Uwxh(t^8AuoZLnE5DRF(^bE=$L3j!Fu(w9<*f3){>iwoE0_lj`3K zBqW^pcC}~V_&r<;YU|?kJp*rYCM$d=y_1e3k2NAM4;D#3oxxPy%G=UcO*bSC+^-^$Rwf0 znKgP+3j)Ra_a~%Zxw9DnjoHe}ELUx9K^0<$V(3Q)hYGuvA@0_+Em2C0c&fST!=t0> z8hkugfpNH%zH-yBKhT=VW5g!@&FB7 zn6^IQ#LeH~syy^PFSxQefG@l2J=+g_ZD`iwoFLV?!eWL2Ru6lR4~1 zpBU0C#X43=``C{$MiuGUN-C!gP_aBcA)x*JeE>rcjqo%>%t~ySU9z+;8&r!%k+=P> zmS(ai?imk+|ElB?4~4qlSrGc%tEuDBlUOAqz3yi=SfIpb%GC5>l4-<=2Zx7bUi7H+ z;FBOw0;5Bw*cd<7xJs6{Wo?;agjz5k;W#IGv3$Q3C3iwx9An|h(0ko2)B!7 zqQ5((HzBwgi&s+zLz;+D%E~?{)aNR;g?qKx<7v&MUP1DrtL~GFO;K(Os6;il?f%|1 zkKPj#o8FU8{R=)w(YnDxWZ6Io;}Ox>UE-R+SWdZnWj=oda2LZjBO80B0==R|jQ`4i zi|5@wPp|V*Pv=Artf=W|@8}3P{Tn9O_kI?gizw9U{Dlyerhi|zZk%ECNH z&I0x|OTIsVW2gu@|U$BTt1vevu+;C^g=>n>-ltXG()#U*lRJX)#BY*;-e z=I8aOMn|{)1}mpr)UBRc z{5~cd%G${dJfOcqZqj2^3AKWSXN&DnfhNjRfRfNQo?Ict_6-gSVZNP#LyXG7po>V( zG$0buH!k$r&SqgI{eoU|kf!kn-K7&lCNS<^cz3U>$$nUBLILTgBwPJya2oa>tKm8} zBj02oK$n7nNVL1N7_o@%=+tFx%G=S{+4Fu4Bl=&ytwac7@A)Yt6wcB1JZWc-2+^-i zG{=@2o?WP|e6vXiBQi@U>`U|3KzgyE&{Ghhp)f(ga;7jHLMb}6nLHw`SGFKL z3et0|Ky-x}RvwTU@+B#X7R=n7kA&&AORrGfb^>f6SVzxm&I(mraWpRv-lB>|$}xfnvENFoD-s4NK9f!l4*W4%<`KcGsN=49g6X`J@B8|6y}reu za}KE!dB);hrkvrOK>i@05;5%&<6)GcXCZPO_&bnQDw5#y?Bv7U<`@tekU^9t8x8C0`-*V+qVVurbMvxOnNC#FSisBdCB$)X0 zRMyQfeQ@~nx6`?06scbf>TD5Ls#3}DuI*@CJWi$ucW3F&xQK|0i!DfsvqyF@+c`=K zg|(fP6LBTU_AuKme-=^-**R=6kkdD8I;YN*W!i4rlpw`gsUNAz6qf2*7^JK36D7Zk zlS5Wzs?w-FojUNUNy}F6L(1kVh%%%5zD?{j*)7(Vn+tayWOXqjV1tg18I`zU5}_dv zXh_2p>pqGMtdNnH6&B0e#0x!FG4ous{i^~oSN?u}*>K?am_-kqiGR>?MEZAd0M;ti zn;!*f2_Ac?Jt3VG7P#S1EdesZ9^gy(fM~xXMo16>3)a`9O?~+T&p=L_uvqX4p+E!0 z`>37-{E<4N$~|cZYs>o+*9J5a(x{XDkS(M6sPyqfDCwms_{x#EkVv}Ha*E|HQhFg@ zh$XXyIR?()4!s-wk4_Kcer)_IW;RQ#LPjtuU1SPLi2R)Slse0-MOc=G8aSV%whI@# zT7e4#Oj;CJ8cF0crU(gysu4ORgss&IB)>EGCERe?@$Y58zh2#%W9pc(Y{}GG$pCYn z@0Pesib7=u%(id(XDO7VzB2^nNcK3?EgMR%gFJ~-^M&s#lw97j@ zEKg0KN)D6yK^csxnE&Tp)+2g2w2~g|Vw8#W(k64#JYMS1C6P$6d zV1bvD-)59ik&h-8$;@lgdpDMiZm!gh3eB%iiNP!AY}vW$a|F#`I>$s5?e?XOipm~b z+{&r<@Fezl(0_gA4k{}9u^zH;y~~G(IIEVVb{oAJUF?~5&$jY%Lk(eNc-NPQqJAv1 zBaSU4bsh-FB?*P>pWy}Z+C$*USZSR+6z2*#`LFGysp7~AqcTm}RZ2tpvsn$OE^ehohdSK0 zwzun2ABS@vW?L3L@Q+qS=i6_dubz%1p3HAQbgMrkbNij#|C|cVTVPUNaaYkqTD>R; zEEg$SBHGz-S;rKqOc1vbrwJ z#uyLrL@@Z6@V|x$Ond#_OC8T4N1m?_B$bmYdHYTBwk%aL=6CK>vI#mJvTHW`4&K+I zc5%zye*Q`Sk~wkv+Saj3yVt)%l4fqWVQwEqYD&N)MCH24TnG`FN5Nr%EbwS|m}!Zr zpE1@q?D)KOo2jb}2K`~AVi6iMX%fhozViuJnW9JpNu6Uw-91mQtiNjT5ThM6YSO#F zz?OB~43d$B=T$GREh4BDbGwUNxTQ2RqH9Py>sC`5LRK8t)J@ zXPc|XdI#O+>Ja@mtP&?H#Lw`g9EHckT><9+P?Nhe($3{uO+{5iiW=NuVTUk1Xu+R4|=r~Q@7x|&^2g9^3@zA4XIGNYy9 zZw-|gN)4hUsdoPAu;wB~1?sVNIbTbi-h+sa{lK0ZE)#ccp8 z#>qX^DxytN`1p94f+0+eFBe?StVlFdnC2w_fZ}ytd*{FyP>u~D{F2AM@;(fRVruhg z>Sz(8PO@4L(S(9Ez}EY1P+m^*kz?q|<(xU`S{l$9gL+Y&Ki@^)2ZoN?=bMoqeT|4M>(74#6PpP1Kad ztRiQz1L4?0tAeHJ{&j}y=q4s7;ozjBg7IX`dFWVKLQsm0u_xnkJ1N}uQ_44a}gz(c&z+H)%uZx}QL(AhvhpWA7Z~f*wU-iF-p2MYH zDbzHvRrP_Pk!OkK?}s{CO?){K!$#aE^|Gy!ZwzAQ<4LMsfCW^h8mj9!IZj(03=Bxh zQ36q{RrrP+rh(EJ`fomJ>?Gcr6b#jdF&8w!1^O}sZoZh@7m0H}c5pvUJa$ez+_eN; zhX?2hA4YMv>yd0-Ue4}ZH*rP@jDdKR5-;lA83)fcXz%~3=7{-OyE{2)20~}VugtrzBwVneG22wI-~b=n40ixt@HTa@NwgB*;F56VCmGov4GR;$wcSn z@?z)DL>5(O@P0F+iY(LhufBH%B{>=3Ud`sf%vkJ_YA@)MbCRN_f@R)xx6t{T&O>zeZLz*}DS0EN)G7cSe|l@?yhixPa2x z50_3Kq;^nR#5^XwQ1^PI;^f+^IQ{#;8wgZdu6P3p|89D#pj<%IsyYP#J@IkHUN!8o zvG}B@d8|PRkcd(M@5hi<6N=-}L+b;}NGqjGd{0of`1Srf7ITUQLtiPvUN3!y!i+>l z&YGdr*a$P*1{vd8eAvX#WD%AGQnp%<4l%cxi_*l}E){qQFyN(efsCf{@Xc8afMF3(oq` z9+P~VC@uG%a=ARPH6qLXKae5DpM!6$RfXwu7CUe)_}NO~> zPpQW@IUSdiERyaQ3p2F$i;~wjV*!sq^i)Ut=9pjq?o?*t$*T|CKJYIA?z39Qj1SIFAi}c(2n_p2 zUEL6~*ZLQ7l>~HjSt69;-(5w|o}09NV)DEi{=+}&4v~^&$A*W3*-4hWb1B7(hH5as zMRu0j`C=1>yqzA>AT9?z*{dZ3~3Kpt$- zN~bJHAZEDyH$^;sgO)*) zWs|_LEf}*-C=Q7UUNSg6;XI1CnIc=R9}O-fn^{Vg@(F_T|`ob zL`qsK9gi1{o-nhgTxR)4PlMfaqO02wPHx808MJT5yNzEWqA-^D3A;SMyq1+ig)x$5 z=aehRw$>ub!TpD}OV3}rrR7nQYSn}~K2w39$Z-YBf$^l#N?~*;ynHC}bbV%Qwn-as zs!-Iz&hqYtq6YpLRiob_WGG6|{Z2Y)KB{+Z#?Ox;g5rs`Z|sZ7t)*mSt)$QbBTIRh zRvZ~ukA0o{#OJYr(H#71|G-2PUDLE>F!B7A@zmr+|7xlR*F>$C0Tf< zir_31MUgcA=8&2=#h#v)YHi~&H^Iev$Z?^8ArvYOWW}~4UvIFrJ#wE+TdZglPAq=h zW+bYYiAK=>ew}(>biVMvXYzVSSZ#O^^efsQ4HZmi5v`KYa0p@>imaGh5f`C(n9wzT z_&fC9fx9mM zp^(Lb@$YDmswV3AU6!7Q5rA&)naAu*HO=KrZq2!AAwFFPfeesF@u@3HYGxJ$v9a=- zx2JP$ab$A$9m2*w$%NYXk1N&3zzUU80VE6iG)i0tn|6{91xP}B7yXGR6BC3W60Z+c zyBYX|QqtP+iTB^I0mw}MBK&HtixiD~lkF7zO#Pr8Be3*ioRz-O9ALKEW-O^l1k;$Q z26j$SVy^Vpr4JHZ5X?Nx4@=G=USzNQZG?mrPg_OA#2SRk%8m7PdZ>LNu-MJ=0tU;J1)Hxi3}Hus0duJSApIvQm~X#?W~=JZbf>-M`~g z8Eu*4I4lby2;KzJm)7!OGo{5|vask1>1*JyVZYLQF9B)goLw6pA+!_EIQK?7eyKWJ z^zd}G>U&dj55&0&2W*>XVQSFbdAxmvkjTnHO?_?>NM>YBJ-obYGvliY_Wj_;1A zq9SP>hKE{qje^UcSY`lNBIr_EuaI};W zGK)Yzg^WC`rz36c*XZ@fxP{n17P}j`uO-bK)nC70Zg#R z4_}Tg3mFjr_yh*qjTv%zZexIYYk7UQn*wT_`SN zk<+K9eU4_HQUtHebH(5z@Z#2?e!&^P`~P_Q%CM-yt?eO%0YQdPT52d!x*J4NKoIGW z?(S{`q&ox@9FUlyK^p097#d*+rMu(Zp7Wh=|Ay;Q_OsWs*1hh4^PMO)%e`b5&sTd7 zHs;Nxith>i6_oML{b!v`#=*);=G3s2Xv5_q?AJia3&@+BSSyF`kzPAJXLolkQf=v5 znZ{`uO8S?)Ag}pzl_j68E}AZdA3~IF>`(nQyM*scrA&yY~+1b+gPln zrCCyfH=>;7EJksGjRDpCz^^IgKh{Mdi=Nswzv=`kX%Z1p7VAHWiAqe!ND#zy9_iH3 z(|)cXJbX26S3?lddU%FI%fy(^GxtTK9D#`KMFBBXa?>>|nN0LDlS4uvndd59^aq-4 z6se9yn#Le1gI|QDB?Bh_Nv&)>k9qy!bm6-c@I~`Vnc#3;N?Y5=Cg0Uj`dW{Hweg@f zk;&g}g`dV6Vo-!W!VDT~P>~WVP5>8wg3!=;e!) z4Nu|>?!GAd8VPDC$$HBK0xNj$?XRX%){EZ_FbAB}Km6|KRzfM z)d!#iZfDBx1_b=K-;lHk`Wn?n-VxDIi@I57E-RPShAq0kqWcGEsPg<{>@bRRU(%X& znmcpl6j~?2th3^nlox~#IspQcY(b*=2}k#hG`2llJOpGFmbcws1B^P=+b-4HQ`Lu4$NSB;x5;JO1QX3} z?BA^s=q0n>7auv5{MsWQX(aNHnU<938W@O)i~c;mww1f_Z3lpIW>rIuYOn{_evYr2C2JI#K-Nac1EkVGz5t<)7|50Eectb~+uD`^bXnG5XrLWEQN2`=E#)BY~J%OH-h9*+%+}m6O|g zyk~Z3j!zrUH`GYAYmYZde?n;Ii~Vo{3~Wla=k9ys(6-5SMzKsEQhjk?}N6(aE{w*poeL*b=T_^5Z(DliLodxu<-x=Kf!vhi?e!>V>}M{X4-C!M%T1K(Np_((C)7`u z8%85G#8^mg8g;LrW5V&pcXOb2$KbtDz^bO81b7-|ZFm011&|D_t+S>u_0}vA8TI8j$_;vqPfDm3_3NsA27Rn$FQ;TX zuf=J68a`Z=XTgsFMa_DG7tpBTo3aen4!WxzVwlJ7KvQdfj$KQ<^Xv#@q}I zcLKK2xj=+do&9UDR=MHQ?5v>g`Kc9ebctP}(kSan6EPr3zoP#Iq!W&;Zr!f%ELQc#=GFwp$6Rn~Q?LjZTSFm z+%0zh4mK*9{px{p_|D4tu+hVI+Z9sF$oFjFem5_6FD2f5``ga7w+leQjSedVDaYprYeXTk<>mcYn^X z3i^KxO}b?q9MF(>cQ@Ai}#u0LLDWuKrC094w?)|Dn$$MIIkMv&yu$yDK zWCh|7%@4*gQL<|aX&s-SXyOvfg(`YHp_=r&jfj_n1qBQ;qTa{fT@m&RKTZfhqVC|y zE7rrh1Det~2GhJi89%P7eZdH!tw6s8MwSwplE`2@nD>N0MBIWH6DTw!zbyK>Mhktm zcchGlni}R)&`Zh>XJbMi)TE>bBEgM_Y&jZvoFMtgAeMx1HtA{+BpO@9t4BTnE*HcKkYZ(pTXL1_>>b}uk`a}2V z?a=7$A;F!%%86K@`@2-qkvtJW!FM=Be)>&;4;O(C0JSOsA29Xf2sn!8Fl@e5YCBbu zxNw!Y*m}6lduTnlX>CNnYpqk$KCmuieebv8r9dER&oH;h)56VXefI_Q*Tm=w|7y6; zTq?R!|1Ai;Gc31Eva_|do%rdx#X(^!LTZ;JsgF+_;`#9paFh*@qQ2)fkqIHPXMd}H z>|F1WfnWLJ-phRLSVS7ooDPM)sIwQKP-Zs@KwDdkZVR~c$t@~UaiF56PBkb0A~y!n z*C1uE@)SvEX80czg*{eYIBblqNxm8T`|$gl^ZaCQw{WhWE{1us$+|r!!Lkx`$^FHK>e||~*p z=$9bv53*06qw)w^H#jI!a(}nQ?Q&+s)@X*Yp|31f1FPnlDtf+TpKnjDIxO;CAqV+n1WtTQT00Ef{CLtL@J#EiG+(z&;ou zZK6UN=@h?w^~$_@Zo#3+-pT2mEj8w^Z?8WE93DIbpkg_i_WTbXO55&b%G}CSaBJZV zMTir;Y?=kaRsO7^+O!aTq&rnTVUHbc^007R0k240h1z?1P=VA~*SFAEUGvGYpjh@7 zuo$)6t#IQE+0tCvzMP#Lr2b9Jm>oY50S%Z_;=+im@FV5opWDya7Gy`*)ar`o5p=$z zwXz4bpNN{qL=(R$ociDd`;wCl*J9JFw;x?^!mHqteJ5gJOG2OT)Kh0SY~}*Uw0S07 zmtZF1$pW%)>(3R4O06pY;2O`|MuOy7esSsYFmTUFz!JZLNb>W)7f0O4qTb;^o(QQ&Llq7!hl*8G zCh(j|u;=XHno8On9OV=OV>Y!J3(M2V)OQkw^^JlD#IGm%uAls1dAh**-)ASGdecuO zET^BIhbRdvMcpD~w`)BGa*PVR-x6p!C(U*L3mf%a<^#gdM zX~m7%N(R6|F^(i@%<9eTHmx#$>O7Vm8d(ga<3c~RYjToj!d-0C_4~(yZ%?NfEB3Gw zxEuT+mugg6FP@sxrVmr(fLRqHS)!@sm=r?7WM<=r>+ePSi|!Vwnmz9L5r6SjrnZgQ zG3R9B{lp#JkN20FfULm~+OaILQ7uKvPU!@9`kFV-Jc4EguS`QLZN=&=W4&3r#4?(h1F!j4i0Iej$o zX)I9?>|FXaD=APM5uMeoe?BnCQOv=yA!_aBl5{igLsi78%2VVbPAV-p5sL!rjS$3y zSq5M$mY1d!#ZFy`GHx`lmi0Trh(=HBZsio2xhN9XWG?XV{4W`3{Ew6nf!%C|&NtW( zHvwMD*ZfjOZ6(9rCtpu@C*>sI?$>Xkn5I@8_}M?X|Hxx}A?y<~MF9Qve*ab2Of zf?8SVcj7fC%eAx=7h&Pn_xv8rVHGAAQAyBDqnD&jiUkFx@?lU=Fds2p1yjiN_P}^2 zwm%Yx5ir01OS+6R{89btPLLKf~_>pc`Lqx9&=S(3aZ-j387A~wx`M`j2&8Fg ze(shg>K&rOlqwh>GUEYaKJXT1OuRaJ@^;owc$ni*-@bjb<8P{{aQZX03fR1}L|4td ztgb9o({y2j?N&`S;P!LlTEQ*JC9!G-^(5tG(LmmaczJ~sG8k1aV><7SU=%)OZz5u+ zGMGitulJ2Ce;23`=&P>@XVJmQjIX=UbxeGh?35Q8-k)d> z56M%=qsb1C5kYhAsD});CW!Z1 z!NfVh!OzXi!GS3*OT^PoDe2E--u=}7(zb!QrxZ90<+qEE4NrX!d@d>rl7T3oAocx) zz<2UmJXTn=iB<(MvND*ultGHGymLkC)W4n-%*>N%YwJ22c-q+w9r@o}$l9_d#G+X| zl}%1gRxDO84(qcdagcPqO+5aYK;lfL#2U*L*#UZ$Hi%{A=f@+=4suGOnynYe8@@t# zPMnR}(%4G!CvhGwO0&Q3Gbi2J0(RJ1G_5unNr{wNHHWHN?UVG0_~japsC^g3?Mf5suy!5U0I1^PX-0B$msI?q96Zq;h8;qs1u{&$}wS3kRpE9e7EnJ(}-dB{Fu zNKV}K2t2SR_b(pxtBM`AV;p$(9-N+?nRCyn1{}v>-=pr+o7WrbZ+pr;-Q5|DC&?Ip zG`c@d2Yvxa=Hs|IUh%*B z{jJmJZeT^?VBXe8No=sR6yZjk3W<8lRFG=HZ>_#I*D*8Tfors2OJ1X1%wJ$OIP;i0 zJby-39;aQGjSfohN<<^(@>8e${Nh45$u0~MkcDoPw`FZ$C;LmLf|&(9>ZmuokeKi>{EhJc(Z##iVaU=#@?bgko5VV)5P0MY?OFr{8n6CEOKz`Q!vhwp1yp$ zDX{WTa6=_0zBR!1jFeQYSM3EFKX{LozD_+>Z;cXdmJ@^)@A#a9lm$selRPkFYRaJCmoTrQ+_xP>wq+ ze;0%o5DEtmH)(wJl&e${)=bdQ;2(+YBUXC4j?8XSz9c6B9K`P9o^mA!lqJNb9Z<1 z+Wc4?ZXH^Pye_4%T6)gAoi;*Fte91Oc1wF&V0@4K0azC4!l!KbD7mnLSfV5Q+?T5V z6rNWHfx?2oF+(%qXqlj~v|^r+iRd7G=7ja25R2NsWD-GTrDBt`R`0L?eNB;o$k@i& zv!(r*mtMP%_oSeLP+|-=$!D1AV7hk@T+AAq>n`QWbM&H?FmG}USVvTyEis>#o*sHepDhe;!-t%)8 z->N7GISPKRU5U;#Kw@-p#+bnMk%OBq98E_XD_0|);O{Oky%w$MDM%cH;aSP*>MB9tWv8Q8C*|__c|EnT+mxqhXTq>~C@rU*kD^$ujWTW(-v)COu6&zJ z9;7EDPOW;&TSfz}IXE~7TMqt~sJ0M^2bm+I>qq##9D1v&LbdmTB>GA}3EFzV3d5w$ zt$MYXrA;n=PBVkH<9Z#AZVJ=qkWVsmwuWiHjEjxMAmmIZB`qps!p6QK#0w%c^Pf;{ zA+@z{pHXzSV3OhQx$s{(0W7t&1_m4amYwyX+g|?Ps7K_b2U_o2p>d_tHr3=lh@zy~ z6H!A3IV8&Y)|xhHWSdBk>*rGajYj34()P2dM((1rk8jN&@%Uw6jzRg~9{OX=h zs7(t2alO9LjI8@a6?|x5l)sMY*7xKZrtj$4DzIb0*whvG5xbW5Sy!B7?^6Vum<%hR zm#sQ`z|+kp-rwrIVy#_)lh%HEN?3XNM1_MUTgPklu~Egz1Y3%hC^whht5E}&@wiH5 ze@}l@p5aNB7BIlx{kgy4m~UN@!8gOV-t!zVRoL(xkY)OR_dEP3gF#G2Lsm{f|D}g5 zX7ADSfXh`&1CKdAq<*rm4p$tiwY62Cc@-ackJyGc^AD#Jlny{@PpmFqj5I4uGBO_w zO5j5$qqQ((i~2x?!)jBj$e&%$m;$`>wqrKO-Mv@l-1q-(_lxE&F*TAU@2wn~yFYT_ zkn)DV(=TR}l$5GZP6)(qQDVLx4oQ^3n}0~mEw(NkZ1_Y{|kt`~k&FMjgU=h>HX zFkO}!6s85A4xuHZrhY{K(Qaz{69Eli-=waHUXU!9H>mmIY46$0?fHDCExaoJV$J5w zvpGR^8#p|Ae{T;yO?mU&+s$rp#^hV}cYB#n(zLWp3Tt2-Xb;D%AgA(Z^ITs$I3c!_N;wU7c%PjsAEt+lYdBXa*j<-n#KtEoc?KV4?4J+xoWoOyQpy# zmF)w)41N^q>nCGuGD~YiB9GT&1tpO-;|YJ8@TkIK%!+axr`OzKXV7?-)AqLqKjyWj z3kI2NXe1P;a_LFIblLAqclXBSmGeLFJ3_+5^~%3<-^QJp!7tnm5X{J>%e6oto{N34 zZlgW8pxX6uY@cY=!N-D3v*U2i5*)c7u9_Bk|AP&@zVMNo#uU%k4lN=DeqZ0`ip4X{ z+buUvU)=d2B7+ca9(#=mvDbg(?pF@{ZWbO6AMRSB3!u3ET2-2gtfMEOc971VzsXD~ z9sLYba{muO%mVFFOM~W}{Lk!VAGB(tIhNh&D9zoDlk;xZ{p(u~fL;+3^fwx~AAAEZ zJOk5**H>;gjZV1dU>i?YF(s1{?UYR#-R_{3bDMSeE<`<;*dZTDDTvC2WfAjTlV8=rxCK3vO zL6Y681@Zf=&u|fdoUB4~g7C~|=}F6blbimWln{qUNwF71gtnPUIuN${uVKEECtl0=N}e+uO07H-sMXIL9Lb?b4J z#WLLrL~_DvSAP2#2fiz# zD_*FDq4o-{zCOHxy}2NWwan5E#=1ejnbCJ3Edp{S{e612Ish0-=Z7Lt}v z>blT}$|uRo|B4x!Jzu4lvB~qq(sp$eK8iclaM><>vY>dK-&rKF5|Zzb?@;foL7_ZtA{EILv<<^VvF=LkQW9U5AepbRSJdzjDP+lkRec!a7-q@H<9% z>F-cW@%jN*Pbu0*H_4ptXMc?^FUCFQ4@3cBIQ?hHrpCFw*UM{{j1Xk>sl3`|9b*V$&`=`8>z@ctJ}a9$SxWe_VmB8SA0Y47Gr zmSm~6K6l$8oa{`F-v{1gUIhN;XI=7ayCE=iTXN4mz;4AJN;hmSEiaFUq@_KJj8!y& zlStIz-K5l5*ufj6FtISR!Fn&BQL`GIc98Zc99K~~%+~Fpr$T#~m?Z9x;+t~oD=H38 z%Kh9E`U7_MANa&uVHz(Q5DNw`8*^W`$6CC`?FUH~Wf~S8FND-tJO^a}+^+ZV9O%FW z&&IT33;7d!iog4R8It5@?PL)QXff(sglVMDfLDpzP`2f*QmT{*$FKieNO>kGp*+b^ zQ*d1&`>Ul*66_v!C@PP=C(I=zYT*0+7O z7MZFp9Cq$pH&T+|XhuR9`ok94>R&x( zA+#z)&^ZM$@xP%e4V63gxOOK)K)2KrW(@eh1Cj0Gc}9kY=b{9Jot&rsd6`i^#;txL z7KBKtFAl18Sz6EUEk0#iOX%E$jM(ZffsnV}9rh2GxGy~hJagMw3{RZTH}h*Cuc|@z zps+}jvp=n`BZ~El{SR&=^mU8vS6cVJ-2`5q2sBq{>WF)p9qW+pfoWabWlC7z5#w}Q z+Ro8$G^6SDV8hS2tt6OP%@YRYjIEHV;g@q*20k#DsQve2k$=$AQJb|eyH&66NiKq| z9Q8_|rYIK-SxppbNRbw%L!8^f83$F)|MuSZ7h`~3V( z|89^VubU~vv*>C}H>ZjUmaI-6r& zytosL>*SQ_q6Gs5tFftxl#~?kuPd$P?^$;dT7Uv!gBs1QW?%QbJfDy5?wQ1j6)oNe z6TZU*dWaac7inP#+I6$R*}}Z0^Q^oF)wUmf57&UBoN`iLW-iq(tCtzH_lM~iRt6q@ zsCJ;1%z*GC!r;CD`#ERNeG1IN@4zFZhWJvmaj^x+c6&w)L?6uG0jV^KY4H5Jyr zyu1t`HUXP}O=9`OSzEwiD2;~VhD!r2IN-9A20-Y5k+a-yOJwEBQQ|f@1wm>yxRLsn ziM01f_{*>I*Sk^Me=tpn-zto}dU+jSadP>L&H!X$0gFj7Qwl`My1E>b@uVv<`Xcs3 zL|2pVW43-m+zpVLjYNrDwDJ_gsfzf7y*)i4Z?QlcWGc$a8z)x)z)R5j!C$pIt=svn zjM&l=pmPo5;XYI&0NBBL^!rt&xT*Ize-CdgeDPp!>PW+`U2!= zbPy0W!bk{E%p2M1_h&0ZBY{|3z*Lhb^DS9~bR+-)#Z-po6Q9;uZtEZPz8{P#eT*3+ zT{F+3?dmZTwI#ezXV(fu1j00P^tGuQes`228n<=QcVBF}KCb4;mc#b{CC&CRv}>p= zBS=QKE8B%>)*0KrptW`<^uJJ!Dq%d2oKVBad8JyRCN4vW)Zy*##Fm?L8sXarqic?7 zn>&tsK$Hx;G{=^+Q3E;e|8W6k0H>O^%WbW;7vJ@DbO@!*LSy2Hcec#J1-`68eU&j= zW6?N`XCqOZF%$^q#94yHep9)JQ&oxcnfg}qk3Sw7M*a5>?v@Y49=3oaKsoW0{_Dq| zT^$2&767!|@F-eqcGef6tqs=%(9jwT?z&lLF|4VPS7kU2?j3fi%!KrBDodtH;!t?_ z_&R|cwmKY-=mA-8*U@U{rverVGP1+(7!kj|K%^zw3j8b|^G0ID_xdg*cCz3oG0M4C4vo?Oj@vT@?ctzsTqdl#ibI_j1!P+?C$A_k?qo; zUp_6IlOe)%1p-C(SaBpTHQL`4t{(aDWE$y56K!~j=WFZHwiL=64|C~!QUTe=aPbdz z3MVisn8f_u-rnBdS4mo*tu#gK*ua5gSoT|#If$PAh1n}c6a36sxY&-N%v?Qs*?15 z-0CGehg<|n^hWpGD+Y}By-)0)lWz|^`ubXQxtS_cXnL8|GLqWd)-fg_&9z9>^ykI0 z@53R%!=b&S?}FpQxntlOab8AFPHo^rH?Y2s6WJH6Ur0-G32^n<;VVQ{!g@&yBSBxs zGxLm`3?4>A+5l+Mv1zZaVXoof=fnM$_*OJ2z|jCK38!mE+h!8gi=lD!Fe26;JelGQ zJGH$5FG1+MorN<4sS}<{76tph4(!R)&*x4TOA+_STCFaJ?ZEzJtStle{B&+WVYin`m_BaVmJaN=(V#R2YuWc=*$fopTyBqT>G5Xc({*Ll`sx zJ|GuxNB^C9+wwC}N8o;TrZV#0NVPmdsjI8cxXhrx1Te@*?U&EWn~w*8mZb%B__*!x z@xw94Ki9^WuSP@=`Z}!XgP)D3BJ(Zyv%7l_yTk?ZMjz94aB3*xDCq9UR<|}crwne~ z{}wy&26nu6QEj(_*nzhwJ)of12b}CJ8HA^9n6rs1wzL50!XJC&X#7dIV*MUSDwYP3 zoESkCkx4&w9l4{&;d&qiTSn^MR;*v344+zV9uaCx!*2;n8fNZb5NEY}o=;NIedYj8 zdI?ug1rt5|?Dn>K%NwOvzYu7n@dEgNgiE7=sCuLFe=uzC9tA4$BXasf`q0TiDeAUW z&*Rtvf!xy0y1l#|Z&~MWV=X87pOyUYN~as$nL<6Do<@x2Q`@n*H*FY`>9*j5WKy6} zC_$O2l@$qL;cdZ@Py%t_t`On7rR17_2ot=*~l5Z|N-e%Rs zMT1<*1SZozN`D|~nMfj}D6xo=KrxC2Jnu&^MY@CoJzkQHoO!^$i*5jSo`lyvAYEug zw(K7da|{I)+cw?xb!3pmKo^?5)~i`QEVaNWW? z9U+;J3@Juu66Tf`|G1q6Egp<&sV+`CdDi(vL$n}yGqQvqO;Z~Ry1MKfh|&VST848^4ArqiS5JY5V}2 z#;-!3T>|)!s)=>!y242f1;xdmWBvkm{I<38xnjQJXT_@i7fmbf2A;qT3wl?qA^vZ> z0i2?ylM#`Fwuk%R;NazDL(tE&8DJT-y>k1HTC=dyy5G3-ghu>UEAUL~pX>L2%Z1_S ziL4xus@oonaS(9PRQ_`fmy$?c!8^j$=V~cSWr3pv)#9-iGsfA3_$>c#RkpRciS?=1 z_ePN)!}}tXprI9+%0VUkQ$i(wxPW0uR-RXvtNLrT?om_SWBaWGvRVrwsDh!_cz6K= zgO;K98Wg&x(LyQap{7kA{ANld+qk- zl2_o$=CV*svv#OL2MYkSx>Aik^RMr2E1tFieH4)=@6@%Wx0x2S8d>MLvO~<_v88@M z;`@!(9;d#eMMvO75htchlu-&@UzWwz&AsxZ>OESgpKaSxq0Qgzs8HKQ}CAyASSDM%<54dE0u&rOPCq;g65R~nYk*6H0=in zADt5~ri=Ec`v)#`V%sX}-1m=iUA|2AInr8q7^s2?Bb4b)9A16N`Fn%NPRwvwcJz{?Dsem#n0@elO!noX^#;3Vw^#!$-eniC0FihP?M z8c32dtz$eZu|gLPtXzY?{nD=-oZ+CQfQHP3glFdF0(A8e%TQ@{22iZA3>K435kZ-l z-V8JA@O_}4JlMPmMN33SNWN*o;D#Zg?&I!$76M3e_wDrig%yhgLIu+d|*zRSqb1=a;$U$u#R)||8B$9uhU0VsV< zb|9=_e}Gf_=0iAUUh?$JG}ug#&!AL?^~2 z=}?j(?Ma-P6tK=$u0);k?Gc~^{NJ(?GOVh^9?Guv4RR$v-sj@P#K*7r?7&y<&+8xl zsRe*5$b)K&k;A)RSzyVm&4}NA{`7O(<>&MMCC?QxA)&d+Nmszh%*f|24Cs?UPM!Dy zivc%#&QuGHC4e3Lwa%!|GmsyOa)peN(igx%a6rJ10q6(NSv(y7!$dS*EV)f8Z@GMW zuRcQ@&(ZdZ`Lh!yQAZ_yK=yDXd2eq$$oAut?BTz~{eGfht1jtN5Zb7p~>9Rcn3px%&y>UCz zY`guBPfj+vyZ!jH2hGDEimWnq&Z3m7qR6Hyy2^>qkyO20JyzyH3G%XPRr-e1ORAm&Lfb)puW@ z1*xPs&3i&+EfR7igzKg+s;~*De`wfb3&dB>L06}%IBwCO$C%C=6_*_NEbXQEKtReX0d=kS( zrWEkk90t^_C&L1xqoXUpWCl#y59^Klz#jDlh>VP^qFkyAh|_}NfST8VGxIwbyY*)2 z08o!S7jnUzc^h$aeZ89uuo*(J36@<3U!BXD0zd8TV8STY)mvG`EHRHTu-{5N>K(1TG#p+T^=#rpzfO+0 zI8#XPP#;zd`+AikV;>fozZN~E0$C$#0h(T23epg;8)GPT3`p!!fHWI`ZVoi@TdxPLvfEw zdG;MrTp_sxO&r@jdF$@iTT8ohip+wRaT8GqGU`^QYtUyM&M-F2=hb_I9q?KpV||ok23)|8KnQ1K4Md#Kho&aD9z9JDZ|Ow!NbO)acX++XU9__DGE5?!Iz+( zf$zfQe*Ln}WphDXRk4^8k0&!GapV*Dwgjpa}*9?CZRkFlXSxbm=cFFsCfz&6y{XpoUzya22+*-9~9jVvVyKBhx;oI zpgyM8Pki+p;Q7Q7Eq;6+f>8qDQyH zFB*`BzI*OSgA2>RbITmkSu#Q39|P#nEX(oTiWt}!H!8oZQte+ZK3mAKj#^(_lzwRc zsHIAifN4K4_*sGK{Nh|87;{%pT2ZH5E0&8t$kZUR40-gvMuM7(HAXYSovIgb1E@~H zl(mJ&DnfB!8mg+Q?CA>t%dg{Bv;ys`U$O7WCfqOqXeWj(c;ZOt=OZLX4@JQA6u-k^ zjDLNAPFg`ww;I0-El4vuOupl=Z@e>X>;ntr_xv-(9MJ{W78=S_m9-#sMR4y)2z31M ziIRGwUcJL35F}qsCo?Mx7)QNYO;7mjiYs1G0;Tis+|-P`_0C%>xwgH@Iuc9h$4#Ia zFddpYUB4YFiz*oToH?hcVM-h2{?I=5hIHSBsvOv1XxchcnTnkFnF{6W2|phktD`#= z<;WhERZAJRNQMHV&77UXe2oGah}0gl;uRe|@n5kyaBaD=e5_k-Ge5Cxr7Ihgm6=G! zI`gweUoGh4&o+n|HI{UEoU!z3h`TKYBW<0-R^tct+@#~lN>2h)Jo$$4^cr>b5h|qn z#lgx$`NMU&?E^Pnryaj9E<{J&(dH^-(V>D1naOS?*jDgZwYhfWiz6{D2)z>tKaP%~4gXG`>_4EWsj;!J zu#kzVsK%K8CDm5PXAbtWbB?t1452tvJu(aXG`-mJJnzXS&bT#gE>xj%c8ISfny+BO+^M-BscrDVlCqLqI3JHgvA}GmWl6gA>J25KAT9^q zC(lJQMz^RH)QRYu5G3feD#A-{WfXzJQZi<)&A*$Ir~AulXM~O6K1xe-?RidbTlXVa`ZL@|76{GKSlLeYea?{OcLs$sn?u?B&Qt)ZFQ`J* zJ7=c}=HlfA=1e2@bY>=|l4+Y>|KY-dyqz4cD$d-mEqf1Oyih~bH9OfGlc5QlaB@QL z@AV6-GUPKIYP2zYxgZ9i#4og*7@YF4DVupkUvPRiJOOf*H&bwAx%aSb>lrZq1FP=l zgVr0M>0jpXTYdbG0RvpuPK`!5At1tw-ML9C-hV(rZMi=_=sBg5@AzlKnwpwZ07I|_ zP`A}jGyqAi?aSyE+E;z{hfayx*R{I-iWflfE;#gZP2r3ER&fFV(NUZ+gKTVo%9INf z#5JsIZf(taxVXQcKdp<{=~1x4Sb9eJIu4bQnHM4X1sHjv>co6O?XqbZ%@@i(nLV9BZs_!~DuN%ap>nAmD!ea`Gu9%G#x!v{B3t>ap}S! z5l@LoqZ{^3zNwY(`JW~p-@XhY3~QGJWB#a>B?(A)6ag3E*xmmN7bt*jOv{pSp(hFY z?mMdrc~qI;Pw(a%ZbjKsjU9>B7yqqu*AEN~te*Rlmxm2v8y`Ij5M?Fn58{>Vi_q5V zbpdfozIwC7J^xX19MiG(Te}s_TTiVxoxBmh5sD(poo~5GF1qtZezpgcTb-UhiUXtV zj|~q)j2_O6IMN6IN%zD7?wrcox6K=`92-t2lvFRSfoKGyYnahBfQ+Awc((o<6#Y)J zSAc1((zN&aO_iQQ!^Yui=Rx4Z%|9{Vq8BQ5hPp+ceFdo3sfruLOQk6(_~@-`Ps{%t z9IVtk8rACFT_f9a-RVD?S$x7|d!=7Q9?^Qh)~QDFsKG7?I<08H$_G$QmL@TvQh=qK z_%_a=Xm5o1uEv52+bAp?=a_tG5C=qt1{3tVbmGrmYPBySHba91b@<#R%02JLG_2Hi z!emld7nH`WN_?34RCYBl-deq5Kv4E{d5;&{F0)maCJU;d->)b88Q+FjPV=`QyMhy5?H1lSUXX76#dLEwRqZjcin~wWynCXrVX`_|)!%H#{=wv;yVB^>%(9sd%WjqU!ZlBb~TWX!r+w;q45KD*2&gvT) zE>-!Bcu$ERL5N?#hXv<*^^TEI9w@!{*T3Nfb>87 zh3)I(1B~hRSeOa4`7F`9E`TgFcuOyDaO40X#-VEP>Xi8BJ>NhWl}YkAADV6`(BOrj zktu+`t@VKvM-9}LWq3|H#Xjl$d;|oB+AXSTa+4IOK)`BbAI%tq=r}20Sl`sRLq1lk zsW=Zbgy{}*17+5xHj7&S6)J-VMZVLMb$mK0(umS`lvY$6m|G>GXs4y6FV!q8-SRG- zrT~F^9~a2T*Ed&Dnei;$`IqrkZR$cr8V&Qq&g0D>P8yNb>?#?Djz5Ismy(AJL3tYUr;j+ zWjze=^jZ%9^MXosPz9%eR&f~s-?Qq4|JwN;IUd*c{;jF~B&*dD+xHZJftiGVyZS4* z-Ia8+(87|5ayl9%pDNQnkMOV_*5v_R%`KX1iCdne!Aqy-x3_J|Vz|Hbua``hKswz0 z=)zDxi>Q(;a>`?JBB_IPcL0%Td`t{4MJxd40E+`yiZV?kN?S3r-^`9504tVxxbkb9Fi77JbYs_s0TZo6XP^OLrK2qW5tCmQ4a8uTLcv%g@~+ST@BIjs z9^Ua#8LN^4@CY$~5mmOdKxdLn>2PkgV2~y;FkrM8vN*|n>tJo&FuTOV&290Sd+;$p zYWo~V`V(Pm>gMsP;Uv{V<$N0l@>6QoYV+TIF%aPLG!(N!!03dR9XSiwSXcnbU~r>q zr!j7e&0g4Oy0=z<0UZt1NZ^mrp5+okteTkOK*dHh!3n}K_o{4us}2zRlzJKI;KC_M z8boweah(iuPx!K9)r*zD#wq6pqd)K&Fh-vCZSuyykHof!`#@yo3WOk)P77)-)E{8l zzw4Vn9$33Y=drBT*@;&UQnmbZqcEWWt()Kihv>7DV*UaWj1w6?CH-Ix1IZMqLcRdo zldH9dOBw?)v2=Zx{>!xCZj*8MB?}TopMFEPd=g!nKDS!_Ael!mnMn&)-~2~`~sAqh5^f` zW%|g;%*u$~J|Z$!{LD{XT}8n%dV)1$UNSi?<==xp&_7v)s>)w-hk>lfPtAZb6a61d+;<2R0kVwm-h`P~3p}Az{DEzag3D(rcM%;$Exl9J^^U?|& zqOn9%lqq1_aOUH0ZB4EQQLvkK%>9k5az0-w^ZpV9ktQD=iVTU|KC^&pQqrs>vAGpP z(Ew`i{E;>~XL53HzTnVSbwiA!hKc_-{&yq})Dz^P)PuYhG9-ZDVG7X70C#-9d$4@? z>eLhoJt^)ZWU{WU%(9d6w>{;~0eQ;7y;o8&>n8VoZ8nw)qhb4^1rOsz1&gq+)tGrYng5RJk3mhm4rb^j%8nu+MjS!C+=Z z9hwheAHfUVtI`x-Robd*aYctkRj)F&ZCMf`e!U0Q7V5d`Drqa2k$6M;j{IRLdR#f5 zI8qIpv-rSW)$oLHX|CkqZfA7p`Th#284rLu)at@{9__xQb1buC&&hbp)H|e*j`@<|~hSurhS4Y3WM^T$m#hKdV7(+opfS$*ip)S*Yln)Ov&f=VpE>XZo z8J4POU#m;=oP1~duQ}FVFVOlGIVib{4(CfwrlIzigM&TR&68n^NoOiLnSyaq^Qr%% z>AS|-T+?@jg$A=|O{Oo)ug&VD1KWUtC5d+*=v^Si$N z)zwvq*XzEY&&T9mRsLL5YJNLUt|=7>MuQ2v01tnqs)~mw^x*Dy1cF&71{`UlR(iG; z35=g}LR;uQOB&84jd>bUd{av*R{szG(FyN1D6Tf|k0Z~4zMC#9BS(LmaG0dTVcG@s z_LFmWc?50X(jM{jOw(m`f2cG_HXK1n^a+wUg?iaI{!$=Gz@73Lp0qv&V~NF@RDnr} zRDrs}|A^ufJNAA5sg&={?nAQo>W))ar?bC|P`n0Go(HcnA4&WNabTo-t4J1uS2{Ei zmY9Lv9PLA(LW$tYv71XZGJCyU)Lt{qod=8&2-Py7rAx{)j+@8sY*eJL{em? zX-zs6Ikkg4CiVLNX#x1`{mx$gteglY4}+r+=H}+@dz@@+Oi_zp3j$viwW(eDS;c)h zsLPOhX<)#X=Ia+B-w(m$LWA+52mhFL%_->(k1Bds7qW+4wZk`w)9f_g?KV>L&gs)T zbV4-KLeCQ9fK^?9v~)g+g0RnuLXpPM`cdF-yBtPEMhyCpNxKIpx{ZjR5$%px(E*FV zN_7}s1Gq$A%O-!9rQ6FbTzcPj8hJv zB$T^-Ik-Ricc(*@`(7dQ3G5Hig{sC;K!*-=Cy0{T&!0_(e>ytvf03@Pi>rG?Scwy} zb2k#)ua>M42m7XgWL{yf65u1MqyEPtl#uWU=!D?r`Q!A|j^i%#k@op4>!~Abs~&GI z|G)6UI;Y=%$)&}CB1&T=T2}nO&mjPov+9p~=zQfIwBpklaJEPw0Y>MlZGoq;w9wa9 ztrX;QR*&&`c?oGlwg)@gjp(Oa_7Z_SNMeO?;7Lov-t?wVU>&)vMiS#J+2=a{J{_19 z11j+Cu;?=*P23@946<2+q&KmAk|M+4jfDfHIu`{=@vnognj{h9$^FH}NVQHzZu?c} z$0UsO2ZHK~PXjJlOokYLbH~4#^?A1INFg@0J*+IyXgMcP(N-}u1Z=XsW;F>zgl|?&0W!;JUSyMCX zYV6)Mrq&$;X<)|YOrvtr0JYRBlXz%UCZ*3|w>vEhtC4o6^8(#`XbG@5XtpN1_lS^jo0T@qI~Ly)BgK{+ z*AkA--tj?u+-sF?*rGHnhoKNmR0|#=3zL&rVUYEL?Khr|pB-O3_JU)UV3d3#(?q1n zM38&nZ*5J!{?|f78dO(cG3S0p6opFbl^W%BqzDd1Nk!W5m7}({w_7#}-^Ynv zZZtPHS5#f<^tf7$I_fuD#6J*oNm$3UOFr`}z5G)6qbzs*0c1hAISoRK*DXVzsLZVS zQOnu6nqyI?o+i5C?D#l@SW5yHY-YOaX4V!MM@uNt|B@+E5=Qy{1!d&Eax{vh6v46_ z&X8l#x7WqM%3YK}St*ELokqljK*4KXbb{8+C$VzigTgTKz?n!Emd%Y3{f+f`1#F-d z^C9)k@NzB<9CNf||8Gq{^;xI1xDcO^_t}EDgPo0ot?eU!U4*2%3iZ0mDEHD_aJa8b z^L4C%B2z&=3ehtZJf>yWGu*=cY*6_j#D0sS81~?;G;U{u0}H8nuNxvv9RX)h9}Ahn zscPB%-GI*Uc{BeZQ$88GWHEUE!)h;^BMvP{A!uDBtOy*4x>O3T$duPgZN^qPqdAHQ z9kB(sg?}|-`PQL+kay;ttG43(gn=4}m;YpAOR6UTkz0Y5f^v!6nL+y#dae;P*PX2D z=OwT8U$^?_qN6#6jdd{&hJ8O7X}SC_H7KzQ3H{?6Xvt$MONk*BJx4@Fq3DxK5ig5_ zCRMMdxg-dOgqfPivoRGzyCbO*5jQ(c9mak;{G6h9XPuoP{M8)?f8TRfd2g0<+@4fh z=lZPCy`!u(`O_u+NLU7H`+6*ktCZgrfU1t^HOee#4ZZVvLc1C2sM4 zNT2J_n~AbL(@af|O9<79MGm?Gkj?b3ozI6C>4Ac=L@m!%>6auEaRePVOdrl6;yu(vCW-!o(`5dhQ86zFXPQ(|;h370w&v+BisDT-k!x#k*s_Z!pHr?9ZJfEt3n#EGCBP={zpOG|^HG$my< zZh7pJ_5kaFDm>yq%_i%~e!vnJp3HIgw_3KT6F)yc{q^sr*%S@<5GwmAP-3sld~{K1 zsfW39xv*|Yq z5r(t@gXSH;oNib8&$M->CMWn^tPoKRj!IFv>%wuw7$J|QSu*FFkF3>y1?T2x_&?sH z4V|5xRbWgSUH4Q+a;s7hdisaldUIEs>VD~P>H7N%I{}7{llF~~Uw#2X?u9q0mGhfS z8HK&X*00}R^EPgN=2$38uXjP|A5V1MYmd;sga3PRHO#QNJ&$>LQrAkE64ghtYtIi? zho-8HJKRBKeo-eDVzx3M`Ue9*_&fQ-;zIksa1*j+~DXA%0MAy>RqBTq?kw<8? z^SN}v_U=;@Fkt`%;OtZ^J^>oqZ#h1V8jnq$?pmFWTVIi^_-Cy3`XAx+B{VDJF212i zR`t!yZ%BG`tP;^QcX|1K;wTwI!<@-yR;{p2TxiVr!7mpz-46qLdZKZK8!wBJE3`+m z|D72QSX5Ng7F4T94jvEH(jz+6?dp9d{|#>0nczXN1)RRGx>?qwcanWzJ8m1e$`*R( zg^kZDr9cKX9LjXh9k7VN#_C7Dt$9^nQgUG~Pjk^pKs`UxL@j|?AP?QDhsxX|iI9!! z@P`5(UO8{JY%?4<_Aa#fJwwz(5_Ebr6!6A5E-Ry@cQW|bI7X%*!H@d{@qp|`ug)sm z^sA|~E-ODS3c~dLw}c{Dgd}W3=#5n5n}9vH{+yqtf?3KoxM6gbxrIeeTuCE}AI&JA zQ})raZDrV};KQ3+o^58Q{T)?m)sG%`u`ok8={AERr0sdQ_@}LHr`g{`&o6=<|KFG|)_j24AAjcyAwn-!XA6dCgo{i^f0MXNaGdj0Q4t|>`wY^NIywsJ|4cW)Ld^9| zzs{YWm8L&r!7+{DhR{oMr<2FX&~GLt2HpLpYg`Jv0^~}`%jQ}AK%l_PC~dMD&a}Qe zUk7H%KV!dtC&%BNo=ky+sNN?8_$8SXPo@9F$6J#zq*~e-dr8{5(LXUMCHs?1b&?$5 zHCte)t*x!8NsIwVKV$G)Mxv-*Gk~Dc39XC#C#&{ow_Kn2u@eOb1PYfJBNzXcuEhq* zH%0#{c9CiI3`4{4Ffp0X>QyNqTvTUhxKPYOD<|Kes7(lcmvRdZ3a$Z8JMzI_bVIc- z)8w;lv^`^q<9nA6nj9VP$)K|t>pY-+x{7+1J8vHUlH+<16X*=qk1nnc+fLmKz4-XM za7eTK{#el~kPvC_&)ebHF=9j!Mf1Kzg7^;boysDO@@{1l;TmfUToB2r8B+H9^V1TP zP%$ttEH9InNZ8Y|U}k59!A7&*+%S+L`%d7}S$}67Qn`yfCmnc+LZogfAfc!v^`}@D zBltT!cu${hE2~<<=~H8gpvatF;eoqPF7JJ0$C?)09Ft?HW2eJDp~3RMEs4U^#j@8YP4K$ax3zR|onG6<=9&AxfEYV}yuj0vrvzpCs?_#bMFrd%-0v5_I!f8i#gn0| zVPWK~hxcWH|2Ha)SFrehZ`!pI*Tj`!ZY77BPRHfX_Z>dhHM}E23>roQWW3nOhfg>R+I&v{ z6LdE7i5*lJUuRh7Zm!n0XMMnvV38u*EsazARPzrz1iUK^C3xLjm1PQCcExgXko=~m zjI75HJ^=v`{Bygw2&l3-0buy%ErUt16d1aXM|0sh&OHi+;J9>CQc=6!e6FdfsVqb< z#!w|+r-yn*v#|b{o8uJ_L+a_-x=Ke#y%-AD%I)e@E{}- z9BJdeXmwVN=;kPH60@DzFF$O4xl%%8p|q@!>F_2{+&$M2ur#GO>-$J4>wWGzo!M{S zg{&_cGEs+U_{BP)ewLblYBqsQDMP&)9Cf?r_?DbICv zo;|N9FF%%#o(&WkF-xmAUSfg*9lv@o$wM6>y6=aCwUW?O$zlaLM-JZJ4G(rt2^^+K z3{sdZ8jSS&HOmL07kR@;!OVx>tamF7qKM|qCiEGWnzvINjBHFhZNGXr1kUIUouwP= zIn*J`fpBi!{#iz;Fo>pQSq=eQffg%2KDJ>@4d~;UpKq<8K>l6eo?yefR)-$E^$R@y zLvVMc+i^Le)c$4@q|2{=`C=F_p*?Rx@bdV-w2tf5yYu*XPJ^#pS;JV8CT@c)3>c*g zEEi66Wdfw%3LxPUTai@5#qOz&J!UnnSq~uNJomXwAJ{aS!0GD1+-Pw?KPb$lW2B9V zz$YNswre9CN=4F_D=-!+VXM$21j}He6zL2E*Wa1y>FIeIQrXm4w&BwkkU%c4{QCRl z1`AbxHH3aM4EjL`bwlrf=~)>iUnr8#9^zD+QIUz z!L6-tp2LxKrri+^0x!Hy9mugTB0HOCzDAgyw>LIbLNFn+%oA>TH5Nx4CBJIvXA!>$ zOh%eIg#2-0kYV@l$cEP3N>!Z;+)V+{p0ipdh5rW`T_zx|E3cSto)y@y=_%Gc2 zLYB9-&U3{a9JtOkeA!_S8xz|%{1tf9h6{nRGD5x`YrvfF2;v!BLSX!OS#m=&8-h-=^BhLEbKJz{wz`YV5)7%Vks{#56apG(DU?^`8x=K2R|kS_@6A$Y!sGnFK0oOl!C9BhjH~1xD$QDB|~m0{m~QG%V6*sZ3r` zN|Z#r!@jyKYS;lyY@gYl?@P%jGydK5nC0_2&2c@;H@P5r&&%7*r_x>P7^ciojk0sF zMT77Xk#8)dldB0%PWc%v3Vh)=RVSXfB4+)TLT!aKotoT{fGB}zacwMc^V>1F8D^X1AE&eRdEBa$idD(@dW!3f?u zcEZrgk9M=~wQBLYad$EWc~B^?P$x)5qg| zzxA_}IJ}%z<`e|GQR}O;9k%FRAA(k78hnVSC2f| z*;%34hlh{noScpGhW$`k4UP|1aizOg5DF|MonKK>ELyL`q^X!5vpZdWiu8PY$xGuIA;VcfCR^ezB>kO1`ldbkIxsav{guoMGu^ zm)$z&B)p;FBHMj*$QZ~tXTF~o%Dxx#nXg$Lh`!C`m~-_Pl!w%BahLGniN0)$jpWiu zF@$zPu_4nDWoS;qLto!kqw^Q&m$HZ);YjvH645c_haa#6o9m-~`im_Ak|0(N#Oad7 z_p=Y-h6cN7!3=C z=PLx~o2gH~S`Traea4Ci&d+pGOC=g7mx|2oT*>y!wI++$8$IXYU;^!=TDVXRBrU6! zl-iOLIaIZ*Dx(t(2UaNlovguSLN`TQe$<5bIpD=GTPNiFBOTzpo2v#_+DXu ziX5Mw@4}aE8I5lGETdpjeDkTXEJ-_sbneZ6Y7EKFSRru7IdTfMEJ6TZdFP(>i{E@{ zZFQSjyqb4A8kP?{-f!@6XDI;Y3HA(7H=gu}kH(T}7X6FP=OY5u znvqZvPYGet=oM)#1+q(xN0d-n*+NKxP^|v>zcsZSTmBm@GdXn+dX*dZ2$@b4{NRyf zNiYPig)q1&IqPuN>z;GC?iySiYCjTP#oD;|p3^jswOF1e7wGHN?db)PSR;rh2w2~m zeka!8?%+JkckHKTv|AqtuW3uS+qgOI*z4FV-D4)QeB!@)%@8NLl~irq{I?`cx1)XS zuTp!n)$r4uCqK!{k%)1=ZZ72y;}A%GK8&~wLee{Il*QEnHHNr>)RM>_Gd1c`f$1QJr@6Qso z#zo7sg2&HOka5jM2RA)W?^;GbwQS8a241^8qc3&4U~imhS8@y>nQE;tXW^zw-?}ks z_n!e)&y`Tjha+NFlrr(w8r?-zpY&t_RK}`*XUrXJx`3b&fgYCJb4Ubu7DIR8t zdaK>7Y*?d5UpSJsgi(Ur{J?v@VW&XLZgnt4MTI?upI?GjPt%;N@A72(3M*pEzCw7t zea~%BXq|^dDsq@9A2;g#+>esV{&^H~#D^>b!Q#Z#UGG*U$dl^i;869k3X@R+B1z99 zLmMpNY5^$6#>VFIp91(L>nchP;!rwVI=m9;^E=VweWm9{Z{F@_+E?i{xvk1RF+9H6 zTk@PXr4jjC^zI=cl+LW?mC%v>)s8v}nNf3aZ1WU{g|j+)N#Ja^B@hx;+}~eOUJ(yq zZ;+UzdvBzy1EJVJy$iH@OKwA6x|QB^Sp%TqPd8|@l@o-d6omYV=o4XLERDF?4u)YR94T(o$Y+>K9SS)fz8#tcsu6Nc6am2wP8-YbSf1 z+yOr3#mO(t_jv&XL-z{S+pE2f+so}|)tuaQ_s?04S?_9^@hKSS!18u4X#bECIO{oO zOcOx_`5RSx@$j+B5Lo^cK8!awG8EEaeg7TiigdA4JKc9=m217?)_Cy*@2xHI6OBw} zP*xy-SM=e7eVKF7n^;-;#1f@6Ir<;%Aq77UVoc@Xg0M)_*SOE-t&(5hPxx)tnCBX`Ra9TOU3pYzI12KOr3ixzQ;I8@+J5hqu0}?r90N)LV}}>k;od(xOYVqtnsui9SyP6 z`Nks|acy5{J!8`Kg&*HCRtYt2Wb?qSf>^n6@eDc15cc^XrepP#{p3e=p5H6Ksg1K; zzb|di-EVE*QGV7n|I+~hQhpluvbAWo?GkoEy2{rjhJi%W~O+hLcW^@dFV$ z{Es32#qQU8&pCK(I*b4)(6|FmA>;F|CotEOt%-hWzkdKw2F;VBmOL3CY~H$}O_y=F z(E7IN?)x)ingKt=N8QWu3K_ietb%gF@~k|3qU9gut0$|z%b)^|7tjHlK%MyrVx8kT zc~1@iy;wz19Jo=wf<)58%*KlaC1thJ%%wD=%P%0Qol~#Y=JxvHiIMl8-@n!Qo(eC= zjH5|FC0UG{J@g6--8@8do>I#)qCRuMl8G_Bl+68<{tNqWf932_(g>tz>F7+(&9wyX zyvCF6Zpg3&8R9LKm7-b0@v)`h>WC1O4OyR#+}50DA3EXtLIgxY*ge3Ri(jgV`@^SL za%N=P%>(3XdHZb&nYPz{A1I4Oofv^Q9&%LNMf+C#$RB2 zt+t=Wi%sLzW6%2#u}QtUIHA9h_unm)rfP%wb?Y;sdkC>R4h=_%>vGVEBkl)Y$lYsLC4RhjNQ&P#l_d_`gf9JF1!M_iAQe_-=8gdo7v|Cvi_L^ z=;K-JHd@V@{rbw?sl(dGB``&AbF|#%P@c<+9VQC9uTgrz znrZ=CA3qoYD<@#rtiaXL25w}XDuavPZwZ_#9=u<^)=Zt0v|M;_DFEYXF2~*l0{JPt zMD@i^J+Z0~8ev}G zxCDkt451X>xI>m;bwdLXD0o<~4J!|QcK9f8gyU!>?qsS=uRfpq*Q^E0P_r@Jt3YX! zND2UJp*D;}@p8Nw2f4Xbv}wJxd~EKg*FIoO-t-XR7l}r}BJ4FAQdi&#S<7N>n z480&95<!ryjk<>zkQn9{j28YOap;7fT5?Rq}=Q{2Mw*d(TE-=Oifmb9sR2_ zGC1Jjb!5>7Z@c57|9Hb;uAqq6ZaCVXnEfu7YnrBd+XLAIqU<+kg6vhLdm8O~EmalL z+dxRE|N1p}!PqZA&TeTi`WRL1P}ExoP}L>GG)4k zguxZM-fL1r#Po&}mXi5OHC#QqY|v~{r!lB4U}ffsK(6oKTeX{i*%TdtGP-I&0ROt; ztggQ+0-HKuoAbG^*iBTxc10!A(RM1kUF)AJ@g6jBb}7 zQdD0K%DV~gg+33Q7#DXN?xm3?0S@Pr2HWq#NBV)s73I7mqhe?M1^QLxBFp|em%Bn+ zkey48_6#Xe>Y(#K?*MSyHBq4(bRP)Uad#!&c6+`YFa9Tt7-C{$vjHCaz||Dp5y0{J zi-`*feVxGCcvob!c-F`DN~5fdLXGd*mINF1SPERQNmU(+eEFolinp-FUj zQCi2pJbeYmgz4#5etuWKfB)`_rO>T>#ce;yHrH_Px(Ckk^YV(St-ZaD<+v9pq^_Z7 z%CZmuP^8Vxmq~REYQX!~es{B{#+(eu0K*#Xy%jt-_owvCtDPne^GbS+_P~Ivj-ZXP zJz&*zZf(LMBuvnV7Qss%D@_H7@XZD0H_czD__ej8WGH)`$Y`zvHYE6SH1s^kap*ic zC8QL5e1up1ZEQe5DB$Syevr{BPX2Nk0hTRfcM)k+n57;<0m83A*Oq?r3DPjf=T8;^ z?cr0ANgA=lEVs~BvGk0s3d4i=8a#ra5_5NBHxFtu%Lm8KvLnOGy13xbpAOYnH%dG+ z-kK7;O(4pp328TzJ9KyZ7gs9MaSr_FcFj8iu50=OkJiP-ulgwLPl3bm;^8b1Wk3T+ zO6Io3gL$#S&fC=-M_AOmO|as72X`-TsXF`)&x|hyb=`!|nzyUt`(EkU-UC7AS2 zYb}RBuJ+^05YtS^U_Jf&$DBL6vk6b1GKaa0;7F3-vV1>2UpK?VpbLA{k%nxps^D~# zQeb=hzSk`KC^t9v@X)P)rpE5QLRqeLar3;OxMX-9i)8m(6tJxLORq)|j8F%l4;GMj?G$w0! z@atI7|ExLM*QWe9^tu8_5?Ex?OS$#?t|dCqDN!S4d860-rU_413nNn;Z+o|n&`nZ@rwbF zhxy^IgfmD6Bqw#~X==LP-JH`oc>O9}^XMerb)hxs`lp|@7IfkWYm76JS zx}2x!REt>Zk?8(6VEy_H6bn)P%W=z<22F>+zkWXUPORQ-6^L*FG@J;?5iN=xASVEA zncKU&Ms2=dkgWIa)}cYLM7ghzus3Ycwb0+OB?5+k8EW#)Tr{-b~Y zOHL@X5!PW$&OWNDs;cprtlx?3jQ%kd7MiQf5qH7-u$HtTW2Q(Cp1K808xmvuoh)Id z3M{f(rW^7MI>qe*X+v#bem{E57Sl&8VMCv>lI=V_miUzFlX7ZS3OJ&2Kk;46Xo@D{ znZJ1ddVBi^7aj^72QsF9-rfDyay2TRGH_ZxUi7bEhtKh>eU;etes`U4W3x!pRPGQM z^Z+l2O44A~;OfiLw+4t4K7~kgvmkRaX;dvw35KME3?nf%6oN3mt8t^7N$xf%x)9hG)*>D!*6n>q(sg_D(vh_cAdw#5s=J zNnmQ7Hq2^z*{tM^DiQ5c{BKoniFhCK(>3aREenTRy-kDH_=S`O!=|MSDK+Re$mF%y zPY%{1qW}6zK}adzxXkt6I!@|V2bryI12a2k;Kfbyqj~F7&Y%uLh`%u;A0>iMe7aP3 zIs2aAZdh|W@a)6sgHyYo&A5<+0qn9dK4Hl9zV+zM;lN1bW>eMZzpbwE{ILed1|v(} zj1PfXS95i(r6T}*@Y!}r~QTh?WDf*YPPPf?%B!74&c@G7y8a_KI8>9 zH#U0drv?3R(?JZ!*B-6y>$m*+YW8h-n1Z#POR%uwA!#G082o+B-z)I1sJ!M6#-s^$ zn$~k`Ui|}dE(%J@d9am&VFmJgEz8-c-sZ>e-zKuM;irA~$qg?qR+2&P7u(R!Nop%t>1QPy3#_UHS6Y6JY z$RC3dSwuH&q2Pmv|W1cVc$jl6gw3%h6Q*N07JjtqHHC&mLvI#>L?UEutD|JK~z(VYH? z5BLXyti*19-36{be*%HCNQ3<4+XN{tD^`}2p4!^Oi=!u?g9^wPu&^Tt70D0*dMqWN z10%$ur8B_6ZT{(cYa!4vl`>Pu6X4@J&VT)JBua;2{v9wywe{Xv?VoOVnKBcC!=$jc zT43}DEg}UD8QHG`KHmkD5khdO1RnT6Zrbz@T6$FUM(VVR27)dhsTsRxO(S}ekr#-F zlqlc714ApelW?G!U-mRLw&tyoQkK*8B{<@Ew&zFNtE-wT+g@lM7d|VW4wXiO_kOKepGOZUax!kKQ!{+3UWXg_o|!0fbB`jbkyAONLproilf%_Da5!N=N>7DI4C z;b&Dj7hXyi5EX>0FHQF-KMejW!&Q&^$=c|SuCmcJ$ z%}G^fExRGfrbX%$U&oz&Pp_Msm7*sB7f0{b+V&fR{(ZfAQlZX*9_IQGLdFXTCcN#b zqd1+b`;+FCd-`|qHj&$Tr1JHlfjGp)X}itvcA>+-`x5jbUM2@fH&r=RdqepetkpxCmf7vNNrc^4tCQ~i2IwBk!u)uR-8;x)bkk`j#k zu<^dWH5t8`W>5R^8GlE|FSf5Di6(xHX%6pF4TxThF*l`@InDtWR^F(yjWZbV52A4) zHaX*yOLM$JLS(+CJbIl?A5l_WOIgQ5E5UbWdG6i+`L%Cfh9tz|tE`eLQaQ>0XYomw ze{3pi)GA4vG+R?joka_QCW){eIJi+Oq>5lzHcutTLGK(^(9|3UuPul*x(A8?wBk5z&b9`b! zvzu?br3?0AV`8y#vns0;b+ikRVYKK>VGwmKbiy5ldP^O9JCo1V9gTH$FET140d*Y? zA_>o`VWEi`ROE(u=5M7OA0nVQq4}Ra4ZCI^931EZdOY~SBXtC5+R?UfDU{;*Ho3RI zhbIeVl7QhznqZ(s7CL-Ckz&M({<=z%)GZkjmSN=8))ONk4pUn5idrBjA)(7}NHmT` zsQBnG&_h_mFEu;vjxLvOY+up^Lwi?E@AjTt-W)x@dUSC-dU7>tc-XVz2>Uap8CbRS zJbWQwlhf$p7wU$j!%}}a+~nppfbukTUc0Y3r{(&*BQgJPJmh@MxFweowroY-^Sm<- z9ZljS@5JSXD9gKPK<{twD(DwD081nIK|Z>ni)*KN*qmPU%pu0wl)}8X<-G< zM+vd3eEjocG1rM43;!fmLWLINv%36K81NKi9YnAE6SiCKi|uA8N?FBuW~amg6PV)9 zFcB2fJ?@o@8o`?w;Kc|&Z`aq=T)n#8-*N-5x6qg zGbAZ-3Bgiq_(4lJLIrN>s3gSW^tj`5c zkH2S(XHruQmGE{Qsa>z&glw1e_X!oGTAn)@;dH)pcK4Az6PYDfEab^hV4Q3}u@cES zY0a->vzm>ANg+(h`ohjy#-bJXtiPWWYBRo{SrF-4Y;Z(;T=%K79u-h=2S|;LO<6;O z&gcu0WP|@?hI`L=M#1Y8N))0nSXPVyAHqUt$fdBkJIDcbIF77($@CG?i%^z~{D1<)j%DLU}7=Hz;$<<=eqRuyS(%p8u}YUyNpLd zzoq^Zi3*>;U8uhb#n>o*RD?pHX4Ms$?IYxorer|+4Fo6mcPeO}>?P$CJFGCiPnkRL z_TOo4T&o{ZEr~FTW03jAf^#FmLK-V)z5D4+ni6>d67_TJjIEmuL-p;Uzo1!$rAq9B z?vEoURNDMs2DY9Ky^XgTceqqAiOfSZT6Na-a0$G^ zQ12crCRieuI+CbsvHeg#is+8<^7=zKE+^0`>%dEnzY##2_Gdq!krvWRz!H#HC_<@6 zB7cl_916l7Fkwciyfm2C8~P+5=F^AC_Y{DE{l5r0%=c;<`CDS;mhq<+YU*CNbY;B+ ziWoDpC-t^J__bJ%7aV-05bH0Japn3AV}@| zo0Nk6!zxl&cz9-JIq(srRDXK?)dhG3LS3mI6d5#ER54|A9d zdKgM-Y>AqkUafJ1Y3Yo8=CvDEiWO5cCS3pPz#)*yL*CL;h|) z=Z+J<_fI%7=YGC^{N8e$e253a#DoDS{1a2(=4G`j2!ZF5lwKBkGJi-46QlD&^4VR6YJYAXSL)UMJ@Dp8qoAg)s;J;q z(ac)%^&7eHdp{*BD}h#o8={~U2zL(*?lB3Ib9~5+D*Gxm_GJKpnnqI|iO@vsWEY-+ z=fofP=Q;%CnodNk3Z+F_p)b_SId{~h&E@|c|8UpMw@39Z?$NkTOhfk<71V4B0ugx;oPBBi94O_7!gjEE3h7s7KA8~dTk6AFTeacs*IFDyFt0Zp&%`;0a^-SU6M66H{ zwFyKFepj>2%@Gk1SWdHYJ+|4r*di~0d0crsMyRi)++9BgKq+ujTyB!CBlIN#z&!m| zqyZVk!-Yghs-u}R;>~+Hw>f3W$rgV1atGcL;Ire!eKk$tG%GlR|K+gZxomgV?^2it zhS}3pEt|PF0?BuMf}GFhH+Hu!C;6xDyIUf?cYD{3TyCFiQ#{S}J_fXp*G9oREF*9S z%NG&09lvz`Ymmu(OZKv({iq|&iTyPrp7dNpI4so^t6(g#BvFAeYq-Cth8EUfI;o|- z)@I@%3OJ#LPmb+WQR$__WGvAP={hn42|SOh%d&^Pjf0#yvL2LxH3dQ%oQX_+IuOG` z%BAN8!iZ)P8rU8}KrmIW+3U>!4-dY)QDP~f_2!kRH)MxiABhzq8j8i0`C5u_G**%b zDaEK5?)R`~U9V_A%1DtjK}vYOGrbXQY2;Fg3bLepzb1;-?DWIKP%dXU+M7J$k58`S z+>54aaP;%wrztZ7A*OlF^hy%VxWz}*pjF*~g`2#WQq<1SFVo}!d|XDnmvTOE&r&G7 z1P(*suyVJQxWf5o=O%y*8yHg}9Jdv0F{FaA=om8Oe8Vn{uTjs2e2I2I$1Cc&aeE(<9M)_|Z4w-;eXV3Qo=Ba>tbO&~hp?NSKsh%Tidn=nB=jO*?7nsaL z!+)*OuWLa~$#q~*CXImv?#J#9$>XhiATu$!vg%Vsg&_NTSou)E1G;E(s02T&*G*Hht>#^lNPz`UiIzoD?R<4^ zJE+V+S#b%6v$WF~0_KmH@iSh3DmFOdj#$ z*DpRF6>xq-ijgcgLRmUoeMtkwPNq@hJz7U|o(p4MML(bpJB$ov>83!r-uH9n*M7oY z6JW>^y~$zfxGY7fwm2Vml;tvN)(-{_ehqn`gZ6f}=2Wn@bPzOtA@5OiD!v|kclAE5sI z4MI$_OKlY`)>g~SRU>0^GUI%N8uajzV7H;#zMteQmPeJ7p4*c-u6^WRJUu&t4uevV z&vHGGzI>iT?2QJV6WXR^zDCslSqWefy{;8`gCQ~;qgvdk5t=;?uQ8aSQo%oWswyw7 zD&$f0adjfZpqI2%H%mXQoD}{M$vf8Q3QPwoD)0ITZ%tSie$>!YJqbs5T~fI& zWMjyW7ep<@e(WEw7UIRfROlbo*Ugxkn-wN;v3Z^N~6U`-ljAM}-bIp#bnd%98 zCT#D&#E++=rT4B9YtDpM zlzsa2Ec-d_1$f+Cwl8$9IpE9HTmy-JJYQ)@EMqD$BG1eT=%+~_{%M!+;to}_?FNc%zS8h z(oWmku?M>YvkS8}V0(z{H3L7PmO6Lud>VB$)}=#7ZlV{FX7xUjj8ZH)?)N^dd*_@`X{LUuZG`E6EOR;`V3P`Hy{eb@BW>=jS%2U z?EcI^@J1II^CG9Vk8k+f378Y?%aZ~q0AMTtk^GICQw6Q>K0X%;b`B0~_>jmApWHVe zH%IMWP(nPepOv88t4NCb~S>vUxR;&}Ie2`=1VQj(4YDrYD+ygDSuJVe$VuI`4R@{y&Z%krCA;v#H{fBkVE*W;dZKJW2* zKL1qGqXcgt!~7U4z_J$lF#Z19a?iV*mMPD+4S@erW{%n_t*5Cevb3&Uo(^^TTs5n| zFm>!jPpCbNLk4OpalC}4-e3*KY;rNxry5GsvAe+oVSri>VT||{>op)q2$lGvz&b{b z_`<%S>P8?5MumG^+{@0^*0$eOp;I`tU4ZI35B1k}6LVe+m7jxojYlLzR9rkfys|&V zdO`!xD~yn*C;kD;WMo>o{js{?Vb=9WE^EhT*czHGBIY+X;KuhEn6xS@bY*5<$GeY< zib@`?5boaX&Otv97EDmf1Aks%fmO7A`P*H+=43;V~(xqH`&>lIKFy$gb>JcLs44kE<>;kPrT;$tNFQP z1tm979(PpVJ8f0G2BH)Gu1;Er1aL^hI+5+>#P|Atvv51ukg>pRG;L_OOPN_*Y)H74 zNaSrEnkXO}uI;p#?Z}$lGv$_F;CL=d&hdGC(!vv4^wF!g@hDNs4$Nx~pdK2TdnO+} zbw$oT!B)?B9yOj#H%ZB@d=U0J+{&1y!!5P8BJ;!`t-sUmM6+T)3yBnZH+ic@zNv4s zyM`DSLUCqK2XbNJ;%KM?U?rMvV6u#lO`XQzVFE$NKu5=>O2Rk|o^hLsLWVKtvtSh~ z3893m8Xbz`(dvPYsF&P{MJzcaxYFl9gFEQNKl|j(00<(#eT}4lNIUQLW9vxOUU;I3A zW;r|NhIr&_R(a9$9zm#=y}gdkYo5iJW**6s`S!L2FkVX*LZ+touT}>xC@g!W0osAgGI|Gp5j|h;J&c%mm`Eqn# zu8y}c2KkezG7BhWAh$9(Y0jf}$TWjRgaNCThu;c$la}|ECqY7d$~Az0^4A4hE6^;boFgrIp*b~%M11ZWikuO8757I7C)r95g?2}k?xa{I<;bm8l|i3D2@ zs2T9oN=%(f?a(?jEs7Ol(N%-WE~%=sLh;g4I?_6`f=la}z9-7XO?zW3p1(eU7(ZOl zNs!lHk6!!BCEpJRw;SrB284r2$U{l0N@=FX9{g~yS0tRx3Gw0igiyaCZ*$WSIkvn z`Zr4pKAPG(1M&ctk#Ee?b}U|p|L#Fjs#IlTGmFCn*A&;41PElDg)6!J{Mod7xA-_m z>Qpvo(oQthcQ?=XbS3BA>CE!w-qqQ9Gk;>Zm$?OYxB|&`HpXaMfh_#e*tm<|T*hTi zDK8AOm(yj$L*;=L7q1gp!LFqZmZD_i(f3ch8ttAZGLIzuC_P&DdV=N)zj>R2f*z+~ zwr-3XCjaGCv<^p=ukFTYixaNviwjs?4^bpRIkLqR2|ul5N4M%V@_#i$+0=@#1(dR_ z4SCqj74N+$wZ+-^e=Ha)b5pLLT~d2lqyjGzYZll#X<8=Z8yf>>>;2?W&Yw`z5*eFW zA>>G2)~~FO26_Hw{w)bYhd-H)cDCaUNOgfwN4=Ld^G;om#@Ns%7PF2s#6zNO1wM5_ zG!zxAuTM3!za6}{n~$+^^_QK}f57=)YKh^=Kc5!rYaHU;NtTHmOKY?!^$<=i2+|ap zAvR{^+UnD6V877I3G9`Eqfu_3KivN?kNul-USM~~`}os4A8@&%XK}ZF{$kGeD*qkv z9bw!vunL9dbPXmHeD+>N6_7=m=FBS^DaI0EpRgr>;;ONw?pW?TcNNvGsq3MWCXSg4 z%LAGAA`CJRk__u|u@H$}K!&Dv}25LOKYdF~SmG%#T!l8`{h)S?_zh$d*f z{@!N-U7FAJF8(zLlJ^Bdv-SDO$eS-2Z>w(3JSlAxN$CR@*?c`c6I}&5hG1*1G_g=q zXaGm}$NB35nn)yNvpsDNrO!lTBoP}rjy#$On6R6uRWXV))YXITd)AvT``g^Al{PcS zngVjUmF9k4x0xO!BDvKwLP?<{8Cz$BJ(ryReFp!~@oNh51AG6t=q~lMZq@5&K1`hv z5xvgNz!-MndQe>I%g>5m}E_Fx}@IBVdH3nK)?u?8D!^yUGHHBCMk(Wu^hBtmBU=SNo-_(~E@eNAc`5& zq+22z@`IeKkkUuS$H-dAX*!rv(GzOs{Kz6R*Q@UQ{?cT-r8Oy1uK!-v#N-33?FpH5 zPq5R$iWu7iEGABm(G*4SL~F&+~K+Ct~Sxwyx4Z2q$+^qp32ZihdUg_{z8>$}y@ z!nI||8K0CzwryfVeO^TUpl;oJmipV{^4x>@h3GqHe1;?#uQG;?TRkyFEqiFtx_T1- z{;=2+c*hKKy(pQ492N-6;ZKtc2nESx36t|S1dp4we@rN;V>y&!0z)fueWVJXtWC;Z z{xkcGqM3z-L7UrB04PywyDfDd|M<#-Yr6)T>Au93e}vH4TA7qRxMd7AFK=m*^fKtq z^!+9`sQxJbl+@nrQA@p-4Mu-0k{PgX?TZ!3x{Kg$>ek<3Jh!6g@Njzw_ z&Ug*l_y?GJP+5Y0(|8J2O?z}pzK8G5d&Qb|KKpK;HFwfq{#3vE*?h91Fuxrv1`cQ= zC;s9xy|-hFJ!Y+^)71)Qho{W;ba6?dW)(6dW>g5r$VY!otLXoHcrSP{!8`e3y5k*1 zD2n&qE}FJiIbv2#BC(Hr;Cj2t^MPc`sws^$@>LhF3+;j@)fT@0S>5>bmXB=1FPb#4 zoLgNahq%V^5yQO?FL6ruOFN> z$}n-(+GMaQpb?zXNdV=G!(%5YqJ*~X1cM+N7Kd1<{55kbR>J#ziN&)&4~Fb3K9aPE z-Y1riL-)eJ^QeKhP3mXx4vHzWtuZ$Qg)-SPJheJ0@4gimeTRD<)z6)P>*S-_Z<>xf z9?yL|nq>ja-S@q>TW0Iso0lcGNc}LFyVCc#ko0v2|5d+!5L>Iy%G8d!x#(Ycf0br0 zb&*1WPJIMQIJ1KW10@y%_t`xE)-F#Shy#A(i{0IzVCpWgL`U}r&QGg+=haA8plI74 zkDNPiAHIC2TU7LLxjb1P$2}|?s>9hj*?(hCEGAmKVw?era|F4O?)@9GtbuW6D#dsS zr-i{CLg#B*E{)@e=IuR&NG7gyeVVnozm8kj8(AOOnU+Ghm1Mti^I^h}#)In_;ye0z zx+5BJtzGlBts$Ok(n31PQ;rK=8uCpQWi#ssC{iz9MvCUi%xW1?B*;2Luq$PQUzr8& z;1{Zg9S2*;;H}i3F7a6q?DO&60|^sj>j#9+NU`a39+j_gUG#$0W06#>+^-yT5l~tkMC{3ne!{u=iFo6(>DFUu}Vt{v{d6^T6-g*Exx`Xx5Tz?~#R6hV+G-Ze2H z!F&Fyo%{Jtx4O^pQ5v%L__+FV{Ad>B;QU8o2{J4%w~IjvbmZ0fj#*+8VAOX_frg5#u}C9q0hC6>-=LqDbY5%U zJ%8q)hRFF<%_OOvk)$=n^vo#<%D|u(fZz@#`9hYyG%3uj9HhdU7)BU$WLhYkUav=2 zQ*$>n*F0k!M|)()FMEtxJ;@wUANU!i=}3zOTaSegiKJ-|OuBhvHe&0QYh@bU9cg=f zTcn-df*TBV-J;j6vAd!fbm@_15iQi@GO-#6iHu$-Bb8@|zT45yTSTYr<(+g(1Nl58 zLV!_)s9Dl4Kbk0ORT+NYGrp~)l)2aTRaT!p3uzs27+9bVXPEXhdu>Vu4HfYK^L||# zp(WrfFE4L;)2(36a*T1)jggw0n>#Nz7m0~kC+i&>)61a`DrJMM@)wTA3-Nb`rR~>{ zVk?MLGYzRwoYAU7w#^cNN+x-0eSN&V(bKv+@ ze$=vJ?SKpTkf9K$6f?tAsgtPlOM?l?D>=YAEUpo{a^{ouQpeCRL&_JdkBq1=6QBg4 zblQ&7$cXTQiinC3N)_v~HM)AoNUJnSfddf0fp3+6#7#WOgdYMPol-6<5J0QoHTD2BZBjeBy1uq<1Q&z#iw4&Z)H0tpHfW7?k(GiOYZ~pc zCgrg4l&I7!*ngm}e9==dcT+r$1`IDhQ~!rZu5Bt5v$p*fGL8)&BK=gP8G@t=C6X@2 z$7)U?Of+ceO|`YPE5@(ZEUr$#kIM91%THvk=R}k0m$}tnY`5K>zfxvl^J4+mIDO9# zs~fj2wyqTHeN*>m!t#|C3McKV#U=l%FgP7PC7$wx5yj9i-O(2crZY`7a~-4xV6olp z8kQAK`uVP{eonP%cTK^!WJCn`sv!fQ%dOE}Nkm5E&ZB>D%HnV?mL6PxKmZjtFSj{SwBt3Ybwbb-U6q z#&1kLji;C~%&To;6YI9nAPMhG-@hAHeYgDtu)@*UZj+5K$60*5d&t@@-#+SYI%`$XEuCRIoctl1{z18+SrD?)aW_`|gfbH}B0~9XDSbM>Z3x-bNDr=;>M8 zy6m@aCNN7KR2KWFk~@M${im&tFstemW7;zroNFUIY$Eqo+{LW^_wzC}6Dt)rN{C;S zzzxuLVU407%OcbPgDioXJvRKe$v55d<}A(1bvqBJlUN5uwDROghOIo_H|ZH9r=)e6 zd7Dz1s_-qsi(Jy|s+T=(ttH-jDLb`L_fCwKBQT;$41i<_ngQDDSoUfrS7H_*D#9Yu zLp-zBT$l*TeC#8#!WJ#q==_dAoE>*v%^~9&n124x#zLHrSkM~ z=uFF?Kz~+fqwe>+npHe+?4Kdzy9S|cPz#hJPPo>l82>S>dgk*XYwnEv*J0~_hwKBT z64Ri$#Ot-iRX3-zQK5plF%ym$)|)uRTZka0tg1SWnj8um{L$B6X#96E=$|*uyL5SK z>8Jn11)zEYqU{ez*t0p5;xy&8coKw?nIOtq zY+t`tc3dL@AAw_IuX!=5B>(vtDI%53Vt5?ka&jUS;N!_=x0O>NB1csqF{^Xv_8hvkZyZf`fYoIFC9i~s)P-#lEA72QQQ zWpgNiFyNCT&d-lsE?7K_xh3-c(;3SO?e)qaL$TQ2IoIU^ly*MX}rAlT!4KTk?hLc;5J>vf<8jJ7`ssyN6s%bZw_ zeC>h@A769xV8MF|6s9Oa^Ehp!qZvwYc&R=tx9OYWglZrW&_Cou+3FZJxZ{tps?;x1 z`8#vBlRDPvck2lPtNn24DZ~Pvp=?)eGLkB`FJJW3W`h|e7}#cwSSJDCEcS**0JTHI z$+5k<#%PTyeYo7{M!0gK<#0Cp(-R3KT_kMRN`~7PE(1dRReX%! zW9o*ZhB?7=ETIN4O8umaj@cX9n9e?`&Vqgwlno6F+x?qtkc^sNuXyt&0kYbihgJql z?>&3(S?gN^s>T!ICqH*&igSnvfhm1%F)KDvO4(WkY>Rb9@e<<)7hD+Xlkxh;n15Xl z8|tFp#7kvU+ZsfirrPm&BdZm9s%HCWPATFeh10>p?Ur@0YZ%;;`&fO za{23`dB3^o@&Mm>dEnl#rp9XU`-5>|jZ3zUs>5bJ&H%Zl5hi{ovv>WJS+A3%!G>8 zZ`DW7dZQvJrZvj&+b zq5{fsEg}4m`R_L_b}fu*?eVUs=??_NkM{@F{y6PpBg}Jgd?M9c>rXy z{?f|{GeFS%coah!{vv4#vsoTSWQ-UiA87 zyVwaU2XFwPOC;Or=nvz$N13OVA>TiB!Sg4%b<`#+DfWv~#!JW1jl+BQmIw|drr94tPimo>tZf9_Cif* zQdGZwVkzbF=?~5w3%u*u#dG#3CVFDNkZH?N_kq649%7bL@Fh2s6L~o~-@LxnxQ2e? z$I5ZKIe$3|+L{05fOy7Es+z(t*h;C5 z8%ERC8=hRv}_wbZ0KIXytkuoljXIlZ`?yEwD? zBuSIzeR+NUAiTqb_Qkkd`-v*v$j0_*uQ4`^A0X%Nyt)hcDe_j{qz!($JYEv`q{R$d zsnNYZDleEBL3$yar#_aD$P*Uy3kU`S+AvduHAV!+r>eFo!lvB*H_y{O9s&S)n3BAV*2l<(+elvCb_1znVvH=S=JpEy>eQt& zoo5g1l0`&qrp!u8O7>CzDUp)$or5Xj)hV07kqrBMMWcdl^=h4HEZF4uXE9hzahUDX z>i3A@sCrf=wQ@*i00jDKf4SR%bcrKp zsUzpd5^mFAww{_b4aB@zXZoy&F?Sm1Vnd8ASz?RU?J$@XcVbhN^Zno~LEK)0b{=Tk z(c^jT*8g)#Dr&g$>9-=jPhVcYed>NVdLC4M5dRLc5_zA)2Qnoa1$<=`SRudk zCZz~z&UO`~e%`gaWz+96dKba&Cw3^@)KzfVJHo38k>Ak9Z!Ir+TugvdwS|QVkt@`9 zaA!yz<@p{;*-3hebS*W&&W^>d+^*&%#VG<{;1H+F?z=~vlN`M-16p&ivpiwA^S}RB z0hNnWoSAq0`y?Ba3RD1yf`(|UF;hH}#9~rK8b_5)B=pkpkJlX7b#1g>7Ez!bKAC^# zyYV*C_v~L2^p5&-4^X(foGCT5dDzOa>RP|$iLVdkL9ul@>TOoJ1Zjp-A{28-bV%fZ z3JR0AGY=E}6_jkKYKu~NUKQY(JE!Zn{Prc0B2Gl078nNs&Mx{_!MPJv#EExh9Zis9 zmX@~T!wXn!U$DmL`XN*Z9}URk0Epo9gypk>8AOZ1YI_?U&7TsoVb#E!;(gB!p%5Ktu%EZnvYK?&I76gg7qqgXX2GLqU2)=1_wx8QX~9zkj=(6*2bdUmjQ{eU zhnzV^kD02~MiipyKNL((FSpQDBS<3MRic#-ZcmvPye<}_U(Q(O!#Y}$eqnAX6_4sO zp=qdbG^xKowNok!q&f3)f)9|^9l2<)+?1N+20Afe{ZC4v-{J?k{TbpXL07vc>KCVSKaMRxk)-qT0BDWBjnJUw+EI`? zj|P9pU@&UyHxtq7acpF<_WFrzg5cTLnc#uvrYOw^seSaVn2x<4?HeUCJ7Tj#-WEofDJYA~Fq~&@nL3*DusUq6sjz<%v}nr&@iQ5JvY=F%k|~Ie&n8 zT)}&kahL6c^YJqLoR~uhHxanN=+%zT(5RsT3OSxrcQ|f%+0njGiczEp($5eaUq8t7 zSvv-Gw9XhIx!ia*BT;H*0HuL4Zqk`k1zmfiR<3bE7+E`;H|B*npI!l)#_A_R$FzCCqN+7#+e=UT#(^<)$v!yofQF{%? zjlxB1huTGZ)&KXNQWMr0G>w3^gKz9#)#7Zi-EgZMxWAG~chrut)&dAq`2a#P&f|-{ zInixk-y;~`dNK4~{AErCJDpD5x2M%TlG*J1hcgK=_70nqff!njAt(S( z_O@!0{GAg&!CDum(>$N3*{VZ<5hNWqyI%YywI;q)EG=5ZPZ~!QhlHr`$3BX`QLDf7 z&${k==t6r~3nA1Vp#<4Pf^RJLe3A=Mj(4&L_DZU#3V#Lp4%Sf;E!>l=j9`d_4FW-6iH@P`tTn9zf1Y!%X~T-AerPo(#)E1$G50$KfkJ!5s?RXCikP68y zjRx%t(QY=hsr6&sUhkX%q5mk$m&(Mn{|gQ^8YyP`{|UY7#udxPZgtoC;Yl3;UP>?2 K=requiredAlt: + print " Reached target altitude of ~%f" % (aTargetAltitude) + break + print " Altitude: %f < %f" % (vehicle.location.global_relative_frame.alt, + requiredAlt) + time.sleep(1) + print("Generating waypoints from tlog...") messages = position_messages_from_tlog(args.tlog) -print "Generated %d waypoints from tlog" % len(messages) +print " Generated %d waypoints from tlog" % len(messages) if len(messages) == 0: print("No position messages found in log") exit(0) @@ -124,7 +164,7 @@ def position_messages_from_tlog(filename): cmds.clear() for i in xrange(0, len(messages)): pt = messages[i] - print "Point: %d %d" % (pt.lat, pt.lon,) + #print "Point: %d %d" % (pt.lat, pt.lon,) lat = pt.lat lon = pt.lon # To prevent accidents we don't trust the altitude in the original flight, instead @@ -143,31 +183,9 @@ def position_messages_from_tlog(filename): print("Uploading %d waypoints to vehicle..." % len(messages)) cmds.upload() -# Set mode to STABILISE for arming and takeoff: -while (vehicle.mode.name != "GUIDED"): - vehicle.mode = VehicleMode("GUIDED") - time.sleep(0.1) - -while not vehicle.armed: - print("Arming vehicle") - vehicle.armed = True - print "Waiting for arming..." - time.sleep(1) +print "Arm and Takeoff" +arm_and_takeoff(30) -print("Taking off") -aTargetAltitude = 30.0 -vehicle.simple_takeoff(aTargetAltitude) - -# Wait until the vehicle reaches a safe height -while True: - requiredAlt = aTargetAltitude*0.95 - #Break and return from function just below target altitude. - if vehicle.location.global_relative_frame.alt>=requiredAlt: - print "Reached target altitude of ~%f" % (aTargetAltitude) - break - print " Altitude: %f < %f" % (vehicle.location.global_relative_frame.alt, - requiredAlt) - time.sleep(1) print "Starting mission" From ba1d1040b58200bd27080926a90f7cb151050c35 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 15 Feb 2016 16:54:30 +1100 Subject: [PATCH 309/475] Make example keep only points separated by at least 3m --- docs/examples/flight_replay.rst | 125 ++++++++++++------------ docs/examples/flight_replay_example.png | Bin 168903 -> 416006 bytes examples/flight_replay/flight_replay.py | 30 ++++-- 3 files changed, 85 insertions(+), 70 deletions(-) diff --git a/docs/examples/flight_replay.rst b/docs/examples/flight_replay.rst index 53a71f30d..d68b3ad95 100644 --- a/docs/examples/flight_replay.rst +++ b/docs/examples/flight_replay.rst @@ -1,22 +1,27 @@ -========================= +====================== Example: Flight Replay -========================= +====================== -This example creates and runs a waypoint mission using position information in a TLOG file. +This example creates and runs a waypoint mission using position information from a TLOG file. -The log used in this example contains around 2700 points. We reduce this to a smaller number -(that is able to fit on the autopilot) by taking 100 points that are evenly spread across the range. -After 60 seconds the mission is artificially ended by setting the mode to RTL (return to launch). +The log used in this example contains around 2700 points. This is too many points to upload +to the autopilot (and to usefully display). Instead we only add points that are more than +3 metres away from the previously kept point, and only store 99 points in total. +After 60 seconds the mission is ended by setting the mode to RTL (return to launch). .. figure:: flight_replay_example.png :width: 50% - Mission generated from log + 99 point mission generated from log + .. note:: - A more detailed example might determine the best points for the mission - by mapping the path to lines and spline curves. + The method used to reduce the number of points is fairly effective, but we + could do better by grouping some of the waypoints, and mapping others using + spline waypoints. This might be a + `fun research project `_! + Running the example @@ -45,22 +50,23 @@ In summary, after cloning the repository: .. code:: bash Generating waypoints from tlog... - Generated 96 waypoints from tlog + Generated 100 waypoints from tlog Starting copter simulator (SITL) SITL already Downloaded. - Connecting to vehicle on: tcp:127.0.0.1:5760 + Connecting to vehicle on: tcp:127.0.0.1:5 >>> APM:Copter V3.3 (d6053245) >>> Frame: QUAD >>> Calibrating barometer >>> Initialising APM... >>> barometer calibration complete >>> GROUND START - Uploading 96 waypoints to vehicle... + Uploading 100 waypoints to vehicle... Arm and Takeoff Waiting for vehicle to initialise... >>> flight plan received Waiting for arming... - ... + Waiting for arming... + Waiting for arming... Waiting for arming... >>> ARMING MOTORS >>> GROUND START @@ -69,53 +75,35 @@ In summary, after cloning the repository: Waiting for arming... >>> ARMING MOTORS Taking off! + Altitude: 0.000000 < 28.500000 Altitude: 0.010000 < 28.500000 - Altitude: 0.020000 < 28.500000 ... - Altitude: 26.150000 < 28.500000 - Altitude: 28.170000 < 28.500000 + Altitude: 26.350000 < 28.500000 + Altitude: 28.320000 < 28.500000 Reached target altitude of ~30.000000 Starting mission - Distance to waypoint (1): 6.31671220061 - Distance to waypoint (1): 5.54023406731 + Distance to waypoint (1): 3.02389745499 >>> Reached Command #1 - Distance to waypoint (2): 4.05805003875 - ... - Distance to waypoint (2): 4.66600036548 + Distance to waypoint (2): 5.57718471895 + Distance to waypoint (2): 4.1504263025 >>> Reached Command #2 - Distance to waypoint (3): 1.49371523482 - Distance to waypoint (3): 0.13542601646 - Distance to waypoint (3): 0.708432959397 + Distance to waypoint (3): 0.872847106279 + Distance to waypoint (3): 1.88967925144 + Distance to waypoint (3): 2.16157704522 >>> Reached Command #3 - Distance to waypoint (4): 3.29161427437 - Distance to waypoint (4): 3.63454331996 - Distance to waypoint (4): 2.89070828637 - >>> Reached Command #4 - Distance to waypoint (5): 0.955857968149 - >>> Reached Command #5 - >>> Reached Command #6 - >>> Reached Command #7 - ... - >>> Reached Command #42 - Distance to waypoint (42): 7.6983209285 - ... - Distance to waypoint (43): 6.05247510021 - >>> Reached Command #43 - Distance to waypoint (43): 4.80180763387 - >>> Reached Command #44 - Distance to waypoint (44): 3.89880557617 + Distance to waypoint (4): 4.91867197924 ... - Distance to waypoint (45): 11.0865559753 - >>> Reached Command #45 - Distance to waypoint (46): 9.45419808223 ... - Distance to waypoint (46): 13.2676499949 + Distance to waypoint (35): 4.37309981133 + >>> Reached Command #35 + Distance to waypoint (36): 5.61829417257 + >>> Reached Command #36 Return to launch Close vehicle object Completed... - .. tip:: + .. tip:: It is more interesting to watch the example run on a map than the console. The topic :ref:`viewing_uav_on_map` explains how to set up *Mission Planner* to view a vehicle running on the simulator (SITL). @@ -132,22 +120,19 @@ In summary, after cloning the repository: How it works ============ -The example parses the **flight.tlog** file for position information. It then selects about 100 -points that are evenly spread across the log and uploads them as a mission. - -For safety reasons, the altitude for the waypoints is set to 30 meters (irrespective of the recorded height). - Getting the points ------------------ -The following simple function parses the tlog for points and then -returns 100 evenly points from the collected set. +The example parses the **flight.tlog** file for position information. First we read all the points. +We then keep the first 99 points that are at least 3 metres separated from the preceding kept point. + +For safety reasons, the altitude for the waypoints is set to 30 meters (irrespective of the recorded height). .. code:: python def position_messages_from_tlog(filename): """ - Given telemetry log, get a series of waypoints approximating the previous flight + Given telemetry log, get a series of wpts approximating the previous flight """ # Pull out just the global position msgs messages = [] @@ -164,22 +149,36 @@ returns 100 evenly points from the collected set. continue messages.append(m) - # Shrink the # of pts to be lower than the max # of wpts allowed by vehicle + # Shrink the number of points for readability and to stay within autopilot memory limits. + # For coding simplicity we: + # - only keep points that are with 3 metres of the previous kept point. + # - only keep the first 100 points that meet the above criteria. num_points = len(messages) - max_points = 99 - if num_points > max_points: - step = int(math.ceil((float(num_points) / max_points))) - shorter = [messages[i] for i in xrange(0, num_points, step)] - messages = shorter - return messages + keep_point_distance=3 #metres + kept_messages = [] + kept_messages.append(messages[0]) #Keep the first message + pt1num=0 + pt2num=1 + while True: + #Keep the last point. Only record 99 points. + if pt2num==num_points-1 or len(kept_messages)==99: + kept_messages.append(messages[pt2num]) + break + pt1 = LocationGlobalRelative(messages[pt1num].lat/1.0e7,messages[pt1num].lon/1.0e7,0) + pt2 = LocationGlobalRelative(messages[pt2num].lat/1.0e7,messages[pt2num].lon/1.0e7,0) + distance_between_points = get_distance_metres(pt1,pt2) + if distance_between_points > keep_point_distance: + kept_messages.append(messages[pt2num]) + pt1num=pt2num + pt2num=pt2num+1 + + return kept_messages Setting the new waypoints ------------------------- -If necessary, the example then reduces the number of messages retrieved into a set that can fit on the vehicle (in this case 100 waypoints). - The following code shows how the vehicle writes the received messages as commands (this part of the code is very similar to that shown in :ref:`example_mission_basic`): diff --git a/docs/examples/flight_replay_example.png b/docs/examples/flight_replay_example.png index 51a605a5bd5bc9f06a55fef216a181b5892fe241..67f29570ff30a742c3a931f4622074916fe0e07d 100644 GIT binary patch literal 416006 zcmYIPQ*@+V(~Yf(jfrhfY}=XG?r36jV%wS|6FZsMw$VvCwv9jUck^HL>h(M~efpfL zy?5=Z6RE5yg^YlY00stzEF&$h3I+yo4+aM53J3A^rlUg`lxljTE_(p4Bhp=5BQb^i3b?iXNiosh`NWt**k0i(WoadO7p~H zcP~O@s^`1?RKgxxRH3+RBgJ?kVXpn?^IDh4^5xIh=gmV)psikF(O+R%3JHJ=)9r<` zi=sAz`!}4Z=uviR_X{temT!QBt`XP-Sa8mZ{beujqJVGvtLyS(O--MJ$_4@k7XK|4&;E z{Fnpu*%!&8Hr1J*v%?GDEKq-uZgRm3mLmfkMvt z&r)Lx+j)-bEY2F8(75~<`T5B2B$!Hsp|!H-U#qg>NDElv#-B8Y&=to`HRj8=7v2u| z3(h$AM}Z1pm)=}^c0IH(&fIzPLhndOBuJcc43|Mz70WubKB=mg{j1W%>3Vyz1?W1z z#JKq!OM|pa6CmX3EYV+Utkv4nl}LjU%yMUz+1#c5-%sI)of5wKLCr=Gnhl?OjYlAXM)T4n0FtISEP~k zx$J*`^Dy`mm%gXe zaUY}p9~F+5}z^|qvN@P?Z(D69L#-QHb1ZH8|wf4sq8kx5r#5u zQO67sVMh?~Kt&jPJRyx@`8&+mLomb5clF;!GyU&Kk@D5kEtr4@2XaRZ3GnSUg*}fp zD!ADf3cUEy@B4W|H)%>f-Osi;H&H)}|0E;-6_ShV8CHiUQsxzNw@d2$yifTkfqaj8 zx#_dFht!ja46ZB`9$R3sA0O4@k|aT#PdplwnO?2=FNn~p962(hgz*~Ava{&%O8e8L z(UrN#;IbLaCw1^_{q80(ggimzkklw89a(!N2+zGx&%HdW`$=8jY0>H}gM7Tx-{QXA z3}9x|OT$t_OFHYj6MRfrpOp9xR+qessmBlq!TSWiAb6C7u+C`VPBDbQS0JiSxqV9( zn|&Ts?ApmD&}sWx$HX^nkQGNJYG4p$^Z7pzHqw09be9(5y9K_~)dz!l(uiv@>-BB} z^QBTORprmNsKi2%7e+RtB&Oi>d_~clVyUe(Gqhx6%9^5(IjjP${|j6%~7DeO&>f1h4E00 zWI(@j_7Cj#Hs|KC`dcSYV|!biuefv>JVKBtdRC^P{PSI((}-UNqGs!_609G&%e8H)AaX8FNyQzkdlsoOV|0>y@jE994K^~FhV4TF1^ci#j>6rqX> z`6{-vE|}tGPqu<#QBX+i&#wvRD8d|vO|MP>gw9Mz{e9`CDdLA~fr@xMxI+>LxvUDX z`*K~`<1PD9=g%hLN%YJ39|dAkal`@!Rh+ck_ATjZmCn#-_mKCH{t>T%E^PL9Dm%lr z-UeR*%_sR^4)+&eLPJ>s&^;$B#_Tb2_M3Sn2nW4^TWU>WtCVKcWc0k(7^+b+?1Lk_ z$?@e8NKSK;k!B(Ab25=d#3CysXN}9rNvdT#+&W{QoQkIma^n!yu^;rmIRABaGy`)T7N z_;r|isIsYoCMBxjA(~hop@FzW$-7_fx(Vh?S#W41_w zy>X1ayodN#XYrn3>4@=T62kR=m8atbLf2aU_w-dcemogFQgsqCOh6b_(mR4c;1kO; z=V?z%FjUX!Fqp)(0eZ5;WydyYPQV*&zSBCVvBQ~?kv2nI&Yuu5&-ih~5) z)u&FC1|_t&|o8pu#zb*VsDRD)~_u5hjIv~*#x<- zxvI%P?8p?|^9!aYFV*9(cs-)IQlCHhj`ET~YxkJ7(=oXght0q4p2o`HJwn;=+=gsO zNo-8;#7@m#7sBSI+74Zl?lt4O#%Di{8^U~ns#En@RLj6~FIg%@;=wCh07-#?~Q&jB^!9Nhobaur%gLiP0IoI`I zl({Jhndu}eGM>YwnE!h?x@t-~N*RqbFR6J{Ymhee{p4xW);CMB!{1eUTuttLkizx> z=)!664>v{+LTK<+ZVkvjsKj&+G#O4Q+XNz>Aq6-v3KL5h(4|4>!Xq)xjdpja3~eS@lly*yuG}f>RUZW z+X=Y-I-a}21U$$l#=AgL#%5Oji0#+;<<{d+S2pD=B3iJPln6k=R+vq{%7CEBN8hd`U;I zYe_endr|H!)4*uJx^<9)sgBs!r}S(XRBboyz_f-~&h*I$;5DEMAnS`%vMLl~dLDDP z$lZ$t-$0k2chpJ(Wd2oJTWVC%iFNVn80h`bGBRS&`u(agqh=xC%f6*=qFV1YjlS=w zA8+Ma20XLrR_D?Qv;;LeDQx>NLwC5P=LhQuC5rRT^&x!!!MK4dbipi*y1YzvgqrLi z0QZT9qrAz+0PP!SoVFoY4KyQ%4WgCl#UE6aa8lO_WWD&1WyT5Fa2+L(Q{vJ}; zx??`G*@1u>9;wPr>g~tK4n|VZVmU3kQqrZO@y9Mea>*@T&jr`l*(~uNpCWP2cO^|} zUDB51QQ4?Hnh~N0%YHe69Fp$m3w~~(8GwELkTP%#avo1^A~rZF#t`s{T++wF`bmuP zHZ+1;qtbgPbVxu!QZ`y}66xr3ujd#E*{hmm$2|f(r+Q2qJvVoDiTqnD(?J^LVx|W# z=fHqYO*+0l!j|UBe%9lx4SG&+FfizH_Z*#SardISnjer!9w3uuiUkbAyxEYR<^O96 z{n7{7;$Peaqr!xVK&2kKnJp9y3=I^5{h7#P_H=ZVAQqk^5t2-p$UU-#-c~36f(JnU z{{8HCVs>MOnJv!hkr7|EMPD=bL`|Ik+krQ6`|VcA&)`)Q3}}=r&5+ek+;sFx&LgS7 zNkzB$fP^LYZEuCtB$ zIppCCH>m9+sXqcA#jpXiv^r*yQ6yR&W+SBDzV&tDsXBE3G80kAz5M>M(=ia?>uw0l ztQ}|kx$T#Okd3YI5xQb+7w68BEYcyh@-3Q;XJEjIF+Unq@hH#Dnzuf+vXx(sBj#nb zroPd79iiqMl}t+(S)lQ{HB%#KtBl!D`A(0N?L#MjTwVH}mSp?Z#q589n6>nmn*x@A zc)0HHm3Zb3AKBwN^Qs%x+z$MI^H3}Vl) zczY%t3f)i%MW92oR*rc|;COdtb|k^vH?Z32udi6^2E-+i!|nguaZj&=?gLO ze?OZt=%IV=Z}OqAcVPb_5dHTYJ}pI&AZM@2<#adWS%>S}V(nx5?=a);@_oG9f4+hs zdqF*@lvUtom4axnv*-OW?f16Ov9oh>5)$y|rDk{(17mNNwVt1>Sz#%Y z1nO1c)ohxA);(SWoAytC7*15e=47mjO9?+u($4iN7`+EHYZ`syx*|A&$YsFWDA$Y? z2O=Sn;a{B@Gn*b3B0_hwL&fqC`hw|;rol)&2lUwsq@{85W#_wjpTCmbGF}5JT8DK)i8Y4Vm z0r;kGVK2To06O9UXobyTM7ZhG#tA959mr-?)e3=YUcK*{vR+xv{c&;4hd9C(j(dhQ z4FOl4Tw4>zz?a=^+8^`i(4OL1uTr@zTpLg*vYl7zH81`ca|7(jTACA{#VGHhuDud< zn&;pZ5@TYCJ-+IBlM3WEEyKj>`>I0c-9>17p?i(eGT!acLTdiq3~jw6oa9pw{5I1I z+}PV4I98wR;j~E7AS{VHOnN8wj7fY&NT1>5H&gbeDymWU4&RK~q;Jtz^%6^VEk7w_ z+gVm8a!n)TFPXIx^wQVuS1fv_>1C;kg5HIRrl85viB@lFYb*A>ipqOG^ZI4IbDrMy zlNy&~PB#j&FS6KiF^9WfUofbEB-WkF;UCwr2!Z6PG9fm-fx%reHy#=HkZVS_@>u^;I(&F0Dbg6WF zVHaH6oChDajS8$W5q;=QeGRiWQ!LFyP@95i@s)q?_6H+Yb2Ojq~? zz>vq%{T`hOlNXXNe$FYpkFnT+&_r8%HJYlkq(jgxX@D)d`+&V%-Ds2jr(5Rzg9D__ zXe^5g{WgqI8J5~~?-or&!tZDDbTn%U0%0uLOg_G=^>UEF#3pLiOFrwf)Lga^XYwGh z&}hqQ`>T8+>qE&qYFk03U`QEnb2BwnPN5C8H&yaWjCz>=_PK|9cF&2HDkhH4;XI39 zE4HYV7Pyg=HQ*Yh3u-8}G&@Fq^nR0GNxRhlXZJ_Lk2Zj7@*mIDmbib)e};^x)G5Iv z1az{91@t_}U;>W|Mq^#$Ot;(ZK}zuWQIRQ+2)IOtVwvfOT}e8<`$$lBEEN@1mICuU zeU(rLscaN(syWv0(1!=-a&?Xv)FGuD2!4luFL!&9V|!N;g9!S_%Cfad6p>C9;a7Ds(fUlw^Ye?q<@L=? z4F*j886It^M#svI`{6>KuW^UmjDDszPyw^pw&X!jV8~RG)AKhC;&6 z8#M8#RKkq}!o620T@hY4e;vmp@@dQw@NaE{H6@qR}1Kq9$RqQ&1hF* zf|N^-(FIL*@>9zQ{5+hqpfmWJvZd&#-66i*U8EELC46)u0#tsv4C;4Ha@ZLv$ZYDe z!YYeq)%kCbtUnIrUQwmVi%-dkkXY+2HVo|HWPaeEacbL=i8CF#y1U=q-`_nxBBR`) zqM*3Cxnm-D_P0Krt=7Ws=kDag?DFtccEc=Xrh;0bS75{qaJSKl>7m5+ekuJLUdvtn z>`%(Y8<+TUE2Vu7uwZCSSli2Jy9C=`q=#$Xr@Py#Tojb=%Sub>Q%?348fCAFUW$@4 zMR*~lNQSS#?~tW)&e#bXjMJTLM6c9X7o1|LU(04{Fr)-C#(`R2wwBU=0Vm#*ZCMmi zGy_{CSoQ)VZH0h-7-N?MIq{RC5MOz64Eyc1{MbPH5@yz z7TkP3#f3k0m7HKGeaY+59P-b#9{o@@b23dxs&Hu zVu?SuFz!>b2_L*-wOi~qEe3c0xqNe)x_#DnR9Y^Sh)QM9`DZqYHj?=e`(RRc#1l(4 z5XxUX1;GV%z2v+@aeWL~)br3UQM(C|EvO&f<2aFu0=8*EVBx4WUGN?*DLL#zPGzf~ znEgZNtUB?o{J4+3SK;TWL#J`pH)mzmFQTHpeeaQL(tJk)d|4<0%t(MzmR8MF`&FC3 z$Ex?Dt^_Cd{F7};4VMbr$S-8$uvmdwuo6@?8h`=est~}sFgk#Zv%LP!**6*GL60(3 zNoWhs@r5Xo)Fm*3>qQLp@%O*XT%_lATx)gM%ruuvGeQG+>(wdOGDb}=Sl)sg9q$kV z;IKfJ=Fh=#Jg{Z59vD(xzr`{+p)lw>!Y;aAV^iwW1UMzAOp|qw+Q@j;k6b5+i3ptA zaqb@w^Kx;g=Gfw5VwB{A21e^~=qO#7bOu8LN!a`1-)QX-fy6_8T` zrvsc{%p&~7ETT~JoyvsFIoa$Dz51jy%-U_Sxr(P&cCkr`dR8sJqifHydfC{A?AA|C zPV~F%j>GOx9adWX7ArI$-+k#?CI^G_W4*=-*?xQQ`#ZP8y4S0Hi`_N^KyCZnF5Z9ilk6yDHnJY)1{P6Zs{+)V;*ejH|laSx6U<`ke?nv>BS4 zntJJ_vt9VlgqK46iugG7Gw?H__7?DCEOLv!WJWJ|Gui|%{yh)W?G{~*DUIo%&sKV( zJ87$Nw37V5m>X1SdrQkUYOA{qQDqbueY+7lhaGp-84g)sK%PS5t zit8`80~g-$dL`5@UTA%TcsHm0P-Ev!iIQ0cmjAGWr|0b1ph_hxWLa}|qo0Nr6PY}f z18&}`eU=BJqDY^q%CO~NNzXyI-4%YtZk|KwS<50#69=n;A=Q&lod-pdFu1kN!+!>A zM(e@=*j?Dq@cSn*JViP6ow5;1nQtglRF;!^)j1OkVVnKBz5RaRhhVFI6b|#r<)y8o zqYEJ#H;LCQuKBZxRP~IpHYwqMM=JVtqby<|f7A~2Y3`A3mA!%A=B;FP({@>K zYM2bK4-~k&0k@2fe+_PBrIzQLU)AQlMp=Ly(Ji4KdAFeGxPFpmcYt~Rtz;>+n3FnA z+%b=X403MfWNfX=D8ZEQFW~Pc`sfw`gk6j8Y_S8O`du+N@?L;E1mX%~OoZpDsfUk` ztwFJ}S18OmB?+Q6Xk*}GXd;t^VDRa15^4K-66W$eT1>gg?wkDj zrRDDr6!s_i_i%S-v}-Z^%|!ABE*Tj|6dM1hfJEi2RW+~c-pa?4UW^4e7|e8|OPdeg z){8-vPM$+mItE2af_0}+2T=M56!*{WbL%op&^Yf|;-STl>F5LkV{7f=yEJ*Mmh^G4 zwLxi)^%|tPc4BHt<9so_Ob6VQDKt8@8ZXT+<%SW>NaOvGo&r?>W={}rlnZ6NXBW_F zf$ESC&bpBGeWIi0qvmtZF#3}@=T3a(Roms2^;!;9PA!)LOv%J3=AAOH!mH6b2VP=51N`tdIqjy8&b|D%_+Pz*N=o1!fZErQ zkM8TNZkIEyiMxoF-JHHd!B<+YZ`8)l7g~s92%$c|v@Fwf*VfmZd9zKUT(Sef{koRi z*`cUgSrAH?ra~_lPZuLKzuH#Mf4&gpfDcCZ@QRML9txSXYa9l_m&b?{d3+RSZ3h|m zpQL?7lZj?QBU$vL-64P2{r5wu?MhvGCmJ>H%v9WaT#|k~DobRl67mv-8QMfCWQx#a z>U|4Zt@1>2Yy6C*!;qEiQa7MCSD!08^!Ic1gSle<_2sj~vAd_05y$r&;A&@G zV)m88AJn&-G=IR`djdb;p%&_XRRuuU`7YO?KlP3ao0}%g=${MGIS|>52jU zgHpOBUu~hH*e`lNg$!$;!8589PBW`9YGo;fDAPv@VPRYkbw=YJ6Dvqo#HW_Y-e!;> z0rRH`Nnv)I_!*pgjS<$iS)a>xUWNzxo*apbU_&0uC9zXVaSS>5l_lwZvI1lH$zjP* z$&2tq^C8I^PIGkH5?NO&@6T8_w;?~EKBb?fGtVr~3{@X$ZIzNk`LVo*@q#y9jPDT&CAV;;k8}o`_5a4wSXnB5Jwe`u6cy?yeMJSZB{p0SWB^t zRwZsDWTi4!uk!u^ZWif6S!3@rK-8qkCbJGk8igignIS)YCOycaFwiT87TIDO_Qf*f z4S}pS2}rp|E9w^)uY`VsMCP9oPj&Ik@f83HQ8a*vEGl1d=Y5wGD4nFSAMSxN1XFNa zJyj)Sk>y^K+X(%6J(uPcTaD~P7K$45pX1%H%hPuL86|rMi&?~7?;ri)apK<;YQ0Z{d*cr zNdn7OsMc61E`jl1St~U+??Bf|5CIH6rA9re8q5=MC&`_<*5;?k2=h1R=y-qe5k=7t zRx)n%8#c1f!ln;&nR#czssL`bbLshN4#vPEnO%*1@5DxS1uwJT??!aW)Pk|QQEUDlHh8+NW#wqA*I{vAp)rma8Uz@exBD5u zkc;p4?B&K5>(dIaOaGt2i}MBRx6rb99Q7gtSDIYDnFA_>(8e=&oqSd~zDZKKPsd40 zf{z>EE_Vay%myYS4oQ2wYfB;VHu7=dOM$H*UsJcW$792%g`eD;eCijW0*L)=@_KL> z9Em48qM?Bu_L`90M1s!>XI44@vrBn|%djqm&x`nPTZP%!h`yN< zQ^uJN_vXF^v#)*8KNz66QwTs%OWTlDOEnK&4?k^05w9C zJ4Q$bLsMWw{s;@a{@4S`dqe{ICwJ+g=;(l|1aB50Wu0YyXU$4#e{|J}=c z$0WwF0A(95a|eK8PXSI?n zL%?Jye%$lH)kCZ{6n-1JKB-0N{CP zg1FPKs~T?HU`emmdVnYAv=5)PAdHjP;Q=Kj2O!;Oq`P1>54Vz>nEpkTg1{L=YbwK-oU3Na@bVOeP;LI zRx;MV%1NBL5UwazL?R+bGu$?3-9*5H>bKo8!N=QQzTc?{ z1%=^B;;D0S!geZ*7$+n_@Qh5d09G_EDFANN<;5iBJq^UI$o!G_x%v68#584e3huHt z=ifPYs4*1)swSCDnJW+&Vw#>Y0G?#{?I6}?=W}=ve1C2v0QAkcanR9^>`KtPZI-J6 zX+-KQ7bKZTMYs0yd!Aq}piYJ?woh*;wnB&e#0DnPl+=}n#5g}*U42F-g?y)dyZZ>p zr;*+Z@}RjA!sZalqJXrKPes_z@U8dF{aADnU;12yxS)KRXfxX2(Lf0$J-U`0?(h9H z&QiPlDj5Fee~Bdg0M0HJ=VvbCwP*kuoJGjh2Ua@ekYZ%}6(H7Y~re%|NOWh0IpNvo53 z@YZA+13#)E5sU)T%QqP9ED8jI`(vJ)c|@+7(7NS%e-nP7v5)qC+2{m%O8KdG9`c)# z_^f2c)bm0LJ1i6-?(#$serXc@7gzdZi@)FWRRU^p`RoGhYWck8SRU{+RnRR%qZL>L zBTXVS+j!vC5wcBBNlV<``mv3cLzAC5>`{Z)MLz>+HVU23C#Xn`Lxq`jF`;FmVKY*u z`Bv_&wRzUlGIixjt#LVac{r*FHyqP1w=qcpyJ#2BEO$UjjtPi4sn0hzwnA(pqoh~yg5_1m4u9!{@4** z{YmbKa5Jjt94;oQcB3fI)jmKvV76d3TMYEs9YAhzv|&!}J!^FTJtPsN!YYsS3dW8K zM4_A+k$k0?;E-X#KJ>8&n_FqjtKXDjc(v3g9Fk$e;^E`d+2!m)hargrak4Q^VE`cc zhTNl^Y-mvkA>kod#@&0tf@z`cm)9=l0@NVYkeBC4)32vBpTS&Iu@_Vmt@Tpbs1;rk zJya4IVn8W?MlzHZifcAn#-UQhV^LYP->WF}(QydZxoF{VG27D`*uAUA)ok|5&Nu1$ zq=5o0e)T#~Otc$v4%NjFdp|vDFtH@-D_QD!PQwQku1gd1IRRtS91%MTx(c_b=f^&#N5Cj z?{+P)J7lgVTF}hzSW#34l5~tAo)x-#R>AeInTTun@t2HqL7Uybh{J5RNCB*|MU#Oy z8v~>0g{9)@r~$qjxfN{b^2+Qosbd+c<3l@-PO*VNWr8W_{6M4{IQ^<{>kF8efEh#6*Ru=IMsvlghMCR8uk5jcN8<&2$+BK7N!UQ%t$8% z1%i*^BacL9ht^Q8JM=&Ux$U_yS;3e2`*M&e^#ch{?XSlzU+>4R7Jp!`80>JVWIqR~ z%=c?9IXpUBNQ3R^HsfBQTE{1B58Oc9AatTO_}oE~;f=l+_L(Z?v5W5un7J zGN0~xpSJfmS8}EB?IH8VILknX=lzxtZ!EQFmV_iVKo@@x!^#VvNpUB`DW&Ng-B*We zPcgK<6>y~A?c*l3ju)IRJeDuPD$hcOyGa;o9sLth22-*Y17X-Y2zeX{sU&w>O8%6$ z$;c*qVUpCr=hDSmH|*B7Dg(CXIt%;2H|(_Xduu~EaWV8z?ydIyWO-s` zI6{{Jx|E(ey5&C-8W~#t)nTa}-=7h|Vb9pIgsyP_`PgX4zrrj(OXZO62#}* zlkbp3%!`U++H0XbLcL*_C@AMx7?ekyZhJKDJH488JU_QT&M*JH_Yu?x-jCgWf%co6 zWB1L?)biFwr|EQWXMg{2);*u`91F4t9-+o>7eF~YP=!C^>f41JjmqPWzPaF+|Je5> z7~5optB^Ip&j?VSW4~K%dQFZ=#7th~bQpTQ#)#P`-C!sAct`(WlkMV`^!p(}hoWPX z=pz~{xtEf>VHQY4@k%w?;f9Vqik&3fp{uN`G;m>5YtRk=l~z|zEh#ENgdx0+(7=nK z#!_SOeLL`%>;2yTTyM>%viA)SzHZsQJBR*FYHC>VUZxk6RLVR33SIM@!qSS&c)gFm z%?oi>3&LzQrYm|4JcZC8(p6G+W_3JNH=~#R^4>jubby7L8NbHU~|s zaKUU(<}A9bIKQaY8Ir>!#lEl+GO3Hs*bTjF%W2gK;G+2iY;P)vdl5tS6i zoaXmZv1U5oe%dOEAw_?k6}Q{es?AN3iI?Jln&IO_h;I0YU&&CdWWN6b1n2pi~hIjwoBuX`EnO=Q~VbI;WlS$ zDoaN5@b$|`H?=}LZkE~K(jo1pe48=EevkFWyuo8>)`2pC+ZTOwr_1u%iV?>pU5PZ5 z4Xju_*IWDMnA?0288nX0A=hngwjGZXKVn-&fo4#f|E<#JBt7Ud8aP=5Jd^3(ASba( zYQfsKr}X@lu>quVWY&Bi$}RhK;cc(vC$Vl+E@h-Bw*voz_y|fhClbAp)`#{FVZRg7 zyai?wzE#Rs6XU-THy4x@t$0MmYN$omkWLD4^&R%czpyBTKDM9L!LI5Kj0yXm&bGOK z>tzx!x1%-W06U(O)InHS*ezONtEZ#bs|}y~Yh-%! z<3#WHoEN?P3Nb34hU%;P*)P%tDmK$j{7x<-+N_im{B3nZp5_O{i zu(+m*(m1lJJY-k4z4v>CO3}o;Uv+308H7CVBab_++8!IP0rf80uS%@AizOI_?oSoV z6?m?eYLg2w2J@E;*QoUj;2ah=2IdROw}ssbH@dN8;6B7v<~_Hec&3WyKUu2~=ePWm z{rjt%dVt~)3`(VlkSjnZ@jpTh^cJCpQ@jJ$EzsbDq>%`Zf&5jIV;UXIrFzjtgTku% z`Zeud2Rh1?>U!;@HuM*4DMH{+my^<~RJ8&>8vlaGBdb4(&c9pxDGuIMLyx6sdr z?S9de(&CrSt`>b=wG1M&#YL=kP;{j)#Na^K9@zd<&$v+eH6;l7Uj)Ma3D+-}Y;-m< zQm+-=XR!Q`D8MEm$@2J^Ed$kxy0iBo&xy$llKcB4|2-om%D1K(Z852z{N9BBY%Kh+ zw&x;|sCE8%9nq=HD1h@Z=jdy#^BK=L#XkCtQawGDjKyC_dz{8jb*VAulK;6z_W_kw z0O_l=-w(Ny!5g|xkh~{>>V3Bkns=XaqzMB+`C-0TAx^Un^|2t&!w?WZ-QQ-O*uo~w zMS?Vpo#Zl+Ol%0VUqw}w*%`MxVd;h&4bX?Yt=9_L;dpKz%vp9I3oJwu(I+w7$uaN`2ZnovrCas@wKzsZ}d+SAe39R+p6sLSL)MOy6 z8(>_5KOp_h2;K2O1N(T7CwwhlK{2Gs7vtSw`6Z=t_1GFr2uvgPH-@7qIe08A%7nTM z_O`Dr##dD0{}+`gV{HYhqpU2AlP?SA9t(^PRBXI^G0}uM(q}R^b2QJL-)@Q!+N|N* zDup#yLa1>K-|~h>xT$4+1^Sev{Z-9TgDINU;LBBV*lfL*L-lJGFdRbaIwV&xEpVRN zeIoK)n0zN#e+D1s=$O$DGZ!LjqFCMWp0qe$23a)?@YYRtS9(I|J2j3~(IB@T9Ilws zvim~bFd_NWCLFFFteFPHM)xzSco2YN^_1e-X8UDdL9z> zhv*j&4M)+EC|2H?^cV)Zf&qg4r75I^;}39q?si03WI>%t;a$(e{&kfe99zm19nO2* z%;epxQhse|KJ`TW@{?50TEo)Y@!cKSZ#Mkp#AFF#`cbZbcum%0hNfeGCG5_*jq`0d z+m;=Y^FuwI6PD$-`x5YsxNdo! z#aMJCbEl2I|1{G}*wCed3~G&TEyOZJs=Qz@j*gX!=s${Wzb-oFoZswzu{G4;uie|4G4YKgSg#l-XxP;BUlrkoyE+4RNL}mSuf(ZUmUj&^6ZX537D2BTwdaOHiqs*0O z4_|^bk$b)yL5AkYle6~>c1+8nR4tuIGgxPLI|B>$9o&n-;cSaTO_a#Wy(ZY z;C?68OB+_XNPk}a;xPi^>v3*9M`m5V zKM6dpE`$_;DS$i;iXyjdAwPm4dg2P-WmM%#$YeE+)u=haue|@KoH#78 z7>7cUZaw+pegQMr1`$7~erK2Fa2PL7y@1!LWi`4jH5Bm=_diVbd2WWR*o8*nELcB* zEBvc)9F0c5ZK3ythIOe&`6?utzyv2(HySqEH-pGMwBs35+b;#PEpajDg0s=S@HS!e{Z81*Fmjy6K-_cxV1JWSfxM41 z>UHz3)w`1z$^XVQE0LiVVqn*X9*xTfuXof1Q;LT{1JS1Z3UM-?Xm`kzodDOQMT8g7?;Jt*g8RVb(ZT6!HHgdxiz?-4=Xr+JGZDpcXfhGT!Mn& zV-_|x6}nYH)z`j4aD6ntok-<3Lbefps@ zgM*UF@suH>5uXfd$+i4c8&Gh0ThA1$k=*gUHG(v^+HMP{;Fw8Pt}>pe50LYPWK|k@ z5gZfibLwe_hNj{E7Se(+!k)v7yJFl8fAlz&-pOLZ;0Q`#a_ehzq1>qnRFFnGEiEpc zM1i*~Mlp9aa`PJe#Q$cKNW^=yxWBi|FQZD`Q6^K6qh2OMNfxIN|LL0i!;7t}6~}?P zJ2E;upE(H%c>$fnbwFP4(;o>9L{vw%q>2$)F`YO z<|&Zy>BbW-^5(2`|Ldoit2?Cp>sgs-jVw~^QJjd~;Yg?1kNQ#4v9+~%mE}D0oicEB zj;%+O@M?nEwzDI8+UE?Tvu$c6if-{_VPWC!j^hKBgpPBDPk5dm4a)JU_rc=Uqmy{a zrhYa)H!XxrY1iBC)tLKN(fJ+TzeT;T%Tc6o+h;SO!D{@KTY=Bw*ft2T2a9Dw3?k!g z>CK2Hn7W@=-jf?YSy7F|*UA}6WR%dEm3FaI+c8aJlq_gU*J*qs;tga!BI>%gcNNC) z+3X>Wiw8FF0$O`V+3azOiT{LXPl_z*a#WY=veRvGcC#&GhYICJ2@G#ZUzi=G z_vQNJC*;g*`_Ex!Fy;5G#eh188uHh#$Z2J%w$>}<#aeg}x>ju6pzy_p;RsN%n2Aog z%Q(JqnGGvg%u1_{%9_1%ZBi{))S`34asqk!p~0vuNY4eA`*15fQjS{TmKwvwIBG}J zoJE7&vbR(i?Cop`7%+dQS_ecw_ngS_Fj64}v$OiYK=e>pj(UUD+5j*uo>g=!nc>VQ z>ThjI8BwsEiQU_OBEi&C4gMV#vtA>gcc;Bg9>5ipXrLXALx0hjGThw-JM52E+NLl` zM@3Utq`z*=G!uZW2jh?oXv;lik8b15NgkoI?|OdADjIENU}YPU<|o%r^wp>bQg2e$ zD<=NJ9fhx-1LG8bP)cl<^U6u>%J{uX4kB=oyKFy=Envzn-c9TQ8pyUHpXtvwyJ#0u z##;3L*U{tx*R$=AutF}AIa;htJK5`|Nmib3`h7l_*8Q&E$td%xFaee&8~u-$7*8no z#DBVL|3hz*s#5EO)B!)n3oQgdNZ;)%s*`k!5mpx*)lb54H~XUp{IPfxU({jj@O5py zV{M&ZcAsmw*9vI{A)i=RuM~b5E!$3ir76?r71Aj?Gw@a}07foRS%UwkC=0T_5)+uK ztV*`$Hu`tP1FVV;n{OlY6b7=ww`}1v#-auVcN(G(XoSy~0KfnXaL-4)gfqwmRs{(^ zBKUhaG>0uFw1Fv~pyg61UhkijhUV^@rEBu=pgKO@Kv2d=t(5x$OY&1LQ+;$o9@mJv z^h7e@^{Ad&agDqt&(SgX=9_cVm8!>b1;J&%~*WntV5o{YPV3D?A9%kym63kx89de3hzDc-D zKPQ{i#nYZuucWL?wTD*p3Li>R?M9-U=>%A4%wv!KMH8BIUdC~`w}w0)398k}>#_?S zrlHph-Lbk^SveXws^yRx=_Vit5>jg>_&CSg?S$Z&^^h~iCi=T2|1cnvON)=g8AU+S zqK--ad?n9n*YrENfOXXM6#GAx&iOH}@B8{OCvH4J8{5gmYHT-XY};mI+qTo#M&rh| z(b#$B{rNtB!2B@xoO{pS>#X(KR@bA$$`5HBux8*MD?;kIEVzcker0UYn6E&ZB|winYkJV=zK(occa<0uKSKGHia=Zh zq3Y?M4&c)(w!Ep2T|oPm9E<7CFq`Sl^JJw=J(#IJ{+!p(kzo}AF2giopoQ~xew`Q` zIs)OB_YAwQhmq}wBS#9q3d1pYj^b{m<3;eKGU)D(&YS6no^Ij}`wlEm4zWlJj>3~s zlqCuz*#53^u{ogN=ZA)d&a?6C=;+W{f^@27jT$t!urITRm=j(B@G-58b%5`qw3O^o zc$~N6n28q|v|MA@Fh=5+($x3<-NFBZu$e8V$Z1Mm760tc8?DBBz-AQ{{6Zy=o=yg}<{h>v49 z!_vNF%fCLD+pPG`Ug8DUpnbfEOe{z*>x%1*7bfq^Tauo=?hi*?%7VLht?K-5I}TMO zC02oA6xL9EL2WIC2zRat+p<5(Wl{bG3a&2KEKPYt4&Bh(Qc?`Sv-k`nbAugXKZpizXL z{E$c08auvdJyptDQM6y1Vi_+OeeBZO=Bh2Cf|~j=g*%9n=Cf?z=mAN+L;&&~s3XGu zfX!gKK2t(3wqTLMsf5@k2J(pkq%$krFspoVi@Acx4bN?`3!SnW9YnCc+0Zbw{;7V~ zMGCwz)Mm+@mLtl+^F6a)ACgK9{}^)O2+d2YJQ+KQG22~x1)C{wduH^GrQgcbD>W*9 zS4e+fL5k1_CPDARY`K#|;(`u33fTQziOEO5lufFjh4WoB+Gfuc(Ci|=!+X-6r$f)mcUr<==Ux@<-v4>H21%{p?zL{jJ3C=wBZEKNV(4lRK^-|`w zl_K9@xF+RCbTw!Csd}txma1YDgQL*fY1ua4oPOT7yqP34Y@jSwz1fHu4gNL3ZLbQak7l_!K75 zi5YijUD({*tgrHVEL^klWxL!5*^FxTpq=X~zDP5C&cB4}&!+m`;%e-}y=R2c04f%w ziybpsg?;8RIYD*=Q)!2<0-dpB=MHQD$Rp@lQl|zV=sfG~Z~hHRYb`C)6HL1!>c#77M|{ zM;>0=zb~gBy>n9$@ECO?iINbJZ$r#(W);QLd@r0_5!DrHF`yZUl5=~T!M_bJlAEF( ztcOpYu~n7p1uuO<`7fgP^G5=`LDlFJoU~t1+(IxPGG@K(iTrw#>Ab!f$v{nVi9xpwo*kQjr)8EZqlBmD zdcIgD4$8;yZhjaJO3mfz=@gI?H;$t;Zaf}KTmVmsx!BS`pIcvviZ|>hguQ_cRqk|) zrYkBtPLlE0-t-QNHPhxi+6JmryCA#opNh`$+$e|GU?10Q_E7Yys%M{rF{_Q4b0&HV ztF81iUNP8##{4mg6v4(9g@1@T;SK4lo2&wMT2E1s;_0oj*n{)8SRxwAcUU>9b!itY86tbQ-N5Z$#I`t<2*QYq^_nAa zhO4ySTgy1MDAO+J)k)q?DcaQcfBS0m53?CiYg&`t)@mrrz`ovVx|;~z^;O*X3UIaT z?BrIC{v6ikuKf!-N=`*~O+hF1?jgZs0*68SWvuUm>354A1CFQ78V7(ZveDw=($K$H zLN0(!Az)I5W?7kXdm6eHl5&=rew^93^!L5B|BCE-=Y>Cl(+{b@*1Vpyedy+6d9Kz zcD&r}-7@9}M*$=avGIrWN+5`Kqz*GIYuW2==0nt22ID8FRpi~44CA${@T?=HTD!fX zS7(OJ(zhuigM>jbvCtsxF$}srB_lL`q763h2Sl_}O?LpvtV`szRX=P%B-^x~M6~JR zf6XK>!e1`f@z$#a1%mCi5S8wuUN7*=S0S%9fpXLwEi=(Zv$fUt>=m_urvMCdcAYzz zxG<67LVNJ5Dtu3TUgw;k*S|YB@Vw}2GL|ybM-w@SLWD+}-k2<;L>E64>wVWd#a0~f zTmT}2KB4us7$2lGQGr%KID;90_jz1~$^`;%Sgp!Gu@rRo{Jih!!yaZtJImXF+OAX1 zj!D}^r7WTIIVpB8qW%-sn%vL;zXWzm)|g0(x$JSwERYEbc16e$vSZjk2S!u}U#LxH z&SGEORCHj5v(k1P(n0_6?Cd){D*MKd8s{0O0qRif9(6Zg#f=72BRem*A1J43`fC&7 zK0)qn$I%1SY_ibCauV9w+FsiE_8*&S=GJ&A$f*d)dYF0=UD5yNL@{;kZT*tmPA25T zcGSm(|B6cD?zL1C9#r^#aX_eEQq#tT@X-HNNTsqqUA2Z&;;Qg`5}oAZbL zm|?$Ar%JjJ*XK4TN)IdnA zk5b<-Pk{AQIsbg_P=i460Ax&9;!bcO0nb2)^J1Em6cD21Yx$=wlZm(O8+}RiyP|$l z?`ksX69n1*5z}hTa?yngQrI+1t^y(7jB8inC ztw?2X><}Z&POSs;ix}$zhMul7fZsoG2OwcYqX)H0#V!&6A4mxioknT7T6w2+U?y6M zVoo3}%+sqRjEK9tJ~*R6Qnz9+CH!TVy(V}tUawZZw>ECdoz$6A8Q{zG1kY$+`6d5* z1Ub>Ke!@a?tSpv2DtT^4R%#S(LDRI_%*Dzy8u-H4?8Ww51LR5pO|O&ar7qnB#zraX zXBoA}^23s7!U@xyX;2<~QsWs9I7iaGnUkO27x2-Yb6KN|=zNP$HZTqGH-{YLL5pQS zp4WfWWTsM>Zug(ogHm?tX|RmfW$8j)d>=m?>4hfH;pSEBgiUfRnZlSr$kia1iIh$B zsQi5E;O&+GK$kV+o7jcZ&(l!_+C~{*85A^Zm(3{Lx%kUJ>#w(}^7CDjNaG|s;S`G^ zAg_`D)3GanKG8FFf#m&yvI&(Z)z9eHk~_w`coItZC9nx1G;H)ep<(bX_%8$W@G+1z zX-j1l4!UezXLU~KQ;>cYx1sBSgZ0K*aTaa~^zsE@7gWHoQ5BqD5ocTyT$CCV>S7q%w&y&*+xP#sn7AyrL21y{RBM@G7-_m z#>U3GPghV7w2x2MMcS{q16<^|u-|a)n6R6v|6Byx(!`y@|9d{LtVVX_!b9oBcGYR3 zm=nIXtnP-7UL9K=6a>rEwi`+7O`26&95b^YLYTfh5w>!Px}c`T!$y=*?wUYiq3pZ^ z5PnYJso3O*M+3|Pz&h@`Qb}-917e+wj97m^UDEe_wAyr7WsR$h$V{9S;lSjfOVSnu zLAJNWYmBH0On8kmkQ#f->5`GX4>P?Kckf?)e!s)8fQQXLKvTYf1p_zo2o!xY=(5H}}p!~<`tnTQMS=tgQ^i@5cT^pL9 zUi2Z^um2iFA&RaE;Yxx{zwMSZQA2Z{j%PvCF}h@ntz3Dot#RV+C9NLM`m^;b4qu80 z&WbDwC&|Sd@trxxP4BYs$?pK`MDkV^9$DWiY%FhMk$;a6)bhPPo}_W$9%GrXN0!aWZ)yU zU&a@ECg!0NYy{3=6@%X$u}C;v27===*!GTg9+{y8ljhLNmXB@2A{uEMXF^@cX$y7| z;p5TzcQC1L@&M{^#DT@j`k0I0-XabJZe9Y7t!ee%mP+0MMtjw){X+BZ(R!$z3c4U- z!)9R#@v{pFLSXa&QK>$+2ctdDIlJ81@9>!s#r#FiMwAG`&X$|&uImf?{DC~pY~n6! zUKHN3R370dc;7NE_*BcqhtGLz3`=FOq>im7yU+8A}Xj}ej2d}>`eW6rq< z7^$btf1*AA&isx>ndzI{`-Ib3AYfY&>iUXvZAb|djt5H z%+q{WP5`r00hAMV^%f(O6FPlY%e6^vikV2cw^2GFEs=}?vgSWN8z=!5?Auz$o zyRI8-!Ct7^Seao4#Pn79>$fur^Y{7&Cyd&Y>^v6D)iqcPQR?V3{|V3-ne`yGtr3!@ z^-(d5GTGbEDo%xv1h$S%NUdfLP6(aFS&KL>&Y@JCjTc&H+#1Mw)5oYJplc#Pef&9N zLWzxzXxCY+H=iH>J)b!55XHs(Vht#)uI_Xky5XqQVEEbI+StgJI&ouF`8{3(pet_B zJB{;_N_ztCwDJDyc_1kQ2~&c;G8xQ3+@@krGbX*1+(%sa;)Wg0$tu{RbNSvn1$>U( z(MAwLRJC3l_7RI#g8G`;kVUqPsinf6cV~W>whz`ZON*nV9qANP3ttt2)L_TBS$r0I1Rxo#hAq8Dzxne8!}(POAV@+Sm46f z8TU>AP>vZUKec9$0`pmnCS~XPl-SfY@<*t^CTMHcUlr4Kg7(H&h-^5bK0%_{@5z?f zm-vdzAtDB2Gcys%6RAvkt6N)@q2AMh(}&L6s}+?Q;(ZiR1xw~NZvW{qsQSIK6R;EP zW-sCd!?tVhF(!fzwEwg+?t=TeCWrM@c1>$SrL$A%8DY*Te&{jx>GNsP;o#|q?MT3P z%{u~&!(+LBnEyp5)wjO8`~tpBWo|P-lC?7r?1l`1Swde7+#cmKuouHer3viXkwupN zZs3N8fPua1G!z35q8t`Z?$=h70VAW5g^K^=<5Fp*l8f5E8qBbaUp}dpVjHP_-NYK^ zb@03^Zppan;-FNntnFzz{}M>b4wzkBY<3=-K>=@Ko%+rn)Ce3*?^Qv%EC#)3MTVb8 z<1H1lf4FKYq-MO0A(6wL-@O;OUBtil(|@J8&stw%cr~*G$iN{7t#utT6uK5}koC zRJG_ptS>vhyUf>Tx`mkTE}i+?@)`e0P}Dv2yj#wsZ2rYwk;1)A4vcuGlLKPIY75ghSwfc&nw`1N`nEN(W;sGkg0~w zW&hc`+9tCCFePUDUO0i0h|?@>22VNPOudRHp`8eGC!O4YWOHATK%IY;#q8Rd^qu}v zQzUG)gVVOv;Vgv#tO940giG5oVp#U0KjE|F>%mwe@LowJf6pLAyw_c5z zkeSnTCAP2siJ848|GP9<#3K9$RlzYFcaR0D8PUQQQ~l%_@5*5ZtD(T7qOIcOO>_Zq zCG;nh9?jc~1=GU0Duw4sq+ftmbBKt12&(HqSbjRqqKB-X3UA}*E)P8crZkX+*Kk{} z)`bs`8TVUJ{gajm*y{sDKcKROW$B241Ral?ZnmxYf9F-2ZIXyqwx)@|@e9ku=u>07 zT@$-xOLh{M|2^$(2#0wvVbKI=vrd2TJwUw9qI;)R4|kYRnxz``S0?+(eU}~}sAIl~ zckP_Ea6ejK#Ggjvrz20v&VVpWz#}wco|nB;-hR_>jj`SS+R(2vVC@wko?fke2Lz-y zQ~XoRKrOKdBbYZsKgGbojyB#C_c*$kt=7&saO5oxVrA%a`2Ar!)vKa*8&>H0*Bl4H z(~}DpwK4-Bah{cdA(NgI*I-Rh0}2JjsAJD}&9!HN_A4M`G{DcU@PXH2)prsYXIWu? zaC?LyPg8L}=>lN{q?)C5@&9edN$cCVsKt_6HU`pTyPyJJ*bj%XMWYT`%q^6?yKZmg zmSk5LqbjLb>hGgaPjIWa5KMN8J}Ow4hN+6Yq8ky|2Vc{pKwI3)atm7f3@>(Lhj6i< z`SHrF)f{X@LZ>D6T0Kox;BYM=V`hsT_bU2CI$d&%NhUyUz3SM!=y^u#N!ioBo_k@< z@VH(QmfZKZNyV8Ftxe%h@DDk*1e{RU&V^gCF9HAiFb56xDrd1NN7MBiQ&nT9h8H!R z?E05eDG)M?^=~tR9m3=Rlvf;th)_8F4NlL79S8frf4Am9ASFJqRS&HoxM1xqH^La>4FSiDDr6O#v zm*H$8M!Jr2D;EdqcR%_YobA*%b{jIEd;6@&k?|b#Ux5gHF2PBg=Cmh$hhm~O;630< ze6ahj@()R>0i0w(#iWvRNV%~>h-t^}QwNS^@*P7>gARrQbyTp1y`lKAK8k}n^U9m1Q!$Uhz$ zZ4`*9Fq=oOl6!zrq0^U0C)Q2svz+;sD${&$gvRtiaUKpbAjo%>`RYGQW>7EqD2yQ#P*g|x(+{JSJT2bbf2H9Xwx`~mdgHCCU$cX(v*V>5%~Z1dn|#$ z{tws9Cdcb;HBVt`6xlP62@ly{K6&vC{U9w2xW~{w8)cq4DRp-SrCY>cU$W~n4Zhc= z!&M;~Ff2KdPK$G0bqOhl{5{~ap1JjBart-ZO8mpKly{YTgg+U$REc{5TQhFpwfpZ1 z@S)Fvzyc~|(Di0Uy1NWHOgT65F?&51-*9QnnhTV}c}D_x=bhhQmF>63!5i#ty#m+r zC%slhJk?wGQj259tzz@eOohlUIN|-(0iWod72JQX@eREHvgXP|T~#fOm3(Wu@e*l6~owAaJCzA;Ajy z7a<6DjmBRL<|On~&dCR=he&?E+*4_XD%;`nBnus`#dDIW6hvEB+|&v(JnDv{4XZz? z+HVL@+0)qv-<3BLn_K9tu`QU_2!I`trX+x#=z-q<6cz@JG~5jG^jo8n_ojol>!KsL z4?YqDh{IZ{f4f!t8Ad;v{}X!*8TD{*bQ3(-pUlYzq4~sXPAh44kL6*X| z$B_?AZQiK?O}B@hR51?TphAG3imOc*0lVCU zQtPCZH%++0p=$vmZW!>9N$yO{5mxFGZvcxtDKKZ?-}V0onq-ku$V*^9O@d+sigu_G zqh-%vCwyh`ILbvNiGZ-WKjTFr;O(0b8i9k?Wx{E}7)KQ+whoi{Xs$u}_la#9D9 zr`Jl=rptfrjTd?t%G-;CDrRaVvr*2it$?^@J3$^GjGmKWq@)R;f zjq$^!EaL*)$2#n;Eh2##DgS+bE_k<1fL1Mrn&<7MbLQYFwYMq0c;j_bOoY z^FI~01??NKy`q(N(nB+uoDBNIpLEFpd_;rSvk(gv@Vgy2V!}Lva5!Q+a@~(()a$Ml zD7{a07J?W1-NN{MWT~!u_$4;n+)tI%*O)}!U@+9R-y51=$Gv)CI-w8+_+4daN-sfC zV`$250|92{9t*%^dl|+v zr&kI6ApBAD9!qDEnZ(HTz^X;|MGd!@_=u{AzSyEADNn;RN|tTokb}0uNqVdO|CmRO zkcBaAx^*asp9Q&u0%nzrSP`3!^Ukg4twuckL-R4OM>W;3X9A`_HgLo?b@Ev^Py<<#sg&|`_~mL66aJI6zcNNPiorR~FxE`7>cO}0)aS|Ru)ZML^TY9`zu3@A zgH6CJvvCNcAjHT%$>TOJfe3$3Gus+K3urwwPwz-L4ha@Ev7{@Cvklbu10~XYd>O>f zV!WC|*@b&=+mB_rQj@Vue5sT5r{}jwp{BmMPvbVks}Jp8TwRt%nHm_JjV34kzcy5M ztF~P$KtiJIoQ#70KL-=diH$%&9Q9~~q6sD;fc+vc(0bk}fQleTMFJeZU~GN17blqfEqs<40;}qW zhf-*alxEWl5dhr`lo*?1PbTHcEAYFxU+VsRC*gZsNA|_z_E>6?MNL4sM~9V46#89W z)qU~BF@$p+o1Ky3Z6m}P;_xkU1jPu39OG*w0zT<}nDTJIqg3s)M&6`nfY$42-eB}k zYL`Ba0Jd-uLG#5!;Y?jNjow-S7u(x$*(zeRh@G$V0dsna@!aH7F!O_nSdw@anhL@9 zo$B!rr;jjL;%S}wp9o|jX6!ddqNSPQPSts2BM&W`mI8Blq{>ymW_2|_lr$R-_YOEq zXaaAe=<-xOpM!t7Z`QAbcEw%dUBHDl+=;=j>bBBpMnyf1M=2e)AAigQ+lp-b4Qu5_ zTOk}0DME!U5~0$XK-Za4nB@ZHYn`~ZdAr7HJmB)-IIaJkzr`f4X|qc|K~$)nTjj||Tad_knXPoZ`jA_|;u=cKlzNAo)nTHo9DPc#Z>nSgMv-jZ ze|)5Faw1lt$3X|pTm*h%=ehX<%V2ZE_!i>lkbjs~u5 ziyFQcO%54|(^-PlkP5=;5osnY<|vBSRuuz$HL1)xVBK+`Yl)v++{d-gz^>x(MJ^Ie zdAJqHva2lb6=v<(hWslr12zCZI@f(&o7aBtQqMo!t*z(3H8t_4UCo_6a<+fshd56f zC2Pgt=-ru8R}6475h~#yJN3AE!m%EbrDN*ypyU!Hy8_jINzn=)=UFQ!zWQes;4vY> zGh6(q<+)r6Syr$Rl2jYF{7+%1MRw?6e#y5SE;Nxn39mHMQcNoUW$~ojDt(P%O}HG& zJTo7}M5;_tRZc*T7XnhW%>i8${gH}l4LjN+r6%M^p)IMJ`avP*HQ$uDJ-ElP?ckIJ zg=_l7)3*^x!P6?_KlJDeSdEQHfaEs{dKRaOl&u#Okjvk_&EVLo90K*|11V>{3MD>n z#z?$xwPT~Us1lf55;G$PO+YBBP?6RQ{u4?ERgQ(2{MQ>qN(64M&UbDPcu{5n1Ern9 zta3u!!ub}fw%sUXu~OsFEex+p6Ce1+=|{PxQhM8h=r4LjRmcRBX%-8P%&M9kCCM)7 z+R)I-aNVc`oy{u#bl8;!P3}_Lxp{~qTdVSo%)K3;m~Gf120j7m-z>cctChh2KmozG zd*D3nVlb5ZuU3#q5f~-JdJ$TR$QdLWDly7z451->AywO;3zniSi#pjzbC(U_)o5m{b{%Sfs*us zhOtw&zj%3ed0^5ILN<`B^5>ip(bFy0B&Bw}iCU?edM0h22rL#Pwp9l0fxl?IeN)>I z{VSpYp9l@AD=gS|59`Km*@HC#3u1JBP=rH*|Bm;DUq~;v$L*3U6m7FolS#+hhUsmx zxDOj1Bre}!gF|Wm*w0@oPPk%=afw8oF`sEatO!mu>M{-5GR7#a@{lt=U_iBd7du{) zE+19tl;&@BLOB#>W%NVbqb*1_3+1c7Wt?GD+X*NORZf6&4f)Wop?G2As4x3VXKt$xlRXHBxIjkWc%>gj{b>qIQ7&Xb`jpU%+DKS`_rLg!s1AjCp*-h zIGVTMD2f5Owr9&NwH}iUDqvV}7Z+O?t&-uNr>-x;kz}kDqHuA9qvYoewWi`2%!LlVfm1z-JR`VIYn0 z$39KPh*r)Vp|3KVuKgLaY8=PBOsE*D0G<|Win$F{hk_5v+t~DC<*&IZ5%{6-2t@-H z(Em;?za(KA0lJ36JSxHnu>_w__F{Wpb#8rCKI|iwJsgb)HHSy{$?K872k)Q2c|^ud zw1?>kS%u3Rzw}0RdV!_ zy0h<5fLM$R)1rk_%@N_$)LPI;Py-?YK3EbwuwtRiV0-zexm-gcmPYwfI;0xNRaCR= zVVjg?R9p@&hJ?mDwYHzRkU5RSRF;j&{|JEy4~~afh^}{%TXcxoOb9DbCOiNXrB?4m zOIOT2yo3aH$*UQDAuG(!XHFc3$ihV+pwbvL>vP_Q#OMcq5p$}ktqa%|nAuuT{58L( z`J3@c)t%v!P@#*uqK+74pmJTK?O3#9#>R`YNtpZG&O-iaKE>?k&gr!d>ITm-3Kq4x zPw#Xx-v19bG2wtNh4BQRSzbM)bYM9Nohf~hgvD2=&3zTYVb{I(Y6BORtJFfGdBsBC zO(;vB3d0&zWU$G)j$JXJ;suxJFiC_Vw((T|2Xl!DTaw=|Bb3U5AOj|IBxbV4YMiRT zdGv7Z)+OIgR8R7BE_jLnj|1p^4OGnZ_cCmU6k6i*RviKrgULZ1nW z?J!tHBq`)#o^`c>8=|9zab&n0c*pZfsP+qi!CKf00P#`sc!M8|F$j&qqs9Te<6p|T zDT@BEvTDn3HaJM~E%uCi<*My2gYWmj=GXc)c{;+$75^@Ycoa;kj#^cLB4j~14fw1K z=@j8U2e- z9ynv?xllhA@ALZD*?e1Vrt9^uJT=GXaN$UI_1`$1T~G6Ems<>wmz|#Uo($@B#J$Pm7zxfj1mD;HSz~RbrWo{BM_ysmH_n zQL_9SGGcgyagf-!qF_Hk99Hmo&Nmlv&!l6>3}SA1N&UF{3MdX5e&R#avHZL}Fp9CM z3JtEDwut#*b?TAmF+Oo8PGa6!15dj4gD|CQ)nP&rF>q9|ataM7m?iVYGd&d+K3DXs zr@M$EEr|0^9|XaV?JfhJk`qPo9R+=?y9@nu)G$jN&M6&^I%;8P{fjC(y-8T1TyfwS zIR@qCTHddtvG4G#3`Jvb^P8i~sWd-DMclh9WkBzIpK0U=COb1+P-xeKW+GU z>3Q!K;}Uxre1?l|$h@xJz?z%&=I#X{M#FGG@~ZRu66J7k={Y)zeWiawx|o{Pacb&r z>lW6|p=;;PN>TpJ>X07(&-Xq0f|qKOkU`a0Tckw!W)f>3EjFG+ee^YJT|a(@pqxe7 zUi-zgKv>>Cp+V~f?sRNG_@7Th#Qlcr8iUyh;Z*F}r5n+aR}x19CXJJlyG-K;FDp^g z&$|wxuE@y|kiW|cC$7lkIfND!;Q@>b-y8e`9PNtioWYt>v{D!>BNWg0-l&yoW;CrN zzZ$aHf!4gaX@sgHfh}{?OoaCgQpttBXhCw%HUY#b463L!BZc{|Z+p||H(tTsnQ=&a z65;HL#*!t~U!$*+xSy37W9Lh^8&ket)3X!KSBP@*ek^KQ3w9rYi4aG6@3(fHTihFO zzaQ@CHg4FmZ!Q};i>d9H;=LwrrX1_iV$TKt-Eieb>#S^U%%%_61#D1%{WVS0gr64> zu!6%JUIvz|M1In3q|E5>f}do}j?S_x@#&WXRN=MSRav$QxlK>2Bi@0lXgrmM=r|wF zl`N_jY$+15J(WS41nKPWZz3o)Ax9u!o+7`u`K2cxfi zSddzFJGn98S@3B!=vCuD-%a2ap_-Lki`6uCw~F!P(#x|XO}3Q2i66+RcT9S7FUNGc z!bv&(40_B$@`Bfdgj<`;XNTXLWJU#OG&g5@ZO7MJaeUqz9`bfIH!teyf zBqwwMFnvc8 zCn$%TDBGClSs*yX$?9dOWOPk)2VJmse}LeZLTUAmMd;us5VI+-^f*RC9Iv;(dh{=!9d^@3@h6%3jm|Xc_(3Z!puU9=rV3W%p{^1w5{j8|f?bh~s5R`@y&*r)Iq%=a3k421 ztjuUKqfSiki#P0iug^v>#hK7JyD@nfP^uTZ)H!iq8e+w4)@W;467Y z9tC&?Q<*3t3m!kl474sylg3t^R+{FXtfRxSLl0$Cc2W*fhXd57QNEuZCYlKazWX0x ztO~&y9ubsV+v*wfLpo9hs9N1@0t;0t;e%}_eXTUxOoLFUnPc-Fvjz8oj}33_?!OjV zAThr$o}>h)3;#ftV$~F5Lg-)vjGt}^<5vn1-|)E4?77U4x>ockgAe{V++_i75{Ve# zd!z($d5z4x8Rh=gswnZMe0LpmYEM-R}9u<|3N7db6%aA zx1n6$%EdA>+iIuY8H!q^a{1Ur+C4?#fCdNf{Eoqih1Ktc>0ZunllNf>T#6?Lc^Sy6 z(=R5$P_3c-7fUhnfY@{V6utfZu)=+`n0O5+R(44NHPRqX2N6f_thY6z{b_N;>BLNF zkUG$kDzV-!8kLA{z2)Lzdi^7A2t~RK{gvTJqWSe_Ny%uy`$QAESZ3yZPd0gEy@Ll1 zEtvoCCBswc_^g|J@?Io^yn+`bnfT=k8Ug~xg4URWOv=Fxy-7@jsKtBVAAbn~{sz?0 z`MyS!SNPw?czGYNqvhf@bB_c^Qr{Uj$nh})nIE*1d~@O$MK-DS{bc4-6TcTp=~*>8 z;aSKEfEysc=Shh-J*FZrB1b>2=cULorpH}JryS>^eMONRt}#DNY2QW?WWg2r6eR3r z(elZHh^zPOr}j0wWBT7KyHPu^rG==?$*S`%GNjAfyZ)z88_70#;6%LEmQI*Hozm|~ zFt;kevfw9cmSa5Id&%cR;@aLq$@&jcZ5d;kcx$?Zuk!TbNLhDl#?%s=xMLR-4a1Z+ zK&zJ2%0)M-tK*HkX9Yh?&82VXTv4&ew+_Q3atV9gOhNwcIX`Qwvvb~*3%hv$9zZI^ zV&Me<$3{6NqxT>+IF3iFM=Or4BmEX9?iAfis4?Vcz(esw3P2`D?R1P`8$vR`r>(=y zQCP;iyr72@LjcGQqp1G1Nx6Yg=WfF^Czx;*Chj9K6xSb~B}0Zn;#4N9S3CF4ItiJF zL>v_BxTrGqraMLz(Iwk|MD&Pi@VTCpnxj$xv(blMM^FV{hbL-*%kdvN0YD66QDQcI zm-N=wsNk;;awMFiwaH_K$jECjEDag(Y-tmovU)WPKiQkA?8=hp%I1(Ee#5Z`$hIQX z8GBST%rBWAeyO&rVN(@D8mplQAdNqA^ zPJ0KdkHq!_bCl2!gywvrLslx@V=X(uFGBP8Raat5@3O&Z+Z;>wTTGLDZ6oX**Wp;H ztf4hlAXjj>5A?wg4hF8wIxL(S#wWO;IE=o=uf--u+1`jU;0ooh9Bl}8llIJH{4h(2 zAOyC{#}U*=u)~akjIcBM4eeLG;yd18S!PbTa)n>XgONKj@<@qj%N=f8$aY=Lu|S2Z z-(!RV+&hU%;1-J5jGz(32=`N97oU64?TXSL8 z&x;$V?V$wFhd)wsd=@L*5n{*+>|gUkFtE9XDvxu(qiqAKb0Dpc&dD85HEDck6Z`$@ zeLs8r+8JT8PMC0LvdslmJvNE>F1iPgWZ4!BCidN#%Cws-RWH=M?{W(~uFUx~?INae z5Iy~ks>r!8e$j0QX8IAgw-tdLHK)WzZXX)YLu<;Y)(!j<8}*9dV5+Go7U1U@dmAQzsz{jE z)c+wK7rKifug(Kzz5{(ZFggOoqHm(PtWPgbEidjwB+qqZ zuoO9gRIbeVoI)EVKbte!zJpJUaC*C1i=(_00Dl#UHXS2wW@gt=&Bt2Gv;UOM+i}%^|!QqOyVEQ-y%Axk?MS))Jfn?IXcCM9xW|7oAg5;1=%t4IQ5~lU=6;! zkVY4jA#em6bc_Q}wVAla^pti7qe~ibTc_Wovd=TV5&bN}azSMeFsESI{Feg1(PF)_xWSL*6GWco z^M$G#9WI79C@~~qktf;|b>`);9r6@b;y^R(h1Gnqe^jtV@Pl(c!SXLRop}VDm%{}g=VQuT@-A{i4mH}=?`lTK5uLMl1d;Qf~0(R z9)@+~Gz)B;Z}ovUCVT^$Y7mhI+vIPg3EOIz$W+@&+yzLQFsh^Q zg(h2mpEKI8u0+z}2aB$bW&zet%=sjI1?sZH^!+d^#|hIo_Ov|12r`n=EI_ktQc5u& zHXM8=cJ=y?%ogj5Q>Xq>5}!I36Q)r8IQrab)I`~ux>&gUWV zvr93=)g;^r#Qf4RL~OCZ6CQ8#gMUWe?(UZE?(Ev)5+lPSBUDtSw8_%*LE}WCto57% z;g)kRiYrRy35Mh)@?nL~#}H7ILy`tM%;cIbV)==ONftfd2^DA>9WH-3@Ai|J?ZU;2 zCjeePM%3EN=_$pPPyf3czb#|lRHI;6fAB7^{vIl7NNAic)}AbgT_hXUn}i;fC=gl2 zsisB0Ds8M2W~A;1sJ#!4{chuPQQ~ExK&OKO#K})UaUA~lJ&R9OxOxE`=qLcYZJ>%v zE?5nO4)8+r-~`yKhYsqCx;~q$xon7aL`jGWsYK2T#!rFnC=@=f?M{Dmn~kLi$6{k+ zVxx!>ogFZ|=hp(HT$f*vr*Dij{M6w0@R5FIrl3ZGwC(*y~=$AEC|Lc2K9Qrc{&R z8MJ{vP@&|-6s*A0G5u{Il9#bEAT=-P7A_VlkcylW+(VY$oxR}j{k8S~1@}iE?F>N{4D#PNvv~!Dsuu$=R{p?O6gAc=mgjw`d0jx<_4U0*I z;N95y45%vT8W91NRG94gmHI>{eO@xzbKHll&u@-kz5rfMLn#3sD$mlKhje4|o zZ9vivrtWBridmFn0?xI{o--);O6YChED zz>9t9sK~|)esGMsaL=v=I*$<@cp3og9BaUCQU62hF%VK=_jwl|?-nzBMl^?#OcpXs z=;d6{Dp5lVKuPkfm|ps@z=c{O8%uB`mE15Nyhb9jgr&xx&_eYYd8Bm$ma-)>$%wo-A3Tg0E?|()( zN(2*zvDj&X~R-I1>eVm#(-?kJsuR_s3EhTY=`Sf;L`)z zx&~JF*X40aq7h>rWij`^ajx9k#SD=8dY&<@sh_>Ig@?YrcjQ4f$f9o3B zN8Z3QU!PJO*_Ug`kMypIeN!g!D3eXW2c7pG+&xD;zn?_U7W8~@`5BdU#a2G!%(0^c z_M$^(Uazv}6A#_#Jk=?-YGr z)cAydUR7k$zWoYke1^t^JL%td@U*4I=tZtuqB6BSAES;Tb>g}B?e(Yt1O*B|405Zf;;) zKu{~#Vo#eo>*S;keMz6xO{1lbN^54GJ5`=AZ(hUHph-j?4{G)nzW_3tFv{_A3zp2` ziv|e?&KSIbk|vrGi-?*H9vLsKqSUD#qGjb|Ck_~65_xdZ$!YSbL>@+{7F9ioyDz%E zYtO|^%0^0ceiL_VL1`C57-+5*`MR|-8z7JwAfU+k{_X>g*O0o&I*IQ|Hp0{@9+*V8 zfu|TW)(M|n8D7%en}f4&hhc`}O>*Pkpu-2KR3)&F{~t$Z71ma_gy9w|#jOyW;_ec( zxLa^{2`(v8+#OonDGo)8yIXO0cX#)b|6JsHKWp!mSu?Zd{l0L&8q8ln8Fq2=oKeQ_ z?>3laso>};&aVAb0wnSQ=W&0`K9=<<<&TD?Z&aCpR8zeOihRa}ZL+uiE%IBQt zX`QB3xR4%FK9eK>oydXIETO7E!PhTOj%G0Lf%bt#2LGW9P;BLz7~GIrPZ3m5o#2te zYsws(kk9RX8m_6hQ%X5dE>*-+q0g^u!fV5V_pC!`Two^l3J7kHPJCLeE{nOl+UV@e z?egyuaVHKcXegrD=TlD3w64&{iQ&L83Hs>OWlP061FmqG2()QzinB6)@d0qMNWdXR zarHC$Qe^xzlUR`JvsTe@s>O6&*sbMV4c4h?zgIF;IHxytz!{*M&{ZzRr1Wk(dmEU1 zZg*UNwQ*o7IGa)HyKePpLmNV9DL6{$uPOBSGp29EbwK)y>#x!n@5~orn|-bL;u{PR z)kwn8vb@_-uK`xO;W3Ue?+(n+H@*8MVJ0|&?L`_xpePMx>=<%%i^KZLS^Myyh^V4D zR*x)43^#_#(C!r!h>}ZYG-&r)tTvYuUeEZxkWE-v_ZsEz04Hb((1_?UWcfof4;D&O z?iXGW7W_pm1K{l52%LDsk1G_6g5ov^+VP3X8hN!}&2`gm0ukt2B;*KM*48!oxf7Y| zWLm&3BCygOL!5^ z_*XBGDG;73754oj=|MV*md#Sd_Lf!u#NSD<1yoRRkH65$v;{TIXjCUd9CA92pC~bi=h!|1Ia$*of+&Tq z8pi3|F8v;E(b$uhwc||{u{+&f6=oty8L~y_Ny}2C%j2N4#=A2w@QbTNx8&@H0k;5s z|A#G<2_s9E52iS}R*wQ|n2#BrYirg}>+hIhK%fSZB2UGn9vjCga6*rPb_^>@#P{=z z4aDI*2dlPec5ZTSuE_~Vn=E5#UpdHdpewQwa#%frD!7_HUuNLjgGxA8q21;V20^jX zoL`^JA*t1Slw{y+Yt>tNT1sz-H7?%;4&q4_*T!HNTg2{FwOAFU0pDjKi@P!1PWothqdJ6=^) z6>9c*{lePYxf#hVx`6}4i!tSmvD2o;vn=``2=7G|gFB!N)}ewX5!nj=TBQV!!FQ8a zh6NT1?Fnw_-9(qmEm&Ae1%RoPS=C^ZwlrOoLjGFnIs04KHYW#?SDAYuEuq={?qw8&2Vz1D^W|`DiPUb{-yk+Z(b?yXg9S?u7zDQ zJMW6E2J6e&(66Z|=*;W=AE3@WeRoK25R^J|CBc+0JJzaibO7bpPuvTduzO7G)8wk` zd`~Huo8u5}vO`hkfMS)yNlf}xCX3L3d3ILeB}60C3ZYl1PQZvWbxZowQpBYh(;m9V zQ)|A}b+kP^`yuUnwDWwd9_D~jAA*7kd+oo4>cje5n~s&)ra32P4$^aPe81+8-g(VM zP->wj8}wRp&=u{7sKQA|qDOBobU}*v@*HnAIanDb-7oa zpYX>~g0qBXmf+T5tDo0L%<0+LCh%lu9F-U}9_T`y`f|J8?(VA1)9^@KKm7EL>y;tu z$s7MBFx(``0lia8ofnQa(y2JbnXvR!Cvle*>+vd|sahY^OeIr{E!Ps6D_{O=@;K1K z=deE#qM(yLhN>JcrcPo?v^zTqA%MCaowS;_)axplZ`Hk9IZq>FF0_T3lsJ1ufRQpojt z8}4Zuz#gDx-xlqA=kM%$uNl;+S$JArzK8Y8$uVvLpEMMR<2t6KotIjaQn1?X z6{RrvWM>)7c^Fqc@(AjeQZq1hKNDb9ls=TqcevN3I42P#pF~-?&2?Dz<=z=u2W9g|enhi)j$ln+?=9Om zSq<+IhJ+v>OJqED)b*JMejy=3n4+HqGvnEP+vB3+vo>c~aE*aAYy?`TRRa1I6E|^W z;(XShy|7r~I3k%dz5ovh_$~P-FyOrNj)9}y@Mpe6;mpRO9z>{RO>FM=$`gP6{&>WUIxrR|r&vou< zx^pw$D#Ee?3?+w>p-NHL1avtDJw=&+aQY#iLcS0>q|Z$!s0(X|$fVWxZT3%e+*?Nw z3ZrJR)?`?elS6&;0`7>9ERn7(a48(df(ooG0V|{k_mqRe8sdM>_Xs8Oy4KNU`{LxM zCeUj>V+UbCUBqlODw~bBpXzKh(NUSKZ5Yz`P73dBc}ue;idGxa7{u3wuL;0I(zeYa zr|bMmD5OWi4u28Iu}DGAI;7+p9(>q1miS!vnxRJUAjZ_r|)UZpI&K6L_H zl-_xmyKl{WtqjJ6c|u5=7v4?kb;5Z9ZH)ivtvVS%xvsONgeNN?4q1kIUpv{Jg(EE2 z9{Gp{fJ%kbIQrKs#EBn_rgO3yQAj;}=t9rU>+_+NFiEcWbQ5 zzjm<wg#{QWWlnf(>V{I*%V;#Y*OMgkuAfKUfIRZk zY<74{sx?AU0aMM!?b|!;Lyu0flc+I*s&7#4Bb*XH;C9hM6BS(LWX#&1lZN~nk_1eH zM;3s8*wAG*XKdR_EwcDPH6 zEN^oD?$hxYW4u(aTbt)`~rpW6in z*TdE+2V5UGp?po#BR9CFK7unXI3j`Gl5Hrxlo%nIQZCQY^cc3V?Z-N+Ypu`-8xCCN z6oh>i(>;wr;yC>gjeE;c@)TnY(qr}#QRv1Czr7vu2>o)dDl5V*c0T|s!PoMGi;od< zK_>aJyIS=OQKe}h<-F8TTG-zK2U4ECF0h+%?zAy;4MIlxZ1lYb{nTMYFT4ZUS%K5R zkohM`NHEwNLj2*08p+#zCz$n-@sO~`9kv&Bn_^K4I+#++g>sfK6+%zV(3&RPqL6|s zol$xc4ZVP(Sr9D97B`n~jL4U9BdV02t{)LrUNU=WWWCEsYcf9*7W_mb2U^Q{md$H| zsby+H`z5mxL8FD+BfYZ8DC6$pI@huxw^Nt?)O zsRpTGZudavubE>ke;07}T^^#+eGb4*g;1c++>gR<>GYYrpID=m^sM~ftEM)l1KYo)VZ zT7oMS0>6|^4e0%-GDHw^$!Ds1w4L!`+?y!)c1S#ryMX@>G+CVEna9>kDcsd@UE|Cg zKKQBm+2L++>?eM(B!K(pR4q=hZte#67diLQUseQCB2Y8b%B)_^oS%kyO=y0WMCqLN zn7Ct=&g=l@X;GXtcb!p;v^|EX=$`8(`V_kjFOd;=A7b3o-dR0f=)JE}aSHz+upv{x z6ox)%E+Vz-5!B-)0dR<)10rViM!xQi7g*7JooBrY>5}0hoRzd=M-kAkwBn@65lyjg zA9Y0%1zhCUMpR;109Mip^|b}XtSCn^Gf4Rp(Z0`NBGj)p8k-zMyKY%mK&ku+8qp5? zV4+&)AS=Qo??3*)kjFIh_u|`+ZPa~~280OrvOh+zMuijYQn<$|B&>3$0RN{`NZg64 zZ+0&X0CTpxAt_%~2%z>(3Lc7*_;Rx8-R^j4GDq8tuC0(d>krsYXYu3v6dqC?1&m^x)6c)qb)QhaCiA&N!~QP zL)-O2x78Bx;0X*+dpr~Y4%6}YjB#cloHfML8XGEm;avPebCY@#0rDZ+R&nPco?jH=&}fsjdw;HMD6)U0VJa>f9S0-3SYGB`QNG?A*Q z;oKh;OaTt~dxTNH!Cx?O5gJN1y6!Z(X5o8L_q$z@LX2g?xf&~GIMX0q%q76yG7P;= zik^qrv&Qi4M448ojH?uYbpOSB?58=YCGrUb5BNAj=c^8#uZO@xpY)0;1*!pkZuQvU ziRUal>26X`9imTqhW(0`@qO)r^6>NP^ENp1$sN@%Vx$(56i=*Avis5T#0_UN8T%Xm_^piZ+SEzDkOSw`_00A|EI!p#x2K64ti~{kf?SIz` zQn#R`3(&Qw-~S-IP`+V1b>ZicLFlYJz1{Y4VT?une?dqR zaoQER$;7i_g1OPjfCY`Se&vN!MQ2>dWU0d4>Oe4qx=nkqPB<5j4=I=RB3*qq25KC< zFC~kQFsiCFH0!q6dpQMc&AI)EZWIuCuV#6FlJD$?eM30gS^8{%Y8~|7!PEC&$cCl= zxWs22R=2woks8=gr`Yw#*5lE~TK_xk0nZFN62~qRQZbm~2ozvODbCJG-J4|?eZt|M zS6S7Y1~bD6P+a6&8jO!zF6ua`|FYthNurebHbZ-X2^|X$MZJ#JPE{m2f+LHe_^$jI z%^9uBz?sG%3GLnkCU}fDx?sKpneW@uu%JB8(Avm~8Mm71jDs}%?Q+BmgMm7D59s-S zkdJFdD+rY7(vyxG;YVD10Gu+$gSq)!1fvrE2vNH`#{PFBvl$g4vK%rV+ZQ3|h1izZ zg|}Eanga7Irrm#8J##)9V*WwV;=7XMuz{}E8(YHveAcnsZphJ^9?vGi_KPV6^j~e< zp6VSmL>ZGD+I1?^8l|^u+h<*i^OV9mt1wtC5}I=_J#S7hisBzCQTQ1x--IYDyHr45 zEX_4&^R$TkE_=`n;J{`J)CWC_JHqxVR4imER4&ucf-Rt+S_LFON~}Xj5UnyBS6FO8 zk(-pH)fe|>)GC&T9LeFXEwtvRCbl}oKGZ_lcq#555Xs1@d>U#lMuFTfWy$1WJzAQI zj(w}(7%5=K=hUwR=x26?pAPQ{2NXiRYW!tI3O%G7{}a61YyPz4B7-$+gKbbVWvkX^ zkvTQPO2fD>VSHj^7nHbd2WnIw@;bhrg(+bjQO;lx@y3-h&f`AhDz(b>T;xiVqlg?r z7aJ+xZ zJn+I>e%}$(falC=xKV_P6`FwGIX4EPe4Cnz(<%q+#8SsKP;MZ^I#;{Us??A0mw{?Z zjnsX$4QDc1y_xdo8DS(xV?YXEtK?P%M3+h1c&H|+95Ef<(GNUGmm?u{oPxwdV_(&L zaew%KkAzwhkP>eJ;SPnv9a7>8)lE)nf?ixieYA(3w+`BAmy#%p;=Yek(Jvt!RWkmg z?)z-sZR^Jn^K&ALFnZ4!B!-mcKd&rvQE}8MCKE-wlt#T;eju2}>XdRVMvt^Vm7TEY ziUvt8vcllZ)|m*T<%0M_AIL_z4aIeF3LLPou&&6yzGwXM#gXcu+I7Ytffnf~{f!^& zws$i023?VqV}t(_1cHKGb0*EAer;7hdqci+1=*v^=f=JOz>-5clqs58m2P9s*{SR&_M`H0$LGYPqB^W&QNxigP> zD`HowO3kJ5w}cw;Xz2*2f1imIH+E1^5O|9a`0j@jd)yS&Kf)Se5D2?r3$L%wa2f<_ zR+iYWLf-d7AWHqEny{Z*X>+*3>U088bInGuyB*$!*QLL)+kXUV#;wmqzmHrS!l%R# z79}~YID>Quf@Lutu8(Lg1uDV#6soe+NutBY3*goXuSamgbRYnw|5k+Jj~DuNB5f{1 z>^?8rxABf^KP*{{AP|U%mk=d$JGawt>zN^bRy!d1h!=M)V1H3ap={V_1i9>OFG)1l zk7xYy1w|NsWBJ27J<41BzQ#l@oPVfBtVP`nq&j!>6f6&lyOsZ{dDPpHOSy^8t5Kt! zPOaT@WDAIbYWBd*sWatSMjmJy%_+K#(6l#<-9v@0^e|$Ox58@zIa$z`h$0%Ym~t7# z!uOhSv3a6?1RtjBe#&BzyIQWkBGAbJGWVHn%-ivU=Ln;pP$ZCIXvI?s_mzXqoSDGj z31DvYPG!B%v%Ek$B`e;*=4Ut=6~|3Kh~2cU+K5G;OBwtbd8ZL0$yPXz;EN#!rNVgb z_s)@&vveNi6}UGeoV_^p7zd0z%=`Dl6FlwLd9PT7X;Hc#GYT>o@rcZ zmYTnCxZ)cbQZ%P2_CBg{7dwpo>HZ9Vxv*QbEI$2p)7%Qo$qrUho@UkV(E@0_r|Sm( z+CFZ6GuQTx-li2mz=D$_I>xTJ-gu_xuJ=5+3kLlI-3ynvi4X_+PKf6Yia6z2Uj1o| z-O<|m2g8D3>=)Yai3}D~9~JftrvAcYg%eC`8!#dDy3>q{`fed6h#v+2^(<`L#8vEF z9LHRbRn;>~umk@W1m0LD&aKcUgESa^zKy1y15cKrm4uVx05OLl`1hnV&=r;op93=r z-fwn&1<5gkfdTqC(XyZdXCE8yda_!mBF3x|f0C?nvHIarP~T9m9fms$E1Igf5j&bUCLpsN&2oUsg13P$yU>6#7L9^u`9Ko z8?G=l>CcZ?D7Cg}_vkhvi^)%nlc! zL(Y__o3^v>o~Ty2Ub~?jVM%qV9RrpJ`Y+qf&XChiq*rEJ&Mo<6<}7gm@#tOgXT~1q z5w}8@Xx}Uj)Q8i-NrLgkKT6#Jz`-lLBaYR;a~e7^Deb)`6@v^O1Y2Fplz z8_Z@!!P@1VZsgKBaJ}d3uaRVaF7)}Voce1>#^Yn&VmLfn9cLd_s73hI_Q#B>u+Ntr z`Edw8bC}9J$pW47gca094z>*wuw{4*Kq_$}>M81`!>pPYolUJ!FU$jFP-Qz{4RRJq zerp?;P=Y@Lt+~lB<3{r7m;^JrQhc?ZXGT$j7qHOjmhOQSaWm*r#{Ktmjbm+~g*YM( z8|jm5I@w-S0?PR+$F5lpn6QlA9c6?-Co!jfO&LuqpkJ<)q``Degrp7)8Z3}U+;|Yu zAQ>Bii>S$4!7Td>=cE$%!B>uBtLqbIV;p&kDh;?aCWNYD2y=}2dI>$POBnhZnsT(g zb{otdnPTL~WiCV}wzal7B-v8mH_++xUYz27|QB; z9e)vfGS17<0_S@FP5hGosxs4TLHnQ!RXEkpS?M;!5&tZKTEhI5WUGL-e^DY%ZN|vS zx4jl0Ir+GQ8)2JKetl&{`f54i&a7EfDC6jP*zS0`%BIhV6_+CGnDcno<3~4psWH*4 zs_cH?wz9=V!1q-bUQy}k@O9kaKKHu7ZJ``X66ITaHEt({hR7q?gfFYvn8}oWlyO3f zqRWc~6HDr}F4mH0v#3bKX_LXC547@Itb0gv?|ame33tUy_f#dVGU?F*_sq*LtxCkN zDbdhJbAfQA3Y-~d2rpS-kQ=3Wu9{<2XQJ|z!$KeaBEC}^Ld7Vf#S^~DYN%)+cPF{a z_f)ylrzlCp#(cW)n!=(&Yz-fzgcm;ivV)VjadOG)i^W5 zz%#)Cr;J#;a0;OdP9w7Xk8vOXus)m}aTjg~`2`_7v#~~>kzF}^q8J8;HZ67=K6d}& z8&W1!*w=ws-ZKfmO4wG|3-pgr{YQk$NcW}AB3uZLR-MJ}Oz$663e#KXo*F@c7P8Mx zb6!fm4wiE1UrRw7;gpWFz^}3uTK90qWf4Rz_%;;GxW*{`vt2i%3ZDmZBo=JUe5K;n z1(vV->xGQd4V^Rjx6}~=yMX98NNW7#LjrwNctC^v4kGCM{-_83y~R~|V}w*3QEqY8 z%-8-Zg8JFc@nDr?;p?h=YuInSI$*xkBeZNTr1wAj-ZL(IrZPL+MAr|4*q-;N%bpJ# zmw%>rEoMLKZ}@!@swyZ)nGPk|GsDh8kRF5QcYl%7nPvCAg3o>F4;Dm5qz+r zYy@KoYUK5#FhO@)R8T8xx#gQM=r?Xqm3t%x0#o$T`xX#AGm{{s%ZQa3i6#5juRixN zU>2TTsRfr!vC&n5V#!IkXJ^JNn?;^A7ele9bFgaynb(TjC%4T@&e0YykvuR<*{qZ})dPpJsyIZHn+&)(n zq|4PF-g1RxlVH~p!d&F|FYEWk3aB5{@eC5rc^UU`w@Zwk_Vxm|3F2N1>MuHwy50Gx z1*Yt-uQjeMy?m{lQ3AV+Mq=^_Lg1py2-Lg-bVAa8_jcZQvt9`xyCBdbMNAhFa1N^r zTo5{~I%U06fL_G>Kzh;Si?%Phiw|F>)w2X&o=D$9*VlPn7M_)bUi9QR^ZmcJe#`Dd zYr+imY$x|}DEyxCKD+)@^n39sc1={O`JT~fTc@n~prm-cT1@2EAM#KcqW(mq*GLB; z@x#9sF9npR{L}1I!6HgEm*X(L7b_1rD9~`FE?!I)w~&SNHgu;qd`*OfUG)^6`-|R3 z9DnzxO}a&%tuA+`E69T|llg^@{uiw+z5`h4TRnt$vIbxT8 zbrziwj#<4C`1rWNB z=;RmcmW$Y{57Xgc+DIuM zI|pEC<4-kZXz9+2m$u_t8R{{>KiRWd7OmfGF}@pFQ-5OnFSiWrmyJ_bA1}5>P>Lsc~(0@2JiH`Xqxp_>A z=((qnW3AhW6#)5=#-@huQJ7tfphItsdX>Q{P46;Rr54+Ni7MgkzYVjzpXEjUu!Q~^ zuE^z;i{?piVE|h{znKlsAUi?s7m!9B(2Ts!`>}}f-@l0=)fV+inA-_Hz1X777$#jx z1Nqi2WMQYkc|Z2yYul3lkdD+0ixuR_SvhnQ*0D~cz9uOQbMNVH58%CxNaU-2YNhOm<#eF{QF@$N47@2< z5B;|mm?d%ES$^4U*4sv6&Uf1C|>~C5|^4YaI4)_q#M#qx#FPrzGEYLX(fR;-h|JnYiQ~ zYID{+Xoi`7VF&DY-;5GDcZXEKxcI;BXDq%-8d?`xOSavd>=Yku)Fr$4ioC zIf5yHUjvPvLH5+z!}tVk6yy;)k<&B&`&$GJ>IQldNSDO{aK(H zty0A8=Ln)@H}tzJf8B;DJ%PdrruoQfqPA##ftdKnthP#e{L*<_JXhe zUR~m=kMpzt&M%U@P5Zql=GIhXBHaK38Y1<0cK*_(+2eo`8a1Y!Mux)(gYv?@@I!)q zACrHMy*#2P%sV$-K=@uF*>A!p=!Ip170MlxQII};!FHY945ki4t99!<<<;_(+$|Qk zUzq7s?fwZhsQc-AiC42I-~2jt(dvhmlS@!7svieB*0M-^+WlKkFNt#O3t@63;^Lqy zi7|-D1!*~D!KA7p*B$GC0AneM#LupRcdG;K*GsBOM8202=WT8r12L|NG@n*tRc?iW z)utZrcc%R4Btop-9^@zjOnC>n@`)7z|N6Y0SdX`qq_M(jVy?-76^Fi2TL|B_;l*RO znsjZCA+{xS2!U*xy|aUqz%51YnMEp0p20Oa3JJ2|E5gb)&YDwBo~0bAK=K!L;%b3n zOinKV#F!Qqp|cBt=qkGsE)^jRp_XC7r!a!xbR{fakOUR})NSoYOK$#GS7ulOdCsN> zUx9|ipfhUwE*p!dkl4r>eC*VX&> z%YDP=<-FIrJ~k1KE;JZ((nd5-rj5s)0YgZF<$FVx3b;Ih-!N7W- ztD9$jm6jzY+H5v7n{wClJEVvLDu5r%ca*%IPTE0hydkPAPKyE z@41UKD19d7&+nK1tX;PXdW$Qh_c!4WBc%cz`U&k+GW;LT5FTXwK9M!kM4Vl&B+;5M zsiGj5qJ@P9?3*VxA2i1tE{vAqAbA0BmAKXxJRfG*bR&dt)7#;e1H-8^wl=l!4OpO~ z)fWqJ0_%Pa){cB|+Wuc->HQ}DwQJjaBU^2HtdB08A3BgRKy|M(7Ium?M_P!NFyy@C z#*f4=bf`eF_#!b}>>(M)m4z1w^!b4S2NDQ>Z*s{gwDY}wq{&*moBCrOU999+Dc{Ax z@t5U;jNcf?>Op7l{_%wvGW4Q7Jzzvk=IX1heL98+;EVt~_+<=@d*dOE@>^c<&+C`( ztzXe6kpE`v^ZgL%``xcMN^gn}J*mmU;&KVX868ilBhouNmL@vE)n=M}jlTE))&vv( zVssmStcC$#X4rRMt4>TKm2zsO`m5t>mH3~Cc%pId7zZLS384N>yL{YdcrB{_{cu7N zNbGI0f_gxoL-&m<&yODUTee;6Q;X4x3bbRwyMfznbO@GDj#lye$K=0< z$%eotkHv_yF=h$*Qb)5N=_P_xgUkNb{ua5#BoD;?9U1#vAPx7JZ`*aO;XTm2DLCIb zEv-O&5Mno6GB9~v(UjGtp&wD}!FB4}feKVc(@H?`^hoFC+xtYA>V&tMfge z9$5R2@@nC0uKg3Zmt^W-TF5ZGTU7GREjF8METCy4Xaw4#FImS)5#jwTFd0>kOt$$E zii@rW$vcoNq>W&If~lVc&sj_~i73R9IH7U1G#&T)d!L^P%ee|9C)7#G1?KQVRxEJoVzdI^t>U6s1~sZO(9jyb?Zm;Jkz1D8h}ptv+A zUSpsnX(bauJ!nm282Vpw7~C6)J<%KNKU?->Kege*gj2wk&dsvw+(J%_3N0|Qcu{@1 z5zgHm$3HMiu`mlpMPz2c{D`%%%}%28D`9C>#t*pTKU?Sfb&BPlHsEhvH0Vw7axKH% zAILg3ZS3B-Se7eGkwfvPx@>c`;298!uEA-57Gaim^e}&~Ujype%^jl7G5B-3+_rv< zLopT__mNQ7m`WLWrbq0ek7R*SOfhs_581Z`_f4G;rD&bJxP=W5m3ET-6eCNN!|_ndQnA$f=rg(yZJCsn8-7- z+%oU;kP{jwHj$kZP-WW!9RQ)9b#7wkP|b?Ld-2mHh%U6!iP_duo({Uh&{rOZz=^2c z%Cm1JRsoHze4SVwE?R{zpN`B+K~{5?dIQZ~ndQ@eX?{kB62kyL4yK{;o=WsUYAJuS zamZa#Lhy<)^%5V8p|iQi7ES)C3EQPiAF~>HZ&lg&sc-}eIpRN)v%IVG;VevP~ zcTuz@*gcd{q3i4IAbNcn5PJMKK+5bF6HusAt{^WT^HWKlT3%tBor_CQP*7~EFycAf zqQ**_`%Qu>A&VO!m|%#Dvjj{?2h`Rh?9~eT`^JM8-~($Bp3jxW*PzTvfCTT;=c+dn zUD^J)2j${zuF1BHdV?)#HXqqt>SD)F4T)3&Z`2UeuW&Bt2Om?G^TIqECg*8w^{TBO zBQkPZi>-fNic(GTfXuY^lsv{(jkO{=gty@xMfAm||C(LJg*iv$F^|u0`mh0_`e2v% zB)G&mzgHEcV^4R%{+?v;eyt29a(l9CSlY=Y`GQ0~t77Q)PlRG)t?cmUm>0Nb_4m_+ z)Td?7w!%Omg94Sl4%+YX)75s%PDFT@tq%BAtYrTOWXf;ggtsvyGcs za@LKN<@}i27W;wC9w4zM@n6a-#W;ytk^GxdLVeU7)w*KZQIwL5(kCCRg*ah#?h=jN zi2E%!0TKt!8`^pzz+CW8h(H8kHIUZc%QyH~01#3>=)WH@zvszpVIeVTJ}a!9bO!y7 zQF0>nij=xV`?QLOM3^CVSd7HhbZ~^{HjYB2hU}%j%mMd5qtete$v4Bl0`6cicxk54A`nEZ(Rfkt4bDY zW`$;S88JFPG=8d}oW>d-bgX!4bj_9i9KejoUFHzk{!sIhNt|?d!by~)%{u-J?=J?S zY1KIwpj>}%`t)g55z@>i#O5D?;DQ=K@DfRG>E&f|k~<7|>+7KbJ*bs%Ejx*pkb1m- zD&AVP*BP}2z|n4NVb5*_eF-}6nJjZIfwqA^4cISfz)FZUJKz@cmYe=aW<3i0H~rz? zEaxs^l>oZ-mqM0O2UZ82uWl>M30J`tc@a;x0^>Nde{u^iUw7+o4{7-z-Pa=Ffj<^) z6JXc#x=wT?H5Q6LLPHEMIPRkHxqN>q>wLtRN(xZ#F(!yHNUDGAb;9f`>=eZEQ+37l zEeh1_`z6b>&iVuu0V1gDIX7!zJE!yUwzO%{|yaHqu%C{@@j-_3>-QYH^q z7}TkhJA09JbK_-|74f6ZXKxB0PHmPkL28oG`D~*i*Bo*PDW)y**)g4MX}kNIjlS2*dC2SY@?~%t&76# z@uG*lVE~RlN=k0BvL|X>(C`ddPK+=)NvcRnYCuv_Qh7An%!*rK{x+^^J((O)bUe>^ z>jB?E1V=)ovGGTOnF5Zv$gc~ZX@w{W*l8X*B3W+`))t#8H@ttNbtrY-5rb#w+*&)g z8&P=(tPbkiE2d6;I8^jZJ$X!Dz!AIR#nxr9&@5uhF8K21Qq3pL>2afSh*G znJ)L22|Ay}Y87FHok_it8?@or|CpVFE%8}GaU)Njj4k#o1vyt5Ezosc7dv<{r(y#t zrg-(H?Bf)YeplR?qmvP~tTEr8%boKJk0XA2deGfrpbAt6S7j|T?(*4viZh^ucF`80 z3*C|*@3&l#E8E3oz=b_%H(wV&5~0vx3`1n&N6hN?G6bYx8-Og?wTfoWYu<04Mz=!R zW+5Jwji8y1#!AFe$b|PD=z5~E#{;&uF-s%g75ug;xyN*EN=mBJ;w(@Z-Ov9(_MxV! zeR9EwTdv+tSEF^K$X&o+>P=3CAw8gQs7hhEZ2LA(N303=C)t0I<68Lo7mB!WI_7e7 zlS^nL?UcZN1+DGi;ATm|rr1x%qvJ2YLuE$QT07T&f`-g8O`_c6Ts;=piP3~`n~a(4 zA{*-JgZs|qt4yo=KKwT1s5Vham(n$;J8kT0Zu>(H|OiH{+>jd$;-{l~({PDGaq+``@7X zJ$LuSrT3asucRP9*N^)fGvB5RxcW3+{xq_fSK&Ma<(*#QV-=Vg@TC^LHU|zp z^RTsWdB3VKX#tGR4M;lWmB{8OADn=t%%PU0)01l&^teo z6O#qhj{#BZTb1GdHsmI_mFKpzv9lb&lEv$cD;!AHt@1! z-?U$Ho)U!uluxGVZZgB35>G`(aviQnu=XWgJh{s#!(S|!85a&rTT!39IqO$wC66Hq zZ_JLk*;(uLLaAvp-;_%!plX+?mh6Ux8?}=9?<^T^G%fdEuxLeFTOD*>yr`w7va+(Y zCQpm;pxJfOo(E6(HB#cUZ~r~a&GlG@)?l9>&dE3zpg@O!{kbgs1xE-o&2 zH#awTu23j9F+!qeB2n&!uATN^`$twZ_gmUC39G#%Ze4rM5TS%>G!gE5jJg}KXGJT% zy0UX>nFjlvk8kLoA0nZMREMwhME(F zA=b{2^1_*8jl9K|4U<0OVNeZXE13+Ig$uL=Yo%YPLkLm{Y8*`6VyTfK1fWQwL=dXy zJz5q!40+92ipMfX3{YC3Uy#sTvk2m6Vbn=)){@RRtk?dL7>>kz?>hSctq8Rv5*7Zm zv_P_PQ9=3#{%^$T9^O{D@uzfS>4o9kDg$OYlmMf>3x$g|7n173JQAarn%#}aE zWtnQ<^8RV%jjSjZe7x(yrs==SvL-O7?Ur^UBOf4k%db?tO$|o3TbfWMs2Z8K=5lbx z8Zu8w9aB(3R~v#Yv?{vg-p9W0cIqJ$zlV2;wm)dDuv%(*3bD?zf-9y~nYW6eHqL2x zh1TkmVi3haq@<^qS#c@aRX$Sj60)f9DUe8t^3K8HIYi2q>IS&2f1dN{Y+e{`Md7DZ`WPoZF z+Qr4?A!2bP`Z*U^;U7U3V0sJk?$A`j1m@Gb|o-b7q@PPk$(4`HQkji;>x| z{${LP_pEjM4m#owWeswlxt~kYB1N$x-e_LGds~{Um@%%IpdvbMQj< zf!c8s>4Uq@!J=Q|*(gCTM)jz$>(&~j9NV`?J1-tqC4 zL2m}_U%pSPD?aztXW$@RMs4L+Ot|L2+t^uYw^-bI->=o(-Z4Q-6PZAM{e3;Zd)ZlT z+T+Gj@Pf(838R5`V8EISV-1@rHv{MWiNFI}N-TSv&p?}Q@*lwqSK^Y7=DTD8uZ2Dn z=i0O7;!>~WdC;F4y#>m4>sX&x4S?>?t$shr7XLNwYPXt`SU9h{+0~qBp~l@^ z_c!mBCN-ddO)=eibNl~zbduIbg%>-p(p-d+l^CBzqVM$l6})JfB=0T7>%JyB0;qA9 zmlvF!ok9Hv?FnR+g{Ag$tI9FhNnu7=rB**L-Y`Hft*q^p7vZk?osYcpSx+uj6b@SP z5x~Y|oW$DP40YA}Kfn`9OFEjBI#u?oXd6xJQKjPP?g~O=h z-4h;1K1`rw{JO{U+l|mJa258{BYb%>JB6o+*opC92q<(8r;jd1j*klh%7=TqVx`wt z{t>vAM0Qclc-U+}|K&e2KbcXx`Fn9u5pr;hF(B?c?5^T9<`^$Zq`iuax}5eJU@Q2iL*#lu zb)CWj0S`G+Z9Us$g5yyyXZ0V>w8C{r=cV_sM=}%s&RPX1{`#wKLw*u-d*|uyS1z`L zl_2B6`;gp=3}X$pTw1f5)QXC+&CRae;Sfzm!)Dt9EZOIn~O~&){Vqc4PQ5a=F%Eq*|+ZMXQ^u8`^pQ}$AmWNuJ zx>u|gD`*x<+12!m0$50J&0kRmWU9L_MKPv=J{|Ty=5rYyvAD{*Y{c-bfLatv&~N5{ z2#s2R59nI zR+EX13mAAiO*OH&y#ktZs*PM}!zqN{Pg)Pd-$(_W8w}|qz`v$4uhBi+s&h+qs6QWO z*_*E%F;2m-ga`Pg38CQSR;Xa^1jO3VeR*6hwD`o7nq543o=f4sD1_4d^++MtH8)$k z!+x|M^;omgV0L;sbJ)B<`+Id0ic<$45|%9SvDPbUU{zRnv1syA@8lCxi63TeJ|I<; zdp%?+Cbg@t$7GhLRXPuDyZhTJ=eTr<9_^PPZw-U*9FqSYjaB3b9$-JT;pYJ-*4@_I z+*Uou^%*oPXmPF}+TjEPti9OG+-EJ&s1($s6sZsbvPM^reXrg zE(FH=Iv{iu%#oB4ysH~Zp7?A?qQwc91P`=BpSv%F-wQp@+OON6&(03dB4Bkv7V;h3 zQbA6o92S=n<}=Vj3qHFv5MCfPpl|0WqivlPNqLu&5WhhnvZ^++`=71GsN|x{$@l3O z3KEw1kL0n`2`RfWI5GN2rm#kj>=(-|#;XhfspD9@aloS}6I2EOvjCc-ZZK;ObjRo%7xn z%u{OX|8;j0Fw~4zEvR5KxS&YXtnt!xTP}=7U#oxIOiHSNTAZ?4QZ^AJKio}6L(c=y z)^o+NR@OdaRzTJbs-siFw~|3csGYbA?(gEzC3Zt2uYngh2c zMk-ib0htVkwhNltr2x=4=~>0QT{$!O$Pqo%pTEEX*hysCD|EsjvvaG(M0bP#txpkkl5g3L+}#51c|$^F-FU{(@P0*4pBryJKL9U;Q7?Q0v*Hvm9mF-<0E_{af2Oadiqu=_5w3#7t^X>N}5BW-7un?~DERadq@ z;vQg~)W19+u*na-h3e-<+=<=#6J<)NTio<3VErzlfdiA^hu@~%;<-1#f`^R6-Ep2{ z{4?WxagJNwuJ)@pB#-a~4s$BmF{l=6qh!?U7H_65(1Va4*)fwUT*BRuWXu0;So`w* z^K4xB=X2+t!Wy|x9PsfQLCWS_cc^?wx43-DdIs@oeYmF^4(}T=HLDq5+q0LOHJo?c ze+)bGN8$=$owSlEFcXFr_3ER96uGxn%(Yy*Ifo)S5F#h#|4AHZqE%$Rm5+47EKlZ4gF&YgTQUY`<6s{GP9B zLGC0PjSMB^UAg09XZB{Q$9hD-cuOd>O6#;cG)-gf{Xllgq#C=v@#fNuBY}C8MZ-v3 z3IV-$!GcK9Y?|VJvpQ3Q4618|3F@trsnCp?0t*?Ha@(Z-(QVFF9&4K)dVkzO19lK< z;&`4h`kV!b{-KC+Y#Rv~TN5?!8*5JyqYR>i*8K8SQIzxQkNWVkLpX-pG|2QuiE zpY?>k-D6D{_s#2tYs>q7z!7bG^1uGX6K_V-1cMxgL>7-d~6%%to`_KwVRUZHC-zW)yg;8=}40{!pAm3}BvAV`P|Vgpynt25%Fn{m)aHt2yT zy-y*IEGo7%cdF>a7L#VQ6^Y3Z)iQa{O9{=JU83o7()lI6ODTG*z)K}+t{~9;u<`==2Y$Bzo*0~#X8Hp?iWrP@>xqWpXukk3 zBt-eYLDCVY3q6FJXhvnY+VQ&!DX5Alx;$vpqJB-=VT7gu_RAOP{pD(dn zgMOx(3lE)@7Pq+*A=XMg;+(K@;c!wJ;;!p9YNG|l4NQ!{B7RgQP68{(f^fthaQnxB?cCD#a`PA)$>MHW4o__2!L58Y(h)de zEF}dq3Og*ADBYbOr}Y{Llj!+^Le-pW0(TfG{#I5QEOIMha8`jz6&a({$H1^iZpAfODT8Cxum zj3&V;tBDp!=lpRC%^*{ZJE}(u7ntp0`t|b%s1JkcO#EO3lzb5nFa{q;%zgdr4 z1<~SQ7hj99?RN)i(Oy2`*h?s8?(-|lwbT++KR8bueSjyIP9E7kcA-%QM_a1Fq2euu z-4#5>SRFxjV!T}3R;k%?1U0Xu13Mb4*uK~Dk!1adOfR)-U_Zk3p7=qD9B)4A39D*gnm;?WPec;nElX856t2?tg=+MJ@0FYBX z#d5j;&=OZ+)xoupFxlj6i}lik@58mx#MIeDUglg!ge=jK&hl3W z^RDwEte4Fv&B$*w8AOJ~41gU3=U;det#VED^^r=%W53izdT-ez*C%=en01~qs|+=y z)K1XPl`G9n#p3#VDUz2(YiR!er&dI<+*=(SlOs~bF2tEKtjA2G6Ih=Y)^#BHvr%{x z?Wc~lA%tMTW^B}On=DlfPN$3hN4=AU<)$&@P2{J>-5R|}>nyZ5r7P?(2OU`va}*d+ zC(2ev9g@Xrgy>5EEGB{ zf0hfJ9Fbej!f?_P`xB792KkfBrN%urm5j}9In`ZgaB5}I1-*id7dKldw=U-v`X)Nw zx{rnO3%5yf$=v8Wrb&{i8h!!Tltme_Nh;&ucYuY>6wdh7#HsGBKs+NKH7^${4SdZW z``FX@Csj^ES-_Rbw$GZGNNW{`H$!sNrvslfll-4?A&GLus+5sRv*iB6)>xuQPl_Cd z--l6IYu*(o9U%bq`RhqUH1@@zkx|oo+t%>>=wePwUnl$y#jO62;y8mYTdW50mnpwj z+%t(`>{8|w5^sq>Kps*6^M0iBIc$GvVP{?`!(NL6TO|ApP(Ps`E)hB-!N7}HGc}5) zLPv8$k{+;HV3ZgPguxIXbO=ovL!TeBO$83D7Sv_*PzZ@+BcxUJ7UFX@`@dCZemN0^ zd&JU!J%DY(ImBHf2Io;o!Ag-#jUL>>y221Z^d1lm_LdhcY!HY0o=v=Wi$s_n3*ff7pX5^hd&_-lITS1B# z|CJ_ltwhX*AHiOB66Kl*!-d9@k5dTT;K8xQU}_tsQ*wTiLmpTeTqj?sW~m1 z41;4#9r(J@A+7u}Q@aT)RW??jxY4c9eCDHswq*3EPd$*~yQge*&_N-}Y?#cc#pyYG z54t_i6x6-GA)LI*Cp#F*RX^lLOXj_z9t6fB4ieUZpnjV3SkC4Sus<>RKXW_ z^rA3RSH;rYC&tR?{-xcNH+u0=*#yw_0(7;)dm=A)6rw?4`CPTonUtvdqMq~8g8*S+83VJ z0d6xmR-gM2h%v%w5I|9WQE8SIB%RnVpe*|&pZM2^Oz{p7VnpMDv+AEd4vCbSpwUEh z3mJ#p4KY(Px48ksBSRzQh7KYIjmbxY6iwT_Q0jyH?tScCz6}iK^!@(C0ni1MmDq#FHp6$X^2)QBT_rvULpa+>k zDK_x3rFp*Yo_%^feO$iGxm9XG^iWYdNngLASNM6q_FiVasy*D?bR<-gKkmOU{r(=U zk?wcSjW&Y()>jq&Ce zsQXT9AcW5TmzM5*pHgLxdJha4u9inyei3SF@qKX#N=gDJ* zuu$p)jDs_$gE4HydR`Y*nAtv#*V|oeKI?Rx0YAk6=9$0fC(^VGC0BNrz3je62apiZ z+R4(#sk8j3uZ{uli(9o3+gWCZ4m|0itkIQjh{jLA74y00yEE&*jj*~$7H91b)HW!- ze*$#ia+S&CcF>tdXhMl3z40cg?P5sq4_0M?^epk%k+cI$5i}-4yzYA$S)?c{pg_uw zmMrafE{Tlo%8E2W`j{)*I1gDUF$9v{@u0I;fYaxrY$V&)b*347?yO9XM=M|47Uk5@ zD+RZ|aVE#1zU0-np|Q>9h_d^}_yS4|qmkB^%dSGgVm*!M#(_=UB2FEA#@RddSRnSq z%0Q3s02a9J%Nt-ew=;_Ig)o!q$QF6nOIVrm&3MxRIzP)PsYhNCJQ6*1@94~Cs=Xs? zW#M4|@4S}%KVk&9i0fp0xj7qOn4UJ4eBo|;%E|i6b=%k9Bc73BiSDniYyR7HXG*Q| zJ)hUpC!0l*fWT!2KFAN~asHN)u`Zym_W^(B**1gszH&xN6XyB5^{wfZ=c0EEZp&87`S15*w$~zGXxSPKn=|$iFb%VmVB- z@x%5zvPa@>z2JcAc6>8m9#LB;T7F z*Xx(#Un4Il63R=Dh7az!=&<-iX*-a}QLQ7+8tIpu0^Z|;gj*6}#!p8)h(R{v)2+<=R!5>=5L!(9BKnJY^{p2OggnLoL zWoM4HWpg5>o60fq;mtl6;RKl^rN{)bM2r#MA}k{n%PLbxo+8qsB>G5L3RLRc2H61M zyFbNXSg3~{fk~=w0er;Hv)bqN=|QsL^ip z#=hSXk=@Kt!T*`j7?!cr|Hq%7x0ILQ=&vTVUr&#kVkOm)m;q#ndhl%OKyibM>`VbD zd-UYak&1Ndh}?4J%59O^wlUu9T9{%*-qnpU?CB;SAcHFGE>nJ^LSu zD0a{2J&)Ke+vE#K3ut4g5aBuQN?TAwMq40lB@qP<#3d#b7N0as01BlV<6n%JP>=n= zh=DM~cf-Qd&~o#Hr2ZhqP$g2nbdjARYEGCVIVB{CVa6{A;FbJo1SeUgbh^Gb()*0p zVW{moDSh@c)nH~!WTyM3|LMH@v;o3hH&EX)Y$kQL8P8@^Fg~mpf$gVf)D8J&X+P5V zu5&FjII9&b5rgNu^*OP<`_QbQcHFNnZ+eI${p^#u1Id3N$1dwQ>a;^pj97yt^Bfw@ zipGgVike|xU1TGV>BPq-v}huTG7Fj6X=#7|{snr|ZhQ?V&Io*-^Vq9Zh7!J+E!5L4 z-174#QI4lJ>Pu*Aq!V;IU^S0$C2S|VoGkbHMt~3w#0ji%Bq4WLSyZ1Ibx?l z$FxivQ2b5T<7Tk3z`%dM=q&KpP9>|i!FGg|ZlsAS-ksnQf2kBIARoIuUP3k4T<(E# z!~_5=N6bp)1LF$BWMsgJmf2P_&K&Kz(2lqH#>IPc&g6`!w(2T&e=Ug7k11qff?1l$ zvRaiOQzdVk9~&itsRjTjF_0v3Yy!Eqw8Ytp#wz_bt(2PC_@A;I>Gs)`5Mq0R0|Y}0 z>g4BPeS#QsFAlWZDoef0C}N1)oZL@l1x6Wcv{G}b*cI}hH$|9)@5j%2evdJ^5>M}< z0wZGHWEw=#FZ+@;EnOD@aogXC0*^>3O^DE$1y(&J=hqIKJrJ!>Gcnk#k*!1^BUbq} z2gdBi$v;+pjA1P)EW#r!>~bywUU)B-s925v2CA0S**?eGdp~M3@O}!jT)%fE> zDs*%z_RchGX8EwcM)kbiskaC;8IO(K7{h){LN9{h^v$P+%+LqqFcCQ~m-RNV?GdUP z#DMlF%1E?X@IHU0byMythje_s+J7YK(3dT>fmvXbW{-{LWkgQHr@M^U)yqu%(tv;D zSe%R>O9m!6ioLR+EUDKWl82Dxo{w8Av9{j>JD)-JT{nl@Pq%lNF7GTJ&v})8<`k`b z2U~WnZs*hDMHJd2ZUjEh5ge~}OvOtA-!+Lye;nfx&-bVDt4$;P!}Gj}uq@6C5C8y0P?JHY`h%J? zNc&tE^xVJBm2AAs->c6CQ1N3dB7XSI^wqfZ)iez-B3;W0n*VeH1Ar)F@N$6l@Ih8_ zxf4N2PdAE4;~=RzlNmYQ!Z;SOEAx+&^}bmQVR(McS4K( z)H*8Fe(D$sy^58Wk?Hhe-r!%J^C-2zgTeymM1RRQZt0MdMuP;ZyfbSBhc=7L4{Hb0 zVvbs*g*{2Lt*~+u@=eJi{-s}}$1XWArkxtL+wERuaJ@Cvc;A<8F^cAS7foqq2@ z7%($6jA~38@D~!;;HYLP^)#`{tf-nqy6tSWd41ft=V4dP2xWj0PW5TwGlLvKs?^WY z3C9))a=NRjD7K3@K?$H8z~U`(gjH?&YUDj^yPnuQBA}RWy6g2Y3Ob6oo=k2t8`;VF zBret{vHAbXE3LH=sS5H~a+Vpf%O4c_48X1GUGv(XRquYUDrxRg@YO&NSOcp-fUU=# zr%k(NfVTVhr$A_l0j5Nc&q$S0OPb}gtC@N?PjyApOnXAN1MP>q7AqX9kxuMMN+cUb zhR8X}EEYl<_u61OBx?AHf_X522M;c>EY0F4hs((Mg8t`r3xVH3o3S)*ALhp16D0;X*}gqtXiBrO=qKv1N1k=Nl7FgcS%^zK2iW+>_3?V>oWqufYlaO z6l&5-LZxLInAxx>)nLGTb?m1^+&?~#(?*SmEBk;AR)B&$2x~90yMscYA&i#$ABfXM zLu15o76%-+Ge$i1y>Pr|y@tlPoz)JfiDTLEdF?P!sRiod$H4a=3X+EX~k0S}!1bL)%J_FZ375{+Rtj zaB}Zu#dY3)Yj;Z_BpeE$mOv&JPXmNsF1luV)V)4#*S8g|4g_OP-vgvs3nUM}w>PcTk!iBW``<1%eTx9Muj59)ZQ z)6{qDS#2+_QW@OX4EsO)9%n;ZfGN)O&nK2Brv4{%tCO*MK5L^^S~)_X54yE&J` z;VhxgrG2bLqMaFqrxBj77aBnZBq@?Ei3t~{T8O}g*w}-*aqR-sq9hGDbEPiqxyrRk zgRjF|_Qut$s>~eRBl(i`2w%|+jzXMLR!-#{28MJ{-QV2w49*uY-{y2j%q{B%m2`*Q zF7OWh9Rk*in`(Gnl$aQ9m7toqem*`%HVFH4M(VzDcj%=FQUypXfC4RE+KC+3$HGzG z*?!#jzmpCp+kUn(R3YT()fc$H;5GazDIkRt&{p(-Uq!x@}D(G3n}N$z|!Y%ZnD8b>=Y>Xj&qFPF+^oD;??eQZV07;;opP^};&a!3>|y zf|P8)9FM?X8kN2X#FXbxE!|(I9O=*EhHL(=mp2oa4lR)Sc7i!zazK@7-Wr&|3QP`7 zz`x!zNEb9>OpX(pPW9%?5{Z?quI?m;a!1BqxV{JIGGQovlukyyBvDPFh{Vx_2Q0{g z<&Xn+F(B_ZC}rGgSz&V!f3X@uR%v4Dd~Ez>@vLkVFo3Fj)1q8E5;Vo^#t58)$qXFt|p zTBQ<|s$EV^@M$0END^LZSt-6$hofPqDCEi%o5Snjz3-x2UjQa37V^mTqCh}E+c&bF zs~=2{u#CCehtb*r;)ZD$5{?Z;Q9D^+shm$v2MX^ z(}}WEBwN?owp{5Ig}h>ZMn)Z{8ZsA`&pxJ2JtOEm(+&QpMap*o1znaBhl4@aATCT9 zfgRtNd0{%QcNd4xwu4hvnzraUt(6gy2-1fK!{OWtI>cR9r>|JM@@sZPb^;5)uz@PY$IZ z+#=VSLNNRlKthjr#DV*WkdoyHq7bP}Ic7Cq@VhQxEI2}pI*uEh`w838In9JRP9A7* zG=RdVr5hYpZyp!~8Um-xd0rZhanGKnc5BN111ISD$qt*QRi#(0 zGI4Y_IXSubF!{jx6=i)SRistHq3}FNeZtEVHw?tuQJS0)tbO%2`A5Yo9AtJ1%%f=O z7^WRdmBUj?Y%1KqoF`B_8nAYBaUu7{mo~}$BkwvfFi%AeC3DQF0GW}YKnGH~+a9jwb z1JHHXa3s%!_sf|%)G&%I-H${J zXa}TCY9YU%JSx%d2kH?u#6@ePPbT9zWE-c&Fn52fP}v~|sdH57d`|Ry!3~glTzaux zb+v9kXQl8Y=`{51@XSqeL4HQ@l((Bm7{nDU*&)dt0y`!kZh0n)2g7xTLXbU z@sH4WGfq{QD>PON<%@UAv4Zr5gaVlYl>)=HNgVEQl6n%L`sAQk2z$oDuM;Z33;+GX z>CKK5bn;xn#g72xUaMtDUM$y+Fzb2Y?S6I^%K&R>2Kz=YU2kL}xnIZwq`W~l3Rr}& zlIBDYx0drdVc$6&Pm|;N9`t<5OUt9T*~>Y-%k+M{3lRz(8;l=ir;T|x-Ldq%!adux zi_`@#0JSv|Bl6k2Z0!88{g6vCv__@b6rchJDb!M#EK%35DPp#&XO_kVLYKgV@4lKl z80kQ5|CnB1k!G;&17R|=bosyx#zf7Y1;Ze4#!*ewxic$eFZFFNPQ9LISuP=2FKyhwm|^ zKo`baE3o!5M0((H#bDs;65!Rg{>Hxf{0hbHR(Vq~eK@Gnrjt#fshpNZB`+&0FC#aM z&V@;De1KXaF>+&Hq%{4zHao;sBESE?5m(@&@1ZBIp-|h z)K<<_2E=qYQiKcI7anwd zE9$jrV%pAym#9qAv#T63 z6gst73M%-RIF6q93L@01D|>sa@+m{+G#7W=>Zct%u`ju0@wXgR%eF`(>SvY70hOPz^3ky|1ujCb%-r1k z+)_%%L2%4$Tx={X%2jF^#YY}`o5Xvc+P&Ja0KK-b?qst=GEHeWM&Q)Fif&@Z0)w)| zKArP6#K*K71_Hh#B^QL>O%@*AIKtwPs1Sac9E?!ZU_Q;d?lmwqK!=-~1`jOG5*t*` zQm9Q!367<0^olvb!VPmMJ+hQr)@GWU{ZMLzu2PqsDkzCZ!br1U2`FAFw+dwyFjb1@ zHfQJOyYify)v*8S<~`Y5z8KSxM}mwgc=e!^LnNGP#foBJUaShpaPA8gd+arPvWr#; z8Ym-4U`1s~%WbG(Owz}Ax7^4}J!sCv=&dz^b73Wjqx{4q#biZ%8wz(ZR43-2+%XBF zYe280LG4TLV=zY~ez{HJPi#P4wb@>@$C`e)QM5_M{juvyVLTXm>c+;-JiC5MW2DPdbB&4hbqW2F2zN&%SvQbGrq@f^;}5_DTB>VFBss!4C=WkJ z9U(k+_K}P>pEs}dV)AcsSTiT+!KITX9u)A%iT9B8?Zot7X9r%=S89RfFd4i{x;rMU zmwfqV?qeP}k>tPlf}>d_`T-rvls-ncG6d=#6ZhHLAXI#CBnBnRS%HK%oYGCkG?zt4 z0I)j!T28%+!YUNedK%2a@S+bZx zk#x7{S#-Y%ceJcN;MHvN84<>>%2-brt|GJJH@*>oOqxZl%Y z!Qfi-(3>OEEQ*AHcm-_7z{FlYJ_Ce`%a^IkW` zYRk22*DAe=TygN9GT@M#hkJcvgBe>S#nc6Ee(O3&GwK29m?>TVIh`WQV6*dobKvYL zN(BW&f*_!}8#EXTGinkJjuzth-ao&;!u(c0GJjT1D^U8O(OlxVz%ecbJ0hK*#fwS? z=pn%3JrC5sVV3ZB99QRjr{!#~IzwIcO&%PGxhILm|A{PYRM?->C3ee%W&EI-8??WT z#iE_8Ps*YhWf)ko64x@ zerJ)Gly3qQ*`fEE>_hOP94XFEU{#qY!G)aBkCzM6MZ@}HtKYKYK4N=Q-u_Zlqrh2U z=zbZ$VCeDvw+Pdt`d9IsS=GEXpzq6zu>ItU=jwF4dC$^kC)tFKU?yMG z5KPmQ15xw$+{-llFdGq7dhyBZb8Uv}LZ{Q;(2G44(+@9u{^#$nm2dr5{U&iF3;^{~ z^vL&2SgJH1ZoArpIS&(Mao9B2xJ$mpsi(AcSw%%dM+HmH1a>I>5NOmw(6qlcqX>3e zLT^;_mW4{mJbv_0-;}x^YTUYNU8!(GT=O?h`H$&*s#EY%yHf(c`|uTpfnwT9RwC4u zTr-nXg}m>~BI)7zKO1_O-&PMIBJ-4l?S5M~;F&W#)z;}4VyiYJ52?b;3M!Bj&9+c( zUi4OsvJ6xv{J7! z%LjpV1qWQt3mZgxPl%Y^6jo^*BP?^WE*AY_`77L7*=0?eT>3!%|mEqA`zR4Oqkc^&< z#>2=iv|8Ebs=uG`dpn|R7Whu@@lxMejX!FtL$`A!R|y@srN1!g_Kwcsb>_94Q{Pc@eylFZIfFP8t z>*EmVd`oe)#-H9HjP`c!Hn~e=i!Muwb;FDlg(ji!LaR>W6!a5NcI{9n z>`>>1y)3SPOwsv%$<5ecb8*w;4U*3?gxkyrhTHa57rNDYdy7D%j;?1*KeSKNA;9Ku^L4#XyaX84n$dxmN$T9xLM2 z{g!3#dk|BCh@^spWVtsWCaBr0LJGm2+h2=OHES4RR{k|QdWQNQ$AwT)P{LP`e;J2v z_%Yl6$LuZIFY6hP2iE6fu8`x6t{@0o0QRP8_<15uckmURBRt##s`c{Sk8_W$iU0;S z|3-`MUd`EbroP!b3R#zyGzaP2OH2`7Wai}Fwu)|RYpbhEHw*uA$Y`5!)~VZGP5^ov zf1TvqQj}>NUk#?cv~}zuMwB!LVevpCu)W#iQ%&!si|aYks~? zvi*`=7Z<#DUZ(Ed2KN%Sj?zmAW_1SQxan7|Y6|;}fY)Yp-DG2B z3H|NsW3D9VMfKaj;C?!E{TD;F`=hiO-z#Op?&kotQ91dUMXM%e2$vd4*axGrLyBb1 z)<`o#u^$w$*+`#5hl4N0LstcnZo!yAC{ROC6xeodmBnk7Tx$4Lly+_+ej{T(`hIU- z`tNTo|8nf%dKQHe|K(Z?r;ZCWkbz6yp;R*E7io2A@w_Zu8kH=sY^yRl@j9rW9(J7C zQJf5_j@a$1Cn&1FsCwR~QI5A#%mRDGwXMUBpq*u{)uS2V&G_qldUgkSfGGKCm#}$< z4FkEcA}C$>Nykzf6HRf`g?Xj(e}&u`*#tW6ibp05nw!Z4o|*|6Lp!e0RQd_G#mR!t3TQj#mM5;uXyUts{52=RR$9sYsm^S~GwD@b*%b!` z;cLRpsMJPwo3mMa&l-Fp$R4Xw-JEDL>i2s9`4=Ia`~wqXoMb|H_vl(6D$GHBB1vU9 z2|`Y{9otO-#I=|zg6hm3REMUUE=^f*tFP8l=epHm)p1^pUDOqopj;trMneq<{|@r! zVCd8P0h0HA08&*~1+;jPl8CHwTw>YUAkrAE582wsXr@82?<=~^nb zu;;iqwL)y{XcJIkwp#*zgYV&dw@nOwpSUx8S6@~V4+plnaJzZAlF!)^`R-bS77F(& ztM}hNMQ)b**MjnD-hKd{bF2jJ+Z$c9m_i)%`RDvX1Nv}M7^dWbR&E7y+%&Lu!WTO_ z1&^5ygMS_uYXv1S(9E58TWOCp(phc%X&pL?kdyvJMg&VT`uadAmAt^$<>lGGQ&xEJ zOY{AJNytu#6(;-=Nj|nT_1eF!mJbLRDHh9#jE<}siJBP$>EbHSwrxrU^PHX^?gct= z%ccsCg%D6Fzo}=sw5B?F8&d3jkN18#Fej&Nm=!lHup~RB9s3rHZCgEhW{t}waGo$| zn6y`i75`u3jU@9Wus4&X+C)A zmbXu*HD(_A)7__z2nW8noKWa+3++vg67N1ux-HbfZW%LV7l zE-;YRob8m;I+kx$E$EvQp#q-KU1_GYgy(42fwZ($H?4VZo7^4YtnS3WC!$BXCi0hv zo~03fww33x6hAWt%&C-QedzT(+n{x;IH&xQThGH}A8IBpXi1ln*Y0*U?G8+LWNJKt zGo<%`VxPm>+}nDmPcoYC$9gR<-yQzk6!#aT7>MztEr78qEaLWFSB85j?U zrm7?JScz12BAL?G`M(}=V5YYzcU(hFPn85?lL3)X0{b~MnEG(+)mjbZ)~mLwteAu$ z&=rZlBi=prDbgH-EF&U8yN2Q4S~Nd)6igt7el)?BVJjvm8oI}Z)ELcYVA+~_YBK$u zEQlGa;eC6wUE)(if?8mvo#{pSIV^$&s!>%lgcedJ3@{uD^-+#39_m#3A;}E^r}_2jvPwxP@q~> z4-E%@KCc&*b9cIwvMXn#%jD;(DQ*H;=dVs;KmE&M)*%wZ&u!7fqQktERbx|r7P`wR zG#Ij1G%tl`{46V`{4|5ND)FI2B;<0;*K)|;h^noJ^UcHja>RspaHs`KTttyvSd42^ zfXh3|oDAEzm2o>VFFejm9Er=~PqX_5F+^@sEqM}-?xe4ZzBD<%m*;A|QmNYjE8qh3GQa0i zVPE<7RNjue;6G5Vo2=Jp<$93)(7Myee?hw(?gM%*F_koyhqw;Vv~2c>c~nD|92n5O zxCe&68*&kP(0LMZbe2)o=`nb0d)SSb_Fe#ePF5bg>D8%|XEFQgQCXbZ-{IZaY58!M z$~;}i9VWwSy77)`cN+-l1&JnKPE9XcsKDNf9}ZA zGFTr)XnAbb)&9z0;O^ii@OU9zw~M2&vKW2@pyzlsZ!TaQ@j#5A(Xp{lU%ohV;X{-d`6>>2(S>w)(&eo(T~vMAz`=KnX_eySTdYW>>2ITy1Xtx| zhVrQ6{H}&|B3DydW9;jxu3S?Uh>77;MyFcR(h~^*-9Ud+;qE_UCMxG+1nE<-usAw4 z4cVFO^ynl?XlRCaKE@GGo_9BY3m_B{1bKOyY5Wz@Deh`fcJIo@ofX4u0+n-0i?!*a ztT}GW@jCi$JF}@woT{97<9*vR`dYDGn#mZ(mX6~uMt~{}@3wtYCq@?I_2#%0|9y&_ z3A-+zdl97Vmfx4uAJM5PzJ^!fO?YRxlg)LV#FCB$%)vSJl;dd3||(0omDC%gbuC zq5`X&t{9Cx;>}4kjSE=28Fjh)fPVY=GqyRa`{2PSYo1hu#%B{N6t_vpw3FD4ekz7* zOFApVr%+tNda{T%o#uuHpRt4hpqjmVo8SRony%_qxFVj0s{Ch&BCpE%Ck*thc6rJe zCeMQm)0Lff%Bb6?!Z8S@3?HSxy2P$NVZZ<)Z)Slndn!~<{#_n2L<5{k+zM(C11?pS zyNfDNfpTUCd0@1wjiL01(tdBF4*~Wkp%{jkTlo^NK)BP|WF-0o|J@!`Dn0(R8H)w( z$=KBp7x|z~L>dH(LwmAgg){0YE_JXd1fL42GTIN9fRnk)Kl=`x70s37F>s9Mf!MHK zQ{EKR)B(dGiiMCu92kJJIYMA_A|>^&;>Nm`;w-J^e2dH3?Cfj;@HiL|=R9<_$v_U% zVsWsJYUmiIp>O18K+EkyOpO{c8)`~JTz3kAmnHq1Uy|M+p2254xo|!15Q+2(zn;FQQd4 zE(7YOddEITik%4qlp~;<_*q2_a2F|ok)+jIcf;;A03Fwfti{u@b)KZyw`PhG})67P> zj<*O7>rQ%CTlqu(Umy><1^cdU9N3;tDC7QkH(sQbnsmz~q6&MnrhI6*B3*2@*yRuz z;z9nd^nTluH@r|6?aT3dnsA}nECLu8<-?;nP)px#_Bh_Xoh{w8GDA!p(pz^^ZC}?H zda7e+=y;WIWiYr2{}yUAue_=scg&VKGFjC$(H&4xK_qvr;ZHWp=KqCGo_ddvK~>zm51i#dEj|X zrb(^QYQsyOnlBm%3JS8Vsw%Z9bhl#BohgVGzlgKDDr*0AfS^R_HqSx5?Ow0=C-`c~ zr=8BR1plv79zk)PhZJmMslqJ-^R)yRzplEK&J+=)*~}lLjC7=k~#b2@ACBc3?gtpSDFI8GJwV za{`vHIup<-!LM@3r&=f8gLEhY0l2|cbFWL_FTL#_b}R z`Y$lZyte_b;kDp**fMji3(=M@8`;XgRf=rt>NB0*`6$Oke|v1Rd70*|_0>_}~k(=2Bx)$5@_Qz)6RG;Uk2NP#a+QT37D=UCB#ojp=1owf( z1&eL2M5stf3Shj4rQ3Q{!aRm`xw{!F5cxBfTp#izT-GowqGM6dL!xQc(Wa(C z$X^HcxaF?il4wh}*2MHF57;IdcZ16+zWYGR?uQ*D6<8!+6A>q1Wez5$|ss~U;FzBuKBh+2T(W6 z>C`PoAZ+W)aatqc((toK8bysS-U-^ZZ}-E5{7s>J5(7U6yUVPw(!kCM8utKkv#W_G z4Hk{lvdBFeDXKE)9|mkEPI95r0o9GYFf~2T$MMP|ol*tbPXwDds}w6X4-o$c+dw40 z-cS@#xtPsldV0I54QhC(ySuAYENT>zcy0oaNHi9PJR93?U@@9(oIA+0p*q1=pH?`^ z`I?>;WknPf)HKPi6DLl*yZzmL`ww`2s2LeW#Y}|<$f&yT%hW^A_c3$Pl-jDn$Gtu9 zTlg9CRNSnCh3mXGa-$;If8_AagL|vf)fUItx_V<))|<^{(!P%3Mc1_U_O@lqmo8g6 z+}qpJ+R~DVXRg6r7gL|Og}M^^p6xo;6`R=bQJ}3vBjPw_G6w~oQ$|&4h~p#U$B&%| z21Qtwhdvcn=V4uqr*!jt zA_yl{{oA6no8u^(gkiyRw>Z`(q9_|@x`hA>5%kp1MBzQ-jo+|caLAAfXlv2lQe8M^ zUbL%PCNH2Ui6Xpm&$H2WaUFA}Hhp|_WcR*(JKue8*Lyp6@7{Ib@PX4)r)=Lw7ZaZ{ z9*>rRgeA$Pjg-xIDK z3e1LTHV4CSK$ew`b{b2JMdr}plJ@p?ReisQ>70O?JL$;cT3A%i+5O^+E{HN_9m?v8 zPO}Z*(+mPqJCbaB&dAuQUAuN|+qP}@@%=x1@8utCd*RK4?~YW*Pfv^;J#=Jb82Z^c+dl|C8D2=HTtM?NtD&oxT<*c47 z6!T8g9vhpO^vvk8hWFthBhvimC~hPUtdQT)P`_E(q%HlzCqBJqc!d!0 zfK=H-=_96I9JW{e=>cRpc-(ARYmL z`o>>?AygdaNb+t?f0P$0NgfIOe%t!2@2y7Do*c6Pp#PSPD|D=mEzUKr%(6pO-4)6Ky4<7%cNB``9{Ouq9 z{jSGDQin?6JpQeC5TH<0p)aqRBEJR};kN)X`8T*%CDw{t)IO zOs3HH7bedf89A|g*PhXRr+Sw3bQW9rki*+S5mzb|*REN;Zrz%Jfj(4o_!gyKxEQz> zJtUNU_^8p2%+mJ7f{vyW_fwBBRiY{{xAeB*yRrA{?^sPM8c-RJ9E*!h3G>?{M=OBL$B?7_3wTtFU@upTeFHD zpU1*XNFt1KD1lN6WfPV63sTc|V*L1?y}M5AInmaWZ_T#If~;v;e}C_T58T(^-)9&X zo2Bx6@cE$aL**x-`2&tL^z6U{lH%Dnea{ZO_w@~u5jE7og_Z5w{>Kj;J&bx)Xpz7_ zKOOP)!PGcvbB~TMJ(&CX|LvFV>RInM+;XK_sZ?iX%BX4*NrPg>KL=Dc)KKNP3sUL<@6P$**}q&pak9(>!;s#5g; z)$PrrAHs2tqCT&xPjP(eHu&yF$9^~n29wnVLs50oH&J9YtBGj1AwWxkxff_oVp&$u zPNE62nxt%ElX703JytvY#LLhA^#GcHu5*i{yIy+P?JtwAnQdiAWM?IPmNLDob9DCF^%=5W!ZghP^wRRMe)xh+_ z66kF5%paI1W#!G0`pY}FkBy&>1~q?H+)?6 zEu-;L6l%o9@{J@&+*KC!hwE6VaPYOp!WcK#{pPlPJOAo${&pL8wE4+wbWa{SWy&P@ zgZPHy-?NLzLq>phIqZ}wr)Me$CbN>>JJ4&0)TWc<2TUnR)==LhRUl|h$UmT94Akpo z4t*w$vjy>_s(xS5o}99_?>#iR>kY4Oee}>BwL5RCtyo^^=oppN-I8>W=g0A2ytF8y z&U)$h&mpdZp~@RfR!Vw8&5Yk7gpSL+wJ*CuhkmWxbmh_tyPIygBqw3#e;v(TTIh(9ZE;M z2r`X|qN*w?@AUk5_6TJc(GuQx?p zE>OQ5dGepJ;J)u758*Tx&bEy;i^>bgq0Y>c0Za% zCq(DNt@m&b-|MYf-pm&!(5g!EyP|jiWso3@3gQIMPw{-2=V%J=2r!?g^&EJS)G{Tj zf#;yOp(~F`oT}tQeDU=80^%Ew(#o5QH6seV(2;GOv1_Lfjf{^?L|bw+=_W$w=4i~+ zpN|fhrOktDmbCVwvsJ6r$`w>KwX+H)?QVm*^aG3Mp`r>=(5R|n(2NoWemGa(;Em$N z<29gzfWL<~cq^GL#`S=&E9O&tAMouy*C5O}iu$aqyetS~$!g#)LviD|TawiU12Y0u z<;F&JVG5DUgBL>q`O!pEwK`9NCZrT0LwyM!{_Vp%zx~t`uN>bNd^8jJ90hG33m_CA z!@*bs-fhCJCK>7jChRw%0#KA-Pz?(F>2L1M<#W9qT^)tC4_GmBedCHEsxYiRWHh3D}?|GAf6{N^i9O?I1MP=)VR z;fXTrb3n+zun1fTZ;ZoNPQur#@bV1Q6=+eQBQ8GsRj3B$k%~MM-ErIP5(Uzr{D4Xn zi&9J`%p~|1ttaLgiYSBE6ssJ}MO4IIV+vwvZ3^NkMSWf~{!Y~%sO zl`_9LGl|iD!_& zkJM9YL4qzaZVD*BN-Dk^mnu-N8_ck-W_(qa-{H8V%@=doBd&9A7`Df&3kPOHpSqq< z9-n;$?L2|D1s}VSEhPc^sQ$#Kxcqcs7t8fn9H0yJx8L~si>J0#dz=Uh!9SaXXJ_EB z4`}3vMA$Y4e?0+@&A`hQc&Q9ePm#H9Q(;(w9tEbn`o5`dt##G1G8$KtH9H3E38s2MMaL)FYQDJCCUNdrWwT;(olr6K4dOY2IK1VC3p7`GPU)=FZ z@PGX~dw)v~w|_o{jpO9erYC|x3;WTKg>$O*pGo0*rh6|;7H^7Q1fvFNTm zb!HNPoAiVyX7b1Q^?fU{g3+v-NqtQEohyM?D~Y0}Yo$`DqobYX1l2VxuRf@6P};h- zY2$0a#0}#Nm|1lrXJlK@(zy0q2BA0$$9bZ(GtRBYk_}NLS(=n`JWB>G{nclzj8|NQUwl}5rP8TcCs{$vn- zxed4`9IQZRJ8aCskF~>3cEV3}!jHE>w+m}qU|5HI+$pC+Zag*88fFLA47VBY$EW=u zi3LL|jaH88mZ-BqGO+xT*LLG`o=q2C6@CW(V5^TMb@4hNL7XdQU(fFE~p#XJxv z6E(`5eW_?u;9E_KsEb0!b8OV8xS7<%tnZ8GXHb-6^Z$pQ`BSu*9ACpMpYEgK7`>MD z*;?hlR%iaWUilAZ^XFaX{(!{j1)fR-oQKJZjvUWtBzaKPBP08mrvH16`)iIf(VNAm zhfhAPq2Ui4IP~prfA7nG^Ocuhd3|K`l;zkFN45!t8pb|kNO@^{eESvIdkIhiS&$@1+Rw! zUicmwwAk6p#|_*!D>r=o4N%uGbehprquQN)F>p2pXFii!qsx~_@u*%faYGcCT0Brj-qHoc(upwMl{E$I;#F@JfARafe)z)CH@1!M-8Xsk-QDlK_QI?0?s#{iGOpzm zndbwVSKLLhqZxTjCKMKU?rK8 zmeibh*$L0j1@AXLuRn zi;+=LlGkU}(F?^#f5xC)65DoOc>d)b(+A7zA~MT+Ex0`gMgVVHa8!T~7a)Vl86RqS zaH<9;Ramd3eF@Mc=sdUEY$>b5+1~YQR>#L(4lHg+{>IZg;G>J3B9g;%{e~_UcHrlD%R(T&ABw7hIpOlROw|Z9 zdPc{W5_3!FQ-86f88toP61?%+TRX-NO!Pa^9XYC0px(rFc*lXMEPOEo*|@N@d>CoK z+f~>p!^$k&ai$VW;yBbd$D%>M{mwgY$DhY-bRlt-rfZuQboHS85qP)}Z;C2Bw2VLv zK$vGP-s6=jRK(-5@|LPSsc272($2FrYWO=*m_rfcI`=yEXI%Tiz(?UC;g`@g48yj- zU*dafd~axOOZvn*)Vq;-aGAAgEbo02&LB>`F*f{D47JS-h@hIz&cED`tI5yh$ zS@rjKZ2N_0U)tx5)HVvRM1heyOoVU}#SIVH417d=zYS)_hWEzUG@U4Ejatv~MgT>d@ghCNA@Bng#K=C}UBY zX7w=4gh9XWuZW@r&6DVGBlrO`z~yh5NiJ}((2K?|}Pc?q|d#~;MFTbk!FML*ja{iCk%f9VhY?ZCt*#OJ2A{nqdN&fopuTZcxE zIn=8ueHy4H(R3zNBeJZb7RNh`Z#1345EV?Rt+?^d4f1XW%07&`%ITMTG( zpW&RpAq&P0uWypxB-LqrE#5Cp=LbPJCQ3Wg6*2(>p0_rNsBR$Lv_Rmy zM6uw)OZQq$h;@P?s|Fqwi=nG{K2+NI9A{ELSz=Qs{F{~Vn{9CH06cG!i-5H0@VR05 z$_5y&!1giNevWW)Le7p*-k*IqDDdmmsb-^`l=K$`b2Y`~w3>K>nBz4)hnJD=ixGrV zy8dW3|L;}fQC^rrxs&dQ@x9f}#;?_@|G}|8enne}4+jkjULJZ(VIbh+LG4wqPE==( zH)><9V}xOLym9hd?|kLA{#ki3&$UyIKGzohn}O<2 z=l}Bm{fnSVP%-l$I5RwJHn)5ny_=G#bg#+@4q`TT~JYvhpt z##}gJ8B^TA$^l8aLjNjFQ#;z*QO~SiwQ}Xk6{}XQShaG+;F2YAn-tBkksfzh@D=h< z-^3I3;Z>zu8H<}ZQ}_W55$6P&d~FV0xPYb#S6}A1)Z-6>4#$4@Mmm+_IM?H5L zyELz$f;4h1My7}!-8E%EPLgCEwb@Jqw%6dh68ym$`0fxaGvO;oVDFjkh)oklZ5YkP zoeknGXE8(GMbmn9Wj)#r3N~1;pjnFx->Z;EHx4&}zM(NxaU|AxRgpYj6T~B8+S{K9 z{3V{dK3!QTC`(fCw=0VqUJz6*C(}F$fo;|(M(x$;n?iqUM%H261vmbd#M7jY-6|~4 zQe*`y-iTMC3e%Y;g|BE>IX-5>HnYiSe zfR}-$#K^X2nF0zxd@SgQ)GL!_qwG0o=8CR!d*FX$%5Ht>&F#PcA0HcgDDQo-BU)p` z@v`Fnzxd$KU8tuXL|t<5*_P(dwLJdZ51#$O?@vTe;>#FCei+d_P-sA1$1Gjfuop#7i@h}7Zc>flA8ZF#3+ z39zRD<2I}^s1~QF!0HSPsIbEV7cCUPxC5q3-EnA|nfRLtUc`;LhM?xVFE@DVqQtI| zjouL&TP$cYIT~=6?z>623G@vbWqi20k(X5iZFIVIt`USIf_R+c(hg{G1ILme=ucJ` z5+AdpWBL>&?~)mk#DSiZReYBLOD{B1XsxbFV)qXAv>PSc1&d_V zJ$Q|He{_SMgLe@Rv7S=Y=ZwssXxcYq{M~qVgs zy=uk4K!00XYd)7VbX}HbTW51Fbo&&DJtSE)mu@=a<_0CXV>K+ZhA%40_p4FNmqQc} zN%GrhO7PXg)iCVv{gpw`j)o&SVBx@*o~CF+zk{ZuNv>xhL0g1n7WMuCNXC3zgN_s> zap~%%IbY?+e3%TN5|F!v5(W+O`!!M??DAn34_oBaN+b9$rs=qgwz@^hcMbNW+ph)` zh4>WFQlUjfKTXxL*Hi`dBjYB}Hz-G``=)B3ua6cw-8$EZ@@~{O=?Yce^auVx6z0

;ogB(N9UfJgjXlvnMrtJ3SO+k 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 z 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 literal 168903 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 z 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 z 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�ma3q&`?5Fn+|1E(A?El-^%`czq zn>TIQu1!sQ&OCnU*)DYGu<{>=`*!zs|Eamt%vAfWmBpo%{rJ%qb@|ToHnRicX5GIS z<^B5o1A`BJ{btsG_A|bJf8v08u*$n^#p$1>9{C&c^vH&26ZPx=%|Q|WpW(x&3l@u) z?fSIo(VjbNjDe+K+7dZWf6JOz6{mm)XgPkLnmRp7O1obo=KQlJ1XSKgUXfq zp3*sjGin!1XW1zGLVYruMsA3gwM!9jd0X)YX|o3c&69HObvxV%1KYx;wBhm0xrbl0 zx max_points: - step = int(math.ceil((float(num_points) / max_points))) - shorter = [messages[i] for i in xrange(0, num_points, step)] - messages = shorter - return messages + keep_point_distance=3 #metres + kept_messages = [] + kept_messages.append(messages[0]) #Keep the first message + pt1num=0 + pt2num=1 + while True: + #Keep the last point. Only record 99 points. + if pt2num==num_points-1 or len(kept_messages)==99: + kept_messages.append(messages[pt2num]) + break + pt1 = LocationGlobalRelative(messages[pt1num].lat/1.0e7,messages[pt1num].lon/1.0e7,0) + pt2 = LocationGlobalRelative(messages[pt2num].lat/1.0e7,messages[pt2num].lon/1.0e7,0) + distance_between_points = get_distance_metres(pt1,pt2) + if distance_between_points > keep_point_distance: + kept_messages.append(messages[pt2num]) + pt1num=pt2num + pt2num=pt2num+1 + + return kept_messages def arm_and_takeoff(aTargetAltitude): From ef2a8ac7d61e8aa98312455781def77e22d73c5a Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 12 Feb 2016 16:06:01 +1100 Subject: [PATCH 310/475] Fix windows style slashes in cd path in examples --- docs/examples/running_examples.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/examples/running_examples.rst b/docs/examples/running_examples.rst index 4fd710a46..3c20422c6 100644 --- a/docs/examples/running_examples.rst +++ b/docs/examples/running_examples.rst @@ -26,13 +26,13 @@ To run the examples: #. Navigate to the example you wish to run (or specify the full path in the next step). The examples are all stored in - subdirectories of **dronekit-python\\examples\\**. + subdirectories of **dronekit-python/examples/**. For example, to run the :ref:`vehicle_state ` example, you would navigate as shown: .. code-block:: bash - cd dronekit-python\examples\vehicle_state\ + cd dronekit-python/examples/vehicle_state/ #. Start the example as shown: From 58d82a47ac46bf0e0f9fc8a1720aa85ed0c74000 Mon Sep 17 00:00:00 2001 From: sander Date: Wed, 17 Feb 2016 20:40:28 +0100 Subject: [PATCH 311/475] Check if mode_mapping has items before iteration --- dronekit/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 4554482a5..3391824e4 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1161,7 +1161,8 @@ def listener(self, name, m): def listener(self, name, m): self._armed = (m.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED) != 0 self.notify_attribute_listeners('armed', self.armed, cache=True) - self._flightmode = {v: k for k, v in self._master.mode_mapping().items()}[m.custom_mode] + if self._master.mode_mapping() != None: + self._flightmode = {v: k for k, v in self._master.mode_mapping().items()}[m.custom_mode] self.notify_attribute_listeners('mode', self.mode, cache=True) self._system_status = m.system_status self.notify_attribute_listeners('system_status', self.system_status, cache=True) From 09496ed494ebe867f31eda00a11cd7ed4c491341 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 16 Feb 2016 11:00:06 +1100 Subject: [PATCH 312/475] Improve description of dronekit on PyPi --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 4f657e5d5..51562f65b 100644 --- a/setup.py +++ b/setup.py @@ -6,8 +6,8 @@ setup(name='dronekit', zip_safe=True, version=version, - description='Python language bindings for the DroneApi', - long_description='Python language bindings for the DroneApi', + description='Developer Tools for Drones.', + long_description='Python API for communication and control of drones over MAVLink.', url='https://github.com/dronekit/dronekit-python', author='3D Robotics', install_requires=[ From ac9c7545330402e9bb7dfe3c24234c29bdbb5c87 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 19 Feb 2016 12:53:48 +1100 Subject: [PATCH 313/475] Correct addition and removal of capabilities request HEARBTEAT listener --- dronekit/__init__.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 3391824e4..596835ef9 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -991,9 +991,6 @@ def __init__(self, handler): self._handler = handler self._master = handler.master - # a message listener to set Autopilot version and capabilties: - self.listener_capa = None - # Cache all updated attributes for wait_ready. # By default, we presume all "commands" are loaded. self._ready_attrs = set(['commands']) @@ -1079,8 +1076,7 @@ def listener(self, name, m): def listener(vehicle, name, m): self._capabilities = m.capabilities self._raw_version = m.flight_sw_version - if self.listener_capa is not None: - self.remove_attribute_listener('HEARTBEAT', self.listener_capa) + vehicle.remove_message_listener('HEARTBEAT', self.send_capabilties_request) self.notify_attribute_listeners('autopilot_version', self._raw_version) # gimbal @@ -1751,7 +1747,6 @@ def airspeed(self, speed): # send command to vehicle self.send_mavlink(msg) - @property def gimbal(self): """ @@ -2062,12 +2057,7 @@ def initialize(self, rate=4, heartbeat_timeout=30): self._master.mav.request_data_stream_send(0, 0, mavutil.mavlink.MAV_DATA_STREAM_ALL, rate, 1) - #Request an AUTOPILOT_VERSION packet - def send_capabilties_request(vehicle, name, m): - capability_msg = self.message_factory.command_long_encode(0, 0, mavutil.mavlink.MAV_CMD_REQUEST_AUTOPILOT_CAPABILITIES, 0, 1, 0, 0, 0, 0, 0, 0) - self.send_mavlink(capability_msg) - - self.listener_capa = self.add_message_listener('HEARTBEAT', send_capabilties_request) + self.add_message_listener('HEARTBEAT', self.send_capabilties_request) # Ensure initial parameter download has started. while True: @@ -2078,6 +2068,11 @@ def send_capabilties_request(vehicle, name, m): if self._params_count > -1: break + def send_capabilties_request(self, vehicle, name, m): + '''Request an AUTOPILOT_VERSION packet''' + capability_msg = vehicle.message_factory.command_long_encode(0, 0, mavutil.mavlink.MAV_CMD_REQUEST_AUTOPILOT_CAPABILITIES, 0, 1, 0, 0, 0, 0, 0, 0) + vehicle.send_mavlink(capability_msg) + def wait_ready(self, *types, **kwargs): """ Waits for specified attributes to be populated from the vehicle (values are initially ``None``). From 010aedf4c4b5f1c2042f4c3a68f144965430fdf1 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 19 Feb 2016 14:34:10 +1100 Subject: [PATCH 314/475] Wait for capabilities to be set by ArduPilot <3.3 --- dronekit/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 596835ef9..d790e414e 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1076,7 +1076,10 @@ def listener(self, name, m): def listener(vehicle, name, m): self._capabilities = m.capabilities self._raw_version = m.flight_sw_version - vehicle.remove_message_listener('HEARTBEAT', self.send_capabilties_request) + if self._capabilities != 0: + # ArduPilot <3.4 fails to send capabilities correctly + # straight after boot. + vehicle.remove_message_listener('HEARTBEAT', self.send_capabilties_request) self.notify_attribute_listeners('autopilot_version', self._raw_version) # gimbal From 9fbfd77b854a0fafef2421e1bd3cfbe7254bd066 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 18 Feb 2016 15:04:29 -0800 Subject: [PATCH 315/475] Fixes test_goto with empty waypoint list. --- dronekit/__init__.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index d790e414e..7c56a4cbd 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -2605,7 +2605,11 @@ def clear(self): # Add home point again. self.wait_ready() - home = self._vehicle._wploader.wp(0) + home = None + try: + home = self._vehicle._wploader.wp(0) + except: + pass self._vehicle._wploader.clear() if home: self._vehicle._wploader.add(home, comment='Added by DroneKit') From 144825e4eddc78db53117907143f89643d8479fa Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 18 Feb 2016 15:05:32 -0800 Subject: [PATCH 316/475] Splits outbound messages into its own thread. --- dronekit/__init__.py | 6 ++-- dronekit/mavlink.py | 75 +++++++++++++++++++++++++++++++------------- 2 files changed, 57 insertions(+), 24 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 7c56a4cbd..edec2b7f7 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -2705,7 +2705,8 @@ def connect(ip, rate=4, baud=115200, heartbeat_timeout=30, - source_system=255): + source_system=255, + use_native=False): """ Returns a :py:class:`Vehicle` object connected to the address specified by string parameter ``ip``. Connection string parameters (``ip``) for different targets are listed in the :ref:`getting started guide `. @@ -2741,6 +2742,7 @@ def connect(ip, :param int heartbeat_timeout: Connection timeout value in seconds (default is 30s). If a heartbeat is not detected within this time an exception will be raised. :param int source_system: The MAVLink ID of the :py:class:`Vehicle` object returned by this method (by default 255). + :param bool use_native: Use precompiled MAVLink parser. .. note:: @@ -2759,7 +2761,7 @@ def connect(ip, if not vehicle_class: vehicle_class = Vehicle - handler = MAVConnection(ip, baud=baud, source_system=source_system) + handler = MAVConnection(ip, baud=baud, source_system=source_system, use_native=use_native) vehicle = vehicle_class(handler) if status_printer: diff --git a/dronekit/mavlink.py b/dronekit/mavlink.py index 1986a4217..a0e6f6697 100644 --- a/dronekit/mavlink.py +++ b/dronekit/mavlink.py @@ -21,6 +21,11 @@ class MAVWriter(object): + """ + Indirection layer to take messages written to MAVlink and send them all + on the same thread. + """ + def __init__(self, queue): self.queue = queue @@ -33,7 +38,7 @@ def read(self): class MAVConnection(object): - def __init__(self, ip, baud=115200, target_system=0, source_system=255): + def __init__(self, ip, baud=115200, target_system=0, source_system=255, use_native=False): self.master = mavutil.mavlink_connection(ip, baud=baud, source_system=source_system) # TODO get rid of "master" object as exposed, @@ -42,7 +47,7 @@ def __init__(self, ip, baud=115200, target_system=0, source_system=255): self.master.mav = mavutil.mavlink.MAVLink( MAVWriter(self.out_queue), srcSystem=self.master.source_system, - use_native=False) + use_native=use_native) # Monkey-patch MAVLink object for fix_targets. sendfn = self.master.mav.send @@ -72,7 +77,42 @@ def onexit(): atexit.register(onexit) - def mavlink_thread(): + def mavlink_thread_out(): + # Huge try catch in case we see http://bugs.python.org/issue1856 + try: + while self._alive: + try: + msg = self.out_queue.get(True, timeout=0.01) + self.master.write(msg) + except Empty: + continue + except socket.error as error: + # If connection reset (closed), stop polling. + if error.errno == ECONNABORTED: + raise APIException('Connection aborting during read') + raise + except Exception as e: + errprinter('>>> mav send error:', e) + break + except APIException as e: + errprinter('>>> ' + str(e.message)) + self._alive = False + self.master.close() + self._death_error = e + + except Exception as e: + # http://bugs.python.org/issue1856 + if not self._alive: + pass + else: + self._alive = False + self.master.close() + self._death_error = e + + # Explicitly clear out buffer so .close closes. + self.out_queue = Queue() + + def mavlink_thread_in(): # Huge try catch in case we see http://bugs.python.org/issue1856 try: while True: @@ -83,21 +123,6 @@ def mavlink_thread(): for fn in self.loop_listeners: fn(self) - while True: - try: - msg = self.out_queue.get_nowait() - self.master.write(msg) - except socket.error as error: - # If connection reset (closed), stop polling. - if error.errno == ECONNABORTED: - raise APIException('Connection aborting during read') - raise - except Empty: - break - except Exception as e: - errprinter('>>> mav send error:', e) - break - while self._accept_input: try: msg = self.master.recv_msg() @@ -140,9 +165,13 @@ def mavlink_thread(): self.master.close() self._death_error = e - t = Thread(target=mavlink_thread) + t = Thread(target=mavlink_thread_in) + t.daemon = True + self.mavlink_thread_in = t + + t = Thread(target=mavlink_thread_out) t.daemon = True - self.mavlink_thread = t + self.mavlink_thread_out = t def reset(self): self.out_queue = Queue() @@ -173,8 +202,10 @@ def forward_message(self, fn): self.message_listeners.append(fn) def start(self): - if not self.mavlink_thread.is_alive(): - self.mavlink_thread.start() + if not self.mavlink_thread_in.is_alive(): + self.mavlink_thread_in.start() + if not self.mavlink_thread_out.is_alive(): + self.mavlink_thread_out.start() def close(self): # TODO this can block forever if parameters continue to be added From a38cee6aad1cd1fead81a1f01e70951b0009b826 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 18 Feb 2016 15:29:20 -0800 Subject: [PATCH 317/475] Adds sanity check to packet forwarding. --- dronekit/mavlink.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dronekit/mavlink.py b/dronekit/mavlink.py index a0e6f6697..b4076b22d 100644 --- a/dronekit/mavlink.py +++ b/dronekit/mavlink.py @@ -220,13 +220,19 @@ def pipe(self, target): # vehicle -> self -> target @self.forward_message def callback(_, msg): - target.out_queue.put(msg.pack(target.master.mav)) + try: + target.out_queue.put(msg.pack(target.master.mav)) + except: + errprinter('>>> Could not pack this object on receive: %s' % type(msg)) # target -> self -> vehicle @target.forward_message def callback(_, msg): msg = copy.copy(msg) target.fix_targets(msg) - self.out_queue.put(msg.pack(self.master.mav)) + try: + self.out_queue.put(msg.pack(self.master.mav)) + except: + errprinter('>>> Could not pack this object on forward: %s' % type(msg)) return target From 02aeab574502ef8b723a087119d2f8d3c234f6ba Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Thu, 18 Feb 2016 15:49:23 -0800 Subject: [PATCH 318/475] Attempts to fix forwarding issues using mavnative. --- dronekit/mavlink.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/dronekit/mavlink.py b/dronekit/mavlink.py index b4076b22d..c60b0d90e 100644 --- a/dronekit/mavlink.py +++ b/dronekit/mavlink.py @@ -223,7 +223,11 @@ def callback(_, msg): try: target.out_queue.put(msg.pack(target.master.mav)) except: - errprinter('>>> Could not pack this object on receive: %s' % type(msg)) + try: + assert len(msg.get_msgbuf()) > 0 + target.out_queue.put(msg.get_msgbuf()) + except: + errprinter('>>> Could not pack this object on receive: %s' % type(msg)) # target -> self -> vehicle @target.forward_message @@ -233,6 +237,10 @@ def callback(_, msg): try: self.out_queue.put(msg.pack(self.master.mav)) except: - errprinter('>>> Could not pack this object on forward: %s' % type(msg)) + try: + assert len(msg.get_msgbuf()) > 0 + self.out_queue.put(msg.get_msgbuf()) + except: + errprinter('>>> Could not pack this object on forward: %s' % type(msg)) return target From 42244b5edc4a9d32fd3c9dda41eeeaa320c5422b Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 19 Feb 2016 18:00:35 +1100 Subject: [PATCH 319/475] Avoid item-not-in-list exception This happens if you attempt to remove a listener if is registered --- dronekit/__init__.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index edec2b7f7..dd7ab8252 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1452,9 +1452,10 @@ def remove_message_listener(self, name, fn): """ name = str(name) if name in self._message_listeners: - self._message_listeners[name].remove(fn) - if len(self._message_listeners[name]) == 0: - del self._message_listeners[name] + if fn in self._message_listeners[name]: + self._message_listeners[name].remove(fn) + if len(self._message_listeners[name]) == 0: + del self._message_listeners[name] def notify_message_listeners(self, name, msg): for fn in self._message_listeners.get(name, []): From 7f2b68aefe9d0a7f4c19e6fe7d0646f74c4feb95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Roche?= Date: Thu, 18 Feb 2016 23:48:32 -0800 Subject: [PATCH 320/475] bump release to 2.2.0 --- docs/conf.py | 4 ++-- setup.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index bdb723a8d..81d918138 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -49,9 +49,9 @@ # built documents. # # The short X.Y version. -version = '2.1' +version = '2.2' # The full version, including alpha/beta/rc tags. -release = '2.1' +release = '2.2' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/setup.py b/setup.py index 4f657e5d5..e567fa77e 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.1.0' +version = '2.2.0' setup(name='dronekit', zip_safe=True, From 14f270f0964b2e3ba8924ca9c58416655be34405 Mon Sep 17 00:00:00 2001 From: sander Date: Thu, 18 Feb 2016 14:19:46 +0100 Subject: [PATCH 321/475] Validate existence of custom_mode before setting --- dronekit/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index dd7ab8252..57833d297 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1161,7 +1161,8 @@ def listener(self, name, m): self._armed = (m.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED) != 0 self.notify_attribute_listeners('armed', self.armed, cache=True) if self._master.mode_mapping() != None: - self._flightmode = {v: k for k, v in self._master.mode_mapping().items()}[m.custom_mode] + if m.custom_mode in {v: k for k, v in self._master.mode_mapping().items()}: + self._flightmode = {v: k for k, v in self._master.mode_mapping().items()}[m.custom_mode] self.notify_attribute_listeners('mode', self.mode, cache=True) self._system_status = m.system_status self.notify_attribute_listeners('system_status', self.system_status, cache=True) From d5eeb468e3f2061d7fd81637c7a3d0a1b54fe3ea Mon Sep 17 00:00:00 2001 From: sander Date: Thu, 18 Feb 2016 22:17:12 +0100 Subject: [PATCH 322/475] Avoid double evaluation --- dronekit/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 57833d297..db2b5039b 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1161,8 +1161,9 @@ def listener(self, name, m): self._armed = (m.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED) != 0 self.notify_attribute_listeners('armed', self.armed, cache=True) if self._master.mode_mapping() != None: - if m.custom_mode in {v: k for k, v in self._master.mode_mapping().items()}: - self._flightmode = {v: k for k, v in self._master.mode_mapping().items()}[m.custom_mode] + flightmodesById = {v: k for k, v in self._master.mode_mapping().items()} + if m.custom_mode in flightmodesById: + self._flightmode = flightmodesById[m.custom_mode] self.notify_attribute_listeners('mode', self.mode, cache=True) self._system_status = m.system_status self.notify_attribute_listeners('system_status', self.system_status, cache=True) From dc30747c33cb7ca95f93cb950df1769928306bd1 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 23 Feb 2016 13:01:02 +1100 Subject: [PATCH 323/475] Remove requests as a dependency from setup.py --- setup.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 33ba9be0e..241253352 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.2.0' +version = '2.2.1' setup(name='dronekit', zip_safe=True, @@ -12,7 +12,6 @@ author='3D Robotics', install_requires=[ 'pymavlink>=1.1.62', - 'requests>=2.5.0,<=2.99999', ], author_email='tim@3drobotics.com, kevinh@geeksville.com', classifiers=[ From 9515f558b4d51fbea4c0a5f2ef6c3c39cb6ce534 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 24 Feb 2016 08:49:27 +1100 Subject: [PATCH 324/475] Fix typo in GPS VDOP description --- dronekit/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index db2b5039b..12d1f3890 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -191,7 +191,7 @@ class GPSInfo(object): If there is no GPS lock the parameters are set to ``None``. :param Int eph: GPS horizontal dilution of position (HDOP). - :param Int epv: GPS horizontal dilution of position (VDOP). + :param Int epv: GPS vertical dilution of position (VDOP). :param Int fix_type: 0-1: no fix, 2: 2D fix, 3: 3D fix :param Int satellites_visible: Number of satellites visible. From 6d460296a1c786b3b7db3b6d15afea0027dcd1b1 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 24 Feb 2016 14:38:13 +1100 Subject: [PATCH 325/475] Remove heartbeat listener if 5 bad AUTOPILOT_VERSIONs received Older versions of ArduPilot always send capabilities through as 0. --- dronekit/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index db2b5039b..771462e86 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1071,14 +1071,17 @@ def listener(self, name, m): self._capabilities = None self._raw_version =None + self._autopilot_version_msg_count = 0 @self.on_message('AUTOPILOT_VERSION') def listener(vehicle, name, m): self._capabilities = m.capabilities self._raw_version = m.flight_sw_version - if self._capabilities != 0: + self._autopilot_version_msg_count += 1 + if self._capabilities != 0 or self._autopilot_version_msg_count > 5: # ArduPilot <3.4 fails to send capabilities correctly - # straight after boot. + # straight after boot, and even older versions send + # this back as always-0. vehicle.remove_message_listener('HEARTBEAT', self.send_capabilties_request) self.notify_attribute_listeners('autopilot_version', self._raw_version) From 29d81b058f247f458e323f21104862f83c39861c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Roche?= Date: Fri, 19 Feb 2016 16:24:09 -0800 Subject: [PATCH 326/475] whitespace killer! --- dronekit/__init__.py | 628 +++++++++++++++++++++---------------------- 1 file changed, 314 insertions(+), 314 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 339ec2b91..0522ed2ff 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -23,7 +23,7 @@ Velocity-based movement and control over other vehicle features can be achieved using custom MAVLink messages (:py:func:`Vehicle.send_mavlink`, :py:func:`Vehicle.message_factory`). -It is also possible to work with vehicle "missions" using the :py:attr:`Vehicle.commands` attribute, and run them in AUTO mode. +It is also possible to work with vehicle "missions" using the :py:attr:`Vehicle.commands` attribute, and run them in AUTO mode. A number of other useful classes and methods are listed below. @@ -63,11 +63,11 @@ def __init__(self, message): class Attitude(object): """ Attitude information. - + An object of this type is returned by :py:attr:`Vehicle.attitude`. .. _figure_attitude: - + .. figure:: http://upload.wikimedia.org/wikipedia/commons/thumb/c/c1/Yaw_Axis_Corrected.svg/500px-Yaw_Axis_Corrected.svg.png :width: 400px :alt: Diagram showing Pitch, Roll, Yaw @@ -103,8 +103,8 @@ class LocationGlobal(object): LocationGlobal(-34.364114, 149.166022, 30) .. todo:: FIXME: Location class - possibly add a vector3 representation. - - An object of this type is owned by :py:attr:`Vehicle.location`. See that class for information on + + An object of this type is owned by :py:attr:`Vehicle.location`. See that class for information on reading and observing location in the global frame. :param lat: Latitude. @@ -139,8 +139,8 @@ class LocationGlobalRelative(object): LocationGlobalRelative(-34.364114, 149.166022, 30) .. todo:: FIXME: Location class - possibly add a vector3 representation. - - An object of this type is owned by :py:attr:`Vehicle.location`. See that class for information on + + An object of this type is owned by :py:attr:`Vehicle.location`. See that class for information on reading and observing location in the global-relative frame. :param lat: Latitude. @@ -166,8 +166,8 @@ class LocationLocal(object): A local location object. The north, east and down are relative to the EKF origin. This is most likely the location where the vehicle was turned on. - - An object of this type is owned by :py:attr:`Vehicle.location`. See that class for information on + + An object of this type is owned by :py:attr:`Vehicle.location`. See that class for information on reading and observing location in the local frame. :param north: Position north of the EKF origin in meters. @@ -211,7 +211,7 @@ def __str__(self): class Battery(object): """ System battery information. - + An object of this type is returned by :py:attr:`Vehicle.battery`. :param voltage: Battery voltage in millivolts. @@ -238,7 +238,7 @@ def __str__(self): class Rangefinder(object): """ Rangefinder readings. - + An object of this type is returned by :py:attr:`Vehicle.rangefinder`. :param distance: Distance (metres). ``None`` if the vehicle doesn't have a rangefinder. @@ -257,10 +257,10 @@ class Version(object): Autopilot version and type. An object of this type is returned by :py:attr:`Vehicle.version`. - + The version number can be read in a few different formats. To get it in a human-readable format, just print `vehicle.version`. This might print something like "APM:Copter-3.3.2-rc4". - + .. versionadded:: 2.0.3 .. py:attribute:: major @@ -307,7 +307,7 @@ def is_stable(self): def release_version(self): """ - Returns the version within the release type (an integer). + Returns the version within the release type (an integer). This method returns "23" for Copter-3.3rc23. """ if self.release is None: @@ -357,16 +357,16 @@ def __str__(self): class Capabilities: """ - Autopilot capabilities (supported message types and functionality). - + Autopilot capabilities (supported message types and functionality). + An object of this type is returned by :py:attr:`Vehicle.capabilities`. - - See the enum + + See the enum `MAV_PROTOCOL_CAPABILITY `_. - + .. versionadded:: 2.0.3 - - + + .. py:attribute:: mission_float Autopilot supports MISSION float message type (Boolean). @@ -383,7 +383,7 @@ class Capabilities: Autopilot supports COMMAND_INT scaled integer message type (Boolean). - .. py:attribute:: param_union + .. py:attribute:: param_union Autopilot supports the PARAM_UNION message type (Boolean). @@ -402,7 +402,7 @@ class Capabilities: .. py:attribute:: set_altitude_target_global_int Autopilot supports commanding position and velocity targets in global scaled integers (Boolean). - + .. py:attribute:: terrain Autopilot supports terrain protocol / data handling (Boolean). @@ -454,7 +454,7 @@ class VehicleMode(object): `Rover Modes `_). If an unsupported mode is set the script will raise a ``KeyError`` exception. - The :py:attr:`Vehicle.mode` attribute can be queried for the current mode. + The :py:attr:`Vehicle.mode` attribute can be queried for the current mode. The code snippet below shows how to observe changes to the mode and then read the value: .. code:: python @@ -473,7 +473,7 @@ def mode_callback(self, attr_name): # Set the vehicle into auto mode vehicle.mode = VehicleMode("AUTO") - For more information on getting/setting/observing the :py:attr:`Vehicle.mode` + For more information on getting/setting/observing the :py:attr:`Vehicle.mode` (and other attributes) see the :ref:`attributes guide `. .. py:attribute:: name @@ -497,7 +497,7 @@ def __ne__(self, other): class SystemStatus(object): """ This object is used to get and set the current "system status". - + An object of this type is returned by :py:attr:`Vehicle.system_status`. .. py:attribute:: state @@ -530,23 +530,23 @@ def add_attribute_listener(self, attr_name, observer): """ Add an attribute listener callback. - The callback function (``observer``) is invoked differently depending on the *type of attribute*. - Attributes that represent sensor values or which are used to monitor connection status are updated - whenever a message is received from the vehicle. Attributes which reflect vehicle "state" are + The callback function (``observer``) is invoked differently depending on the *type of attribute*. + Attributes that represent sensor values or which are used to monitor connection status are updated + whenever a message is received from the vehicle. Attributes which reflect vehicle "state" are only updated when their values change (for example :py:attr:`Vehicle.system_status`, :py:attr:`Vehicle.armed`, and :py:attr:`Vehicle.mode`). The callback can be removed using :py:func:`remove_attribute_listener`. - + .. note:: - - The :py:func:`on_attribute` decorator performs the same operation as this method, but with - a more elegant syntax. Use ``add_attribute_listener`` by preference if you will need to remove + + The :py:func:`on_attribute` decorator performs the same operation as this method, but with + a more elegant syntax. Use ``add_attribute_listener`` by preference if you will need to remove the observer. The argument list for the callback is ``observer(object, attr_name, attribute_value)``: - - * ``self`` - the associated :py:class:`Vehicle`. This may be compared to a global vehicle handle + + * ``self`` - the associated :py:class:`Vehicle`. This may be compared to a global vehicle handle to implement vehicle-specific callback handling (if needed). * ``attr_name`` - the attribute name. This can be used to infer which attribute has triggered if the same callback is used for watching several attributes. @@ -561,10 +561,10 @@ def location_callback(self, attr_name, msg): print "Location (Global): ", msg #Add observer for the vehicle's current location - vehicle.add_attribute_listener('global_frame', location_callback) - + vehicle.add_attribute_listener('global_frame', location_callback) + See :ref:`vehicle_state_observe_attributes` for more information. - + :param String attr_name: The name of the attribute to watch (or '*' to watch all attributes). :param observer: The callback to invoke when a change in the attribute is detected. @@ -580,13 +580,13 @@ def remove_attribute_listener(self, attr_name, observer): """ Remove an attribute listener (observer) that was previously added using :py:func:`add_attribute_listener`. - For example, the following line would remove a previously added vehicle 'global_frame' + For example, the following line would remove a previously added vehicle 'global_frame' observer called ``location_callback``: .. code:: python vehicle.remove_attribute_listener('global_frame', location_callback) - + See :ref:`vehicle_state_observe_attributes` for more information. :param String attr_name: The attribute name that is to have an observer removed (or '*' to remove an 'all attribute' observer). @@ -602,20 +602,20 @@ def remove_attribute_listener(self, attr_name, observer): def notify_attribute_listeners(self, attr_name, value, cache=False): """ This method is used to update attribute observers when the named attribute is updated. - - You should call it in your message listeners after updating an attribute with + + You should call it in your message listeners after updating an attribute with information from a vehicle message. - By default the value of ``cache`` is ``False`` and every update from the vehicle is sent to listeners - (whether or not the attribute has changed). This is appropriate for attributes which represent sensor - or heartbeat-type monitoring. - - Set ``cache=True`` to update listeners only when the value actually changes (cache the previous + By default the value of ``cache`` is ``False`` and every update from the vehicle is sent to listeners + (whether or not the attribute has changed). This is appropriate for attributes which represent sensor + or heartbeat-type monitoring. + + Set ``cache=True`` to update listeners only when the value actually changes (cache the previous attribute value). This should be used where clients will only ever need to know the value when it has changed. For example, this setting has been used for notifying :py:attr:`mode` changes. - + See :ref:`example_create_attribute` for more information. - + :param String attr_name: The name of the attribute that has been updated. :param value: The current value of the attribute that has been updated. :param Boolean cache: Set ``True`` to only notify observers when the attribute value changes. @@ -635,27 +635,27 @@ def notify_attribute_listeners(self, attr_name, value, cache=False): def on_attribute(self, name): """ Decorator for attribute listeners. - - The decorated function (``observer``) is invoked differently depending on the *type of attribute*. - Attributes that represent sensor values or which are used to monitor connection status are updated - whenever a message is received from the vehicle. Attributes which reflect vehicle "state" are + + The decorated function (``observer``) is invoked differently depending on the *type of attribute*. + Attributes that represent sensor values or which are used to monitor connection status are updated + whenever a message is received from the vehicle. Attributes which reflect vehicle "state" are only updated when their values change (for example :py:func:`Vehicle.system_status`, :py:attr:`Vehicle.armed`, and :py:attr:`Vehicle.mode`). - + The argument list for the callback is ``observer(object, attr_name, attribute_value)`` - - * ``self`` - the associated :py:class:`Vehicle`. This may be compared to a global vehicle handle + + * ``self`` - the associated :py:class:`Vehicle`. This may be compared to a global vehicle handle to implement vehicle-specific callback handling (if needed). * ``attr_name`` - the attribute name. This can be used to infer which attribute has triggered if the same callback is used for watching several attributes. * ``msg`` - the attribute value (so you don't need to re-query the vehicle object). - + .. note:: - - There is no way to remove an attribute listener added with this decorator. Use - :py:func:`add_attribute_listener` if you need to be able to remove + + There is no way to remove an attribute listener added with this decorator. Use + :py:func:`add_attribute_listener` if you need to be able to remove the :py:func:`attribute listener `. - + The code fragment below shows how you can create a listener for the attitude attribute. .. code:: python @@ -663,7 +663,7 @@ def on_attribute(self, name): @vehicle.on_attribute('attitude') def attitude_listener(self, name, msg): print '%s attribute is: %s' % (name, msg) - + See :ref:`vehicle_state_observe_attributes` for more information. :param String attr_name: The name of the attribute to watch (or '*' to watch all attributes). @@ -683,12 +683,12 @@ def decorator(fn): class ChannelsOverride(dict): """ A dictionary class for managing Vehicle channel overrides. - + Channels can be read, written, or cleared by index or using a dictionary syntax. To clear a value, set it to ``None`` or use ``del`` on the item. - + An object of this type is returned by :py:attr:`Vehicle.channels.overrides `. - + For more information and examples see :ref:`example_channel_overrides`. """ @@ -730,10 +730,10 @@ def _send(self): class Channels(dict): """ A dictionary class for managing RC channel information associated with a :py:class:`Vehicle`. - - An object of this type is accessed through :py:attr:`Vehicle.channels`. This object also stores + + An object of this type is accessed through :py:attr:`Vehicle.channels`. This object also stores the current vehicle channel overrides through its :py:attr:`overrides` attribute. - + For more information and examples see :ref:`example_channel_overrides`. """ @@ -779,37 +779,37 @@ def _update_channel(self, channel, value): def overrides(self): """ Attribute to read, set and clear channel overrides (also known as "rc overrides") - associated with a :py:class:`Vehicle` (via :py:class:`Vehicle.channels`). This is an + associated with a :py:class:`Vehicle` (via :py:class:`Vehicle.channels`). This is an object of type :py:class:`ChannelsOverride`. - + For more information and examples see :ref:`example_channel_overrides`. - + To set channel overrides: - + .. code:: python - + # Set and clear overrids using dictionary syntax (clear by setting override to none) vehicle.channels.overrides = {'5':None, '6':None,'3':500} # You can also set and clear overrides using indexing syntax vehicle.channels.overrides['2'] = 200 vehicle.channels.overrides['2'] = None - + # Clear using 'del' del vehicle.channels.overrides['3'] - + # Clear all overrides by setting an empty dictionary vehicle.channels.overrides = {} Read the channel overrides either as a dictionary or by index. Note that you'll get - a ``KeyError`` exception if you read a channel override that has not been set. + a ``KeyError`` exception if you read a channel override that has not been set. .. code:: python # Get all channel overrides print " Channel overrides: %s" % vehicle.channels.overrides # Print just one channel override - print " Ch2 override: %s" % vehicle.channels.overrides['2'] + print " Ch2 override: %s" % vehicle.channels.overrides['2'] """ return self._overrides @@ -832,11 +832,11 @@ def overrides(self, newch): class Locations(HasObservers): """ An object for holding location information in global, global relative and local frames. - - :py:class:`Vehicle` owns an object of this type. See :py:attr:`Vehicle.location` for information on + + :py:class:`Vehicle` owns an object of this type. See :py:attr:`Vehicle.location` for information on reading and observing location in the different frames. - - The different frames are accessed through the members, which are created with this object. + + The different frames are accessed through the members, which are created with this object. They can be read, and are observable. """ @@ -883,13 +883,13 @@ def listener(vehicle, name, m): def local_frame(self): """ Location in local NED frame (a :py:class:`LocationGlobalRelative`). - + This is accessed through the :py:attr:`Vehicle.location` attribute: - + .. code-block:: python - + print "Local Location: %s" % vehicle.location.local_frame - + This location will not start to update until the vehicle is armed. """ return LocationLocal(self._north, self._east, self._down) @@ -898,19 +898,19 @@ def local_frame(self): def global_frame(self): """ Location in global frame (a :py:class:`LocationGlobal`). - - The latitude and longitude are relative to the - `WGS84 coordinate system `_. + + The latitude and longitude are relative to the + `WGS84 coordinate system `_. The altitude is relative to mean sea-level (MSL). - + This is accessed through the :py:attr:`Vehicle.location` attribute: - + .. code-block:: python - + print "Global Location: %s" % vehicle.location.global_frame print "Sea level altitude is: %s" % vehicle.location.global_frame.alt - - Its ``lat`` and ``lon`` attributes are populated shortly after GPS becomes available. + + Its ``lat`` and ``lon`` attributes are populated shortly after GPS becomes available. The ``alt`` can take several seconds longer to populate (from the barometer). Listeners are not notified of changes to this attribute until it has fully populated. @@ -918,29 +918,29 @@ def global_frame(self): :py:func:`add_attribute_listener` (decorator approach shown below): .. code-block:: python - - @vehicle.on_attribute('location.global_frame') + + @vehicle.on_attribute('location.global_frame') def listener(self, attr_name, value): print " Global: %s" % value - - #Alternatively, use decorator: ``@vehicle.location.on_attribute('global_frame')``. + + #Alternatively, use decorator: ``@vehicle.location.on_attribute('global_frame')``. """ return LocationGlobal(self._lat, self._lon, self._alt) @property def global_relative_frame(self): """ - Location in global frame, with altitude relative to the home location + Location in global frame, with altitude relative to the home location (a :py:class:`LocationGlobalRelative`). - - The latitude and longitude are relative to the - `WGS84 coordinate system `_. + + The latitude and longitude are relative to the + `WGS84 coordinate system `_. The altitude is relative to :py:attr:`home location `. - + This is accessed through the :py:attr:`Vehicle.location` attribute: - + .. code-block:: python - + print "Global Location (relative altitude): %s" % vehicle.location.global_relative_frame print "Altitude relative to home_location: %s" % vehicle.location.global_relative_frame.alt """ @@ -950,37 +950,37 @@ def global_relative_frame(self): class Vehicle(HasObservers): """ The main vehicle API. - + Vehicle state is exposed through 'attributes' (e.g. :py:attr:`heading`). All attributes can be - read, and some are also settable + read, and some are also settable (:py:attr:`mode`, :py:attr:`armed` and :py:attr:`home_location`). - + Attributes can also be asynchronously monitored for changes by registering listener callback - functions. + functions. - Vehicle "settings" (parameters) are read/set using the :py:attr:`parameters` attribute. + Vehicle "settings" (parameters) are read/set using the :py:attr:`parameters` attribute. Parameters can be iterated and are also individually observable. - + Vehicle movement is primarily controlled using the :py:attr:`armed` attribute and :py:func:`simple_takeoff` and :py:func:`simple_goto` in GUIDED mode. It is also possible to work with vehicle "missions" using the :py:attr:`commands` attribute, - and run them in AUTO mode. - - The guide contains more detailed information on the different ways you can use + and run them in AUTO mode. + + The guide contains more detailed information on the different ways you can use the ``Vehicle`` class: - + - :doc:`guide/vehicle_state_and_parameters` - :doc:`guide/copter/guided_mode` - :doc:`guide/auto_mode` - + .. note:: - - This class currently exposes just the attributes that are most commonly used by all - vehicle types. if you need to add additional attributes then subclass ``Vehicle`` + + This class currently exposes just the attributes that are most commonly used by all + vehicle types. if you need to add additional attributes then subclass ``Vehicle`` as demonstrated in :doc:`examples/create_attribute`. - + Please then :doc:`contribute ` your additions back to the project! """ @@ -1241,7 +1241,7 @@ def listener(_): # Check the time duration for last "new" params exceeds watchdog. if not self._params_start: return - + if None not in self._params_set and not self._params_loaded: self._params_loaded = True self.notify_attribute_listeners('parameters', self.parameters) @@ -1334,17 +1334,17 @@ def listener(_): def last_heartbeat(self): """ Time since last MAVLink heartbeat was received (in seconds). - + The attribute can be used to monitor link activity and implement script-specific timeout handling. - + For example, to pause the script if no heartbeat is received for more than 1 second you might implement the following observer, and use ``pause_script`` in a program loop to wait until the link is recovered: - + .. code-block:: python - + pause_script=False - - @vehicle.on_attribute('last_heartbeat') + + @vehicle.on_attribute('last_heartbeat') def listener(self, attr_name, value): global pause_script if value > 1 and not pause_script: @@ -1352,49 +1352,49 @@ def listener(self, attr_name, value): pause_script=True; if value < 1 and pause_script: pause_script=False; - print "Un-pausing script" + print "Un-pausing script" The observer will be called at the period of the messaging loop (about every 0.01 seconds). Testing - on SITL indicates that ``last_heartbeat`` averages about .5 seconds, but will rarely exceed 1.5 seconds + on SITL indicates that ``last_heartbeat`` averages about .5 seconds, but will rarely exceed 1.5 seconds when connected. Whether heartbeat monitoring can be useful will very much depend on the application. - - - .. note:: - - If you just want to change the heartbeat timeout you can modify the ``heartbeat_timeout`` + + + .. note:: + + If you just want to change the heartbeat timeout you can modify the ``heartbeat_timeout`` parameter passed to the :py:func:`connect() ` function. - + """ return self._last_heartbeat def on_message(self, name): """ Decorator for message listener callback functions. - + .. tip:: - - This is the most elegant way to define message listener callback functions. + + This is the most elegant way to define message listener callback functions. Use :py:func:`add_message_listener` only if you need to be able to :py:func:`remove the listener ` later. - - A decorated message listener function is called with three arguments every time the - specified message is received: - + + A decorated message listener function is called with three arguments every time the + specified message is received: + * ``self`` - the current vehicle. * ``name`` - the name of the message that was intercepted. * ``message`` - the actual message (a `pymavlink `_ - `class `_). + `class `_). For example, in the fragment below ``my_method`` will be called for every heartbeat message: - + .. code:: python @vehicle.on_message('HEARTBEAT') def my_method(self, name, msg): pass - + See :ref:`mavlink_messages` for more information. - + :param String name: The name of the message to be intercepted by the decorated listener function (or '*' to get all messages). """ @@ -1410,22 +1410,22 @@ def decorator(fn): def add_message_listener(self, name, fn): """ Adds a message listener function that will be called every time the specified message is received. - + .. tip:: - + We recommend you use :py:func:`on_message` instead of this method as it has a more elegant syntax. - This method is only preferred if you need to be able to + This method is only preferred if you need to be able to :py:func:`remove the listener `. - + The callback function must have three arguments: - + * ``self`` - the current vehicle. * ``name`` - the name of the message that was intercepted. * ``message`` - the actual message (a `pymavlink `_ - `class `_). + `class `_). For example, in the fragment below ``my_method`` will be called for every heartbeat message: - + .. code:: python #Callback method for new messages @@ -1433,11 +1433,11 @@ def my_method(self, name, msg): pass vehicle.add_message_listener('HEARTBEAT',my_method) - + See :ref:`mavlink_messages` for more information. - + :param String name: The name of the message to be intercepted by the listener function (or '*' to get all messages). - :param fn: The listener function that will be called if a message is received. + :param fn: The listener function that will be called if a message is received. """ name = str(name) if name not in self._message_listeners: @@ -1448,12 +1448,12 @@ def my_method(self, name, msg): def remove_message_listener(self, name, fn): """ Removes a message listener (that was previously added using :py:func:`add_message_listener`). - + See :ref:`mavlink_messages` for more information. - + :param String name: The name of the message for which the listener is to be removed (or '*' to remove an 'all messages' observer). - :param fn: The listener callback function to remove. - + :param fn: The listener callback function to remove. + """ name = str(name) if name in self._message_listeners: @@ -1478,9 +1478,9 @@ def flush(self): After the return from ``flush()`` any writes are guaranteed to have completed (or thrown an exception) and future reads will see their effects. - .. warning:: + .. warning:: - This method is deprecated. It has been replaced by + This method is deprecated. It has been replaced by :py:func:`Vehicle.commands.upload() `. """ return self.commands.upload() @@ -1513,42 +1513,42 @@ def mode(self, v): @property def location(self): """ - The vehicle location in global, global relative and local frames (:py:class:`Locations`). - + The vehicle location in global, global relative and local frames (:py:class:`Locations`). + The different frames are accessed through its members: - + * :py:attr:`global_frame ` (:py:class:`LocationGlobal`) * :py:attr:`global_relative_frame ` (:py:class:`LocationGlobalRelative`) * :py:attr:`local_frame ` (:py:class:`LocationLocal`) - + For example, to print the location in each frame for a ``vehicle``: - + .. code-block:: python # Print location information for `vehicle` in all frames (default printer) print "Global Location: %s" % vehicle.location.global_frame print "Global Location (relative altitude): %s" % vehicle.location.global_relative_frame print "Local Location: %s" % vehicle.location.local_frame #NED - + # Print altitudes in the different frames (see class definitions for other available information) print "Altitude (global frame): %s" % vehicle.location.global_frame.alt print "Altitude (global relative frame): %s" % vehicle.location.global_relative_frame.alt print "Altitude (NED frame): %s" % vehicle.location.local_frame.down - + .. note:: - + All the location "values" (e.g. ``global_frame.lat``) are initially created with value ``None``. The ``global_frame``, ``global_relative_frame`` latitude and longitude values are populated shortly after initialisation but - ``global_frame.alt`` may take a few seconds longer to be updated. + ``global_frame.alt`` may take a few seconds longer to be updated. The ``local_frame`` does not populate until the vehicle is armed. - + The attribute and its members are observable. To watch for changes in all frames using a listener created using a decorator (you can also define a listener and explicitly add it). .. code-block:: python - - @vehicle.on_attribute('location') + + @vehicle.on_attribute('location') def listener(self, attr_name, value): # `self`: :py:class:`Vehicle` object that has been updated. # `attr_name`: name of the observed attribute - 'location' @@ -1560,14 +1560,14 @@ def listener(self, attr_name, value): To watch for changes in just one attribute (in this case ``global_frame``): .. code-block:: python - - @vehicle.on_attribute('location.global_frame') + + @vehicle.on_attribute('location.global_frame') def listener(self, attr_name, value): # `self`: :py:class:`Locations` object that has been updated. # `attr_name`: name of the observed attribute - 'global_frame' # `value` is the updated attribute value. print " Global: %s" % value - + #Or watch using decorator: ``@vehicle.location.on_attribute('global_frame')``. """ return self._location @@ -1599,7 +1599,7 @@ def velocity(self): def version(self): """ The autopilot version and type in a :py:class:`Version` object. - + .. versionadded:: 2.0.3 """ return Version(self._raw_version, self._autopilot_type, self._vehicle_type) @@ -1608,7 +1608,7 @@ def version(self): def capabilities(self): """ The autopilot capabilities in a :py:class:`Capabilities` object. - + .. versionadded:: 2.0.3 """ return Capabilities(self._capabilities) @@ -1659,7 +1659,7 @@ def armed(self, value): def is_armable(self): """ Returns ``True`` if the vehicle is ready to arm, false otherwise (``Boolean``). - + This attribute wraps a number of pre-arm checks, ensuring that the vehicle has booted, has a good GPS fix, and that the EKF pre-arm is complete. """ @@ -1674,14 +1674,14 @@ def system_status(self): System status (:py:class:`SystemStatus`). The status has a ``state`` property with one of the following values: - + * ``UNINIT``: Uninitialized system, state is unknown. * ``BOOT``: System is booting up. * ``CALIBRATING``: System is calibrating and not flight-ready. * ``STANDBY``: System is grounded and on standby. It can be launched any time. * ``ACTIVE``: System is active and might be already airborne. Motors are engaged. * ``CRITICAL``: System is in a non-normal flight mode. It can however still navigate. - * ``EMERGENCY``: System is in a non-normal flight mode. It lost control over parts + * ``EMERGENCY``: System is in a non-normal flight mode. It lost control over parts or over the whole airframe. It is in mayday and going down. * ``POWEROFF``: System just initialized its power-down sequence, will shut down now. """ @@ -1707,9 +1707,9 @@ def heading(self): def groundspeed(self): """ Current groundspeed in metres/second (``double``). - - This attribute is settable. The set value is the default target groundspeed - when moving the vehicle using :py:func:`simple_goto` (or other position-based + + This attribute is settable. The set value is the default target groundspeed + when moving the vehicle using :py:func:`simple_goto` (or other position-based movement commands). """ return self._groundspeed @@ -1734,9 +1734,9 @@ def groundspeed(self, speed): def airspeed(self): """ Current airspeed in metres/second (``double``). - - This attribute is settable. The set value is the default target airspeed - when moving the vehicle using :py:func:`simple_goto` (or other position-based + + This attribute is settable. The set value is the default target airspeed + when moving the vehicle using :py:func:`simple_goto` (or other position-based movement commands). """ return self._airspeed @@ -1755,12 +1755,12 @@ def airspeed(self, speed): # send command to vehicle self.send_mavlink(msg) - + @property def gimbal(self): """ Gimbal object for controlling, viewing and observing gimbal status (:py:class:`Gimbal`). - + .. versionadded:: 2.0.1 """ return self._gimbal @@ -1769,7 +1769,7 @@ def gimbal(self): def mount_status(self): """ .. warning:: This method is deprecated. It has been replaced by :py:attr:`gimbal`. - + Current status of the camera mount (gimbal) as a three element list: ``[ pitch, yaw, roll ]``. The values in the list are set to ``None`` if no mount is configured. @@ -1792,14 +1792,14 @@ def ekf_ok(self): def channels(self): """ The RC channel values from the RC Transmitter (:py:class:`Channels`). - + The attribute can also be used to set and read RC Override (channel override) values via :py:attr:`Vehicle.channels.override `. - + For more information and examples see :ref:`example_channel_overrides`. - + To read the channels from the RC transmitter: - + .. code:: python # Get all channel values from RC transmitter @@ -1809,7 +1809,7 @@ def channels(self): print "Read channels individually:" print " Ch1: %s" % vehicle.channels['1'] print " Ch2: %s" % vehicle.channels['2'] - + """ return self._channels @@ -1818,7 +1818,7 @@ def home_location(self): """ The current home location (:py:class:`LocationGlobal`). - To get the attribute you must first download the :py:func:`Vehicle.commands`. + To get the attribute you must first download the :py:func:`Vehicle.commands`. The attribute has a value of ``None`` until :py:func:`Vehicle.commands` has been downloaded **and** the autopilot has set an initial home location (typically where the vehicle first gets GPS lock). @@ -1836,15 +1836,15 @@ def home_location(self): home = vehicle.home_location The ``home_location`` is not observable. - - The attribute can be written (in the same way as any other attribute) after it has successfully - been populated from the vehicle. The value sent to the vehicle is cached in the attribute + + The attribute can be written (in the same way as any other attribute) after it has successfully + been populated from the vehicle. The value sent to the vehicle is cached in the attribute (and can potentially get out of date if you don't re-download ``Vehicle.commands``): - .. warning:: + .. warning:: Setting the value will fail silently if the specified location is more than 50km from the EKF origin. - + """ return copy.copy(self._home_location) @@ -1853,11 +1853,11 @@ def home_location(self): def home_location(self, pos): """ Sets the home location (``LocationGlobal``). - + The value cannot be set until it has successfully been read from the vehicle. After being set the value is cached in the home_location attribute and does not have to be re-read. - .. note:: + .. note:: Setting the value will fail silently if the specified location is more than 50km from the EKF origin. """ @@ -1895,27 +1895,27 @@ def parameters(self): """ return self._parameters - + def simple_takeoff(self, alt=None): """ Take off and fly the vehicle to the specified altitude (in metres) and then wait for another command. .. note:: - + This function should only be used on Copter vehicles. The vehicle must be in GUIDED mode and armed before this is called. - There is no mechanism for notification when the correct altitude is reached, + There is no mechanism for notification when the correct altitude is reached, and if another command arrives before that point (e.g. :py:func:`simple_goto`) it will be run instead. .. warning:: - - Apps should code to ensure that the vehicle will reach a safe altitude before + + Apps should code to ensure that the vehicle will reach a safe altitude before other commands are executed. A good example is provided in the guide topic :doc:`guide/taking_off`. - - :param alt: Target height, in metres. + + :param alt: Target height, in metres. """ if alt is not None: altitude = float(alt) @@ -1927,13 +1927,13 @@ def simple_takeoff(self, alt=None): def simple_goto(self, location, airspeed=None, groundspeed=None): ''' Go to a specified global location (:py:class:`LocationGlobal` or :py:class:`LocationGlobalRelative`). - - There is no mechanism for notification when the target location is reached, and if another command arrives + + There is no mechanism for notification when the target location is reached, and if another command arrives before that point that will be executed immediately. - - You can optionally set the desired airspeed or groundspeed (this is identical to setting + + You can optionally set the desired airspeed or groundspeed (this is identical to setting :py:attr:`airspeed` or :py:attr:`groundspeed`). The vehicle will determine what speed to - use if the values are not set or if they are both set. + use if the values are not set or if they are both set. The method will change the :py:class:`VehicleMode` to ``GUIDED`` if necessary. @@ -1980,11 +1980,11 @@ def send_mavlink(self, message): """ This method is used to send raw MAVLink "custom messages" to the vehicle. - The function can send arbitrary messages/commands to the connected vehicle at any time and in any vehicle mode. + The function can send arbitrary messages/commands to the connected vehicle at any time and in any vehicle mode. It is particularly useful for controlling vehicles outside of missions (for example, in GUIDED mode). The :py:func:`message_factory ` is used to create messages in the appropriate format. - + For more information see the guide topic: :ref:`guided_mode_how_to_send_commands`. :param message: A ``MAVLink_message`` instance, created using :py:func:`message_factory `. @@ -1997,12 +1997,12 @@ def message_factory(self): """ Returns an object that can be used to create 'raw' MAVLink messages that are appropriate for this vehicle. The message can then be sent using :py:func:`send_mavlink(message) `. - + .. note:: - + Vehicles support a subset of the messages defined in the MAVLink standard. For more information about the supported sets see wiki topics: - `Copter Commands in Guided Mode `_ + `Copter Commands in Guided Mode `_ and `Plane Commands in Guided Mode `_. All message types are defined in the central MAVLink github repository. For example, a Pixhawk understands @@ -2023,13 +2023,13 @@ def message_factory(self): msg = vehicle.message_factory.image_trigger_control_encode(True) vehicle.send_mavlink(msg) - Some message types include "addressing information". If present, there is no need to specify the ``target_system`` - id (just set to zero) as DroneKit will automatically update messages with the correct ID for the connected - vehicle before sending. - The ``target_component`` should be set to 0 (broadcast) unless the message is to specific component. - CRC fields and sequence numbers (if defined in the message type) are automatically set by DroneKit and can also + Some message types include "addressing information". If present, there is no need to specify the ``target_system`` + id (just set to zero) as DroneKit will automatically update messages with the correct ID for the connected + vehicle before sending. + The ``target_component`` should be set to 0 (broadcast) unless the message is to specific component. + CRC fields and sequence numbers (if defined in the message type) are automatically set by DroneKit and can also be ignored/set to zero. - + For more information see the guide topic: :ref:`guided_mode_how_to_send_commands`. """ return self._master.mav @@ -2085,31 +2085,31 @@ def send_capabilties_request(self, vehicle, name, m): def wait_ready(self, *types, **kwargs): """ Waits for specified attributes to be populated from the vehicle (values are initially ``None``). - + This is typically called "behind the scenes" to ensure that :py:func:`connect` does not return until - attributes have populated (via the ``wait_ready`` parameter). You can also use it after connecting to + attributes have populated (via the ``wait_ready`` parameter). You can also use it after connecting to wait on a specific value(s). - + There are two ways to call the method: - + .. code-block:: python - + #Wait on default attributes to populate vehicle.wait_ready(True) - + #Wait on specified attributes (or array of attributes) to populate vehicle.wait_ready('mode','airspeed') - Using the ``wait_ready(True)`` waits on :py:attr:`parameters`, :py:attr:`gps_0`, - :py:attr:`armed`, :py:attr:`mode`, and :py:attr:`attitude`. In practice this usually + Using the ``wait_ready(True)`` waits on :py:attr:`parameters`, :py:attr:`gps_0`, + :py:attr:`armed`, :py:attr:`mode`, and :py:attr:`attitude`. In practice this usually means that all supported attributes will be populated. - + By default, the method will timeout after 30 seconds and raise an exception if the attributes were not populated. - + :param types: ``True`` to wait on the default set of attributes, or a - comma-separated list of the specific attributes to wait on. - :param int timeout: Timeout in seconds after which the method will raise an exception + comma-separated list of the specific attributes to wait on. + :param int timeout: Timeout in seconds after which the method will raise an exception (the default) or return ``False``. The default timeout is 30 seconds. :param Boolean raise_exception: If ``True`` the method will raise an exception on timeout, otherwise the method will return ``False``. The default is ``True`` (raise exception). @@ -2143,22 +2143,22 @@ class Gimbal(object): """ Gimbal status and control. - An object of this type is returned by :py:attr:`Vehicle.gimbal`. The - gimbal orientation can be obtained from its :py:attr:`roll`, :py:attr:`pitch` and + An object of this type is returned by :py:attr:`Vehicle.gimbal`. The + gimbal orientation can be obtained from its :py:attr:`roll`, :py:attr:`pitch` and :py:attr:`yaw` attributes. - + The gimbal orientation can be set explicitly using :py:func:`rotate` - or you can set the gimbal (and vehicle) to track a specific "region of interest" using + or you can set the gimbal (and vehicle) to track a specific "region of interest" using :py:func:`target_location`. .. note:: - - * The orientation attributes are created with values of ``None``. If a gimbal is present, + + * The orientation attributes are created with values of ``None``. If a gimbal is present, the attributes are populated shortly after initialisation by messages from the autopilot. * The attribute values reflect the last gimbal setting-values rather than actual measured values. - This means that the values won't change if you manually move the gimbal, and that the value - will change when you set it, even if the specified orientation is not supported. - * A gimbal may not support all axes of rotation. For example, the Solo gimbal will set pitch + This means that the values won't change if you manually move the gimbal, and that the value + will change when you set it, even if the specified orientation is not supported. + * A gimbal may not support all axes of rotation. For example, the Solo gimbal will set pitch values from 0 to -90 (straight ahead to straight down), it will rotate the vehicle to follow specified yaw values, and will ignore roll commands (not supported). """ @@ -2181,12 +2181,12 @@ def listener(vehicle, name, m): @property def pitch(self): """ - Gimbal pitch in degrees relative to the vehicle (see diagram for :ref:`attitude `). - A value of 0 represents a camera pointed straight ahead relative to the front of the vehicle, + Gimbal pitch in degrees relative to the vehicle (see diagram for :ref:`attitude `). + A value of 0 represents a camera pointed straight ahead relative to the front of the vehicle, while -90 points the camera straight down. - - .. note:: - + + .. note:: + This is the last pitch value sent to the gimbal (not the actual/measured pitch). """ return self._pitch @@ -2195,10 +2195,10 @@ def pitch(self): def roll(self): """ Gimbal roll in degrees relative to the vehicle (see diagram for :ref:`attitude `). - + .. note:: - - This is the last roll value sent to the gimbal (not the actual/measured roll). + + This is the last roll value sent to the gimbal (not the actual/measured roll). """ return self._roll @@ -2206,24 +2206,24 @@ def roll(self): def yaw(self): """ Gimbal yaw in degrees relative to *global frame* (0 is North, 90 is West, 180 is South etc). - - .. note:: - + + .. note:: + This is the last yaw value sent to the gimbal (not the actual/measured yaw). - """ + """ return self._yaw def rotate(self, pitch, roll, yaw): """ Rotate the gimbal to a specific vector. - + .. code-block:: python - + #Point the gimbal straight down vehicle.gimbal.rotate(-90, 0, 0) - :param pitch: Gimbal pitch in degrees relative to the vehicle (see diagram for :ref:`attitude `). - A value of 0 represents a camera pointed straight ahead relative to the front of the vehicle, + :param pitch: Gimbal pitch in degrees relative to the vehicle (see diagram for :ref:`attitude `). + A value of 0 represents a camera pointed straight ahead relative to the front of the vehicle, while -90 points the camera straight down. :param roll: Gimbal roll in degrees relative to the vehicle (see diagram for :ref:`attitude `). :param yaw: Gimbal yaw in degrees relative to *global frame* (0 is North, 90 is West, 180 is South etc.) @@ -2247,7 +2247,7 @@ def rotate(self, pitch, roll, yaw): def target_location(self,roi): """ Point the gimbal at a specific region of interest (ROI). - + .. code-block:: python #Set the camera to track the current home location. @@ -2270,7 +2270,7 @@ def target_location(self,roi): 1, # stabilize yaw ) self._vehicle.send_mavlink(msg) - + #Get altitude relative to home irrespective of Location object passed in. if isinstance(roi, LocationGlobalRelative): alt = roi.alt @@ -2282,7 +2282,7 @@ def target_location(self,roi): else: raise APIException('Expecting location to be LocationGlobal or LocationGlobalRelative.') - #set the ROI + #set the ROI msg = self._vehicle.message_factory.command_long_encode( 0, 1, # target system, target component mavutil.mavlink.MAV_CMD_DO_SET_ROI, #command @@ -2296,8 +2296,8 @@ def target_location(self,roi): def release(self): """ - Release control of the gimbal to the user (RC Control). - + Release control of the gimbal to the user (RC Control). + This should be called once you've finished controlling the mount with either :py:func:`rotate` or :py:func:`target_location`. Control will automatically be released if you change vehicle mode. """ @@ -2331,7 +2331,7 @@ class Parameters(collections.MutableMapping, HasObservers): vehicle.parameters['THR_MIN']=100 It is also possible to observe parameters and to iterate the :py:attr:`Vehicle.parameters`. - + For more information see :ref:`the guide `. """ @@ -2400,20 +2400,20 @@ def wait_ready(self, **kwargs): def add_attribute_listener(self, attr_name, *args, **kwargs): """ - Add a listener callback on a particular parameter. - + Add a listener callback on a particular parameter. + The callback can be removed using :py:func:`remove_attribute_listener`. - + .. note:: - - The :py:func:`on_attribute` decorator performs the same operation as this method, but with - a more elegant syntax. Use ``add_attribute_listener`` only if you will need to remove + + The :py:func:`on_attribute` decorator performs the same operation as this method, but with + a more elegant syntax. Use ``add_attribute_listener`` only if you will need to remove the observer. The callback function is invoked only when the parameter changes. The callback arguments are: - + * ``self`` - the associated :py:class:`Parameters`. * ``attr_name`` - the parameter name. This can be used to infer which parameter has triggered if the same callback is used for watching multiple parameters. @@ -2428,10 +2428,10 @@ def thr_min_callback(self, attr_name, value): print " PARAMETER CALLBACK: %s changed to: %s" % (attr_name, value) #Add observer for the vehicle's THR_MIN parameter - vehicle.parameters.add_attribute_listener('THR_MIN', thr_min_callback) - + vehicle.parameters.add_attribute_listener('THR_MIN', thr_min_callback) + See :ref:`vehicle_state_observing_parameters` for more information. - + :param String attr_name: The name of the parameter to watch (or '*' to watch all parameters). :param args: The callback to invoke when a change in the parameter is detected. @@ -2448,7 +2448,7 @@ def remove_attribute_listener(self, attr_name, *args, **kwargs): .. code:: python vehicle.parameters.remove_attribute_listener('thr_min', thr_min_callback) - + See :ref:`vehicle_state_observing_parameters` for more information. :param String attr_name: The parameter name that is to have an observer removed (or '*' to remove an 'all attribute' observer). @@ -2465,17 +2465,17 @@ def notify_attribute_listeners(self, attr_name, *args, **kwargs): def on_attribute(self, attr_name, *args, **kwargs): """ Decorator for parameter listeners. - + .. note:: - - There is no way to remove a listener added with this decorator. Use - :py:func:`add_attribute_listener` if you need to be able to remove + + There is no way to remove a listener added with this decorator. Use + :py:func:`add_attribute_listener` if you need to be able to remove the :py:func:`listener `. The callback function is invoked only when the parameter changes. The callback arguments are: - + * ``self`` - the associated :py:class:`Parameters`. * ``attr_name`` - the parameter name. This can be used to infer which parameter has triggered if the same callback is used for watching multiple parameters. @@ -2485,12 +2485,12 @@ def on_attribute(self, attr_name, *args, **kwargs): .. code:: python - @vehicle.parameters.on_attribute('THR_MIN') + @vehicle.parameters.on_attribute('THR_MIN') def decorated_thr_min_callback(self, attr_name, value): - print " PARAMETER CALLBACK: %s changed to: %s" % (attr_name, value) - + print " PARAMETER CALLBACK: %s changed to: %s" % (attr_name, value) + See :ref:`vehicle_state_observing_parameters` for more information. - + :param String attr_name: The name of the parameter to watch (or '*' to watch all parameters). :param args: The callback to invoke when a change in the parameter is detected. @@ -2503,8 +2503,8 @@ class Command(mavutil.mavlink.MAVLink_mission_item_message): """ A waypoint object. - This object encodes a single mission item command. The set of commands that are supported - by ArduPilot in Copter, Plane and Rover (along with their parameters) are listed in the wiki article + This object encodes a single mission item command. The set of commands that are supported + by ArduPilot in Copter, Plane and Rover (along with their parameters) are listed in the wiki article `MAVLink Mission Command Messages (MAV_CMD) `_. For example, to create a `NAV_WAYPOINT `_ command: @@ -2514,7 +2514,7 @@ class Command(mavutil.mavlink.MAVLink_mission_item_message): cmd = Command(0,0,0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0,-34.364114, 149.166022, 30) - :param target_system: This can be set to any value + :param target_system: This can be set to any value (DroneKit changes the value to the MAVLink ID of the connected vehicle before the command is sent). :param target_component: The component id if the message is intended for a particular component within the target system (for example, the camera). Set to zero (broadcast) in most cases. @@ -2604,7 +2604,7 @@ def wait_ready(self, **kwargs): def clear(self): ''' - Clear the command list. + Clear the command list. This command will be sent to the vehicle only after you call :py:func:`upload() `. ''' @@ -2625,10 +2625,10 @@ def add(self, cmd): ''' Add a new command (waypoint) at the end of the command list. - .. note:: + .. note:: Commands are sent to the vehicle only after you call ::py:func:`upload() `. - + :param Command cmd: The command to be added. ''' self.wait_ready() @@ -2714,12 +2714,12 @@ def connect(ip, source_system=255, use_native=False): """ - Returns a :py:class:`Vehicle` object connected to the address specified by string parameter ``ip``. + Returns a :py:class:`Vehicle` object connected to the address specified by string parameter ``ip``. Connection string parameters (``ip``) for different targets are listed in the :ref:`getting started guide `. - + The method is usually called with ``wait_ready=True`` to ensure that vehicle parameters and (most) attributes are available when ``connect()`` returns. - + .. code:: python from dronekit import connect @@ -2728,36 +2728,36 @@ def connect(ip, vehicle = connect('127.0.0.1:14550', wait_ready=True) :param String ip: :ref:`Connection string ` for target address - e.g. 127.0.0.1:14550. - - :param Bool/Array wait_ready: If ``True`` wait until all default attributes have downloaded before - the method returns (default is ``None``). - The default attributes to wait on are: :py:attr:`parameters`, :py:attr:`gps_0`, - :py:attr:`armed`, :py:attr:`mode`, and :py:attr:`attitude`. - + + :param Bool/Array wait_ready: If ``True`` wait until all default attributes have downloaded before + the method returns (default is ``None``). + The default attributes to wait on are: :py:attr:`parameters`, :py:attr:`gps_0`, + :py:attr:`armed`, :py:attr:`mode`, and :py:attr:`attitude`. + You can also specify a named set of parameters to wait on (e.g. ``wait_ready=['system_status','mode']``). - + For more information see :py:func:`Vehicle.wait_ready `. - :param status_printer: Method of signature ``def status_printer(txt)`` that prints + :param status_printer: Method of signature ``def status_printer(txt)`` that prints STATUS_TEXT messages from the Vehicle and other diagnostic information. By default the status information is printed to the command prompt in which the script is running. - :param Vehicle vehicle_class: The class that will be instantiated by the ``connect()`` method. - This can be any sub-class of ``Vehicle`` (and defaults to ``Vehicle``). + :param Vehicle vehicle_class: The class that will be instantiated by the ``connect()`` method. + This can be any sub-class of ``Vehicle`` (and defaults to ``Vehicle``). :param int rate: Data stream refresh rate. The default is 4Hz (4 updates per second). :param int baud: The baud rate for the connection. The default is 115200. - :param int heartbeat_timeout: Connection timeout value in seconds (default is 30s). - If a heartbeat is not detected within this time an exception will be raised. + :param int heartbeat_timeout: Connection timeout value in seconds (default is 30s). + If a heartbeat is not detected within this time an exception will be raised. :param int source_system: The MAVLink ID of the :py:class:`Vehicle` object returned by this method (by default 255). :param bool use_native: Use precompiled MAVLink parser. .. note:: - The returned :py:class:`Vehicle` object acts as a ground control station from the + The returned :py:class:`Vehicle` object acts as a ground control station from the perspective of the connected "real" vehicle. It will process/receive messages from the real vehicle if they are addressed to this ``source_system`` id. Messages sent to the real vehicle are automatically updated to use the vehicle's ``target_system`` id. - - It is *good practice* to assign a unique id for every system on the MAVLink network. + + It is *good practice* to assign a unique id for every system on the MAVLink network. It is possible to configure the autopilot to only respond to guided-mode commands from a specified GCS ID. @@ -2769,7 +2769,7 @@ def connect(ip, handler = MAVConnection(ip, baud=baud, source_system=source_system, use_native=use_native) vehicle = vehicle_class(handler) - + if status_printer: @vehicle.on_message('STATUSTEXT') From 5b49d98eb1ebc5bba354a4b9b5912a794f2e7054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Roche?= Date: Fri, 19 Feb 2016 18:15:39 -0800 Subject: [PATCH 327/475] cleanup vehicle mode setting api --- dronekit/__init__.py | 18 ++++++++++++------ dronekit/test/sitl/test_mode_settings.py | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 dronekit/test/sitl/test_mode_settings.py diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 0522ed2ff..c31cdfe07 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1163,15 +1163,14 @@ def listener(self, name, m): def listener(self, name, m): self._armed = (m.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED) != 0 self.notify_attribute_listeners('armed', self.armed, cache=True) - if self._master.mode_mapping() != None: - flightmodesById = {v: k for k, v in self._master.mode_mapping().items()} - if m.custom_mode in flightmodesById: - self._flightmode = flightmodesById[m.custom_mode] + self._autopilot_type = m.autopilot + self._vehicle_type = m.type + if self._is_mode_available(m.custom_mode) == False: + raise APIException("mode %s not available on mavlink definition" % m.custom_mode) + self._flightmode = self._mode_mapping_bynumber[m.custom_mode] self.notify_attribute_listeners('mode', self.mode, cache=True) self._system_status = m.system_status self.notify_attribute_listeners('system_status', self.system_status, cache=True) - self._autopilot_type = m.autopilot - self._vehicle_type = m.type # Waypoints. @@ -1493,6 +1492,13 @@ def flush(self): def _mode_mapping(self): return self._master.mode_mapping() + @property + def _mode_mapping_bynumber(self): + return mavutil.mode_mapping_bynumber(self._vehicle_type) + + def _is_mode_available(self, mode_code): + return mode_code in self._mode_mapping_bynumber + # # Operations to support the standard API. # diff --git a/dronekit/test/sitl/test_mode_settings.py b/dronekit/test/sitl/test_mode_settings.py new file mode 100644 index 000000000..da7ec794c --- /dev/null +++ b/dronekit/test/sitl/test_mode_settings.py @@ -0,0 +1,15 @@ +import time +import math +from dronekit import connect +from dronekit.test import with_sitl +from nose.tools import assert_equals + + +@with_sitl +def test_modes_set(connpath): + vehicle = connect(connpath) + + def listener(self, name, m): + assert_equals('STABILIZE', self._flightmode) + + vehicle.add_message_listener('HEARTBEAT', listener) From 62b464e047ab0aa1dcc7b3223cc5669749eb5415 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Thu, 25 Feb 2016 21:28:02 +1100 Subject: [PATCH 328/475] bump version to 2.3.0 --- docs/conf.py | 4 ++-- setup.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 81d918138..0d934a3d5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -49,9 +49,9 @@ # built documents. # # The short X.Y version. -version = '2.2' +version = '2.3' # The full version, including alpha/beta/rc tags. -release = '2.2' +release = '2.3.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/setup.py b/setup.py index 241253352..7bc24f124 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.2.1' +version = '2.3.0' setup(name='dronekit', zip_safe=True, From 9b19a825115c1448846fbdbe7f9aba614ce10890 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 26 Feb 2016 09:24:21 +1100 Subject: [PATCH 329/475] Update changelist/release notes --- CHANGELOG.md | 58 +++++++++++++++++++++++++ docs/about/github_latest_release.txt | 65 ++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31bf9b2fc..9c9330eec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,63 @@ # Changelog + +## Version 2.3.0 (2016-11-25) + +### New Features + +* px4 compatability improvements + +### Updated Features + +* Documentation fixes +* PIP repository improvements +* mode-setting API improvements +* ardupilot-solo compatability fixes + + + +## Version 2.2.0 (2016-02-19) + +### Bug Fixes + +* Splits outbound messages into its own thread. +* remove of capabilities request on HEARTBEAT listener +* check if mode_mapping has items before iteration + +## Version 2.1.0 (2016-02-16) + + +### New Features + + +* Gimbal control attribute +* Autopilot version attribute +* Autopilot capabilities attribute +* Best Practice guide documentation. +* Performance test example (restructured and docs added) + +### Updated Features: + +Many documentation fixes: + +* Restructured documentation with Develop (Concepts) and Guide (HowTo) sections +* Docs separated out "Connection Strings" section. +* Improved test and contribution sections. +* Updated examples and documentation to use DroneKit-Sitl for simulation ("zero setup examples") +* Debugging docs updated with additional libraries. +* Flight Replay example fetches data from TLOG rather than droneshare +* Drone Delivery example now uses strart location for home address. +* Disabled web tests (not currently supported/used) +* Updated copyright range to include changes in 2016 + +### Bug Fixes + +* Numerous minor docs fixes. +* Harmonise nosetest options across each of the integration platforms +* Fix incorrect property marker for airspeed attribute + + + ## Version 2.0.2 (2015-11-30) ### Bug Fixes: diff --git a/docs/about/github_latest_release.txt b/docs/about/github_latest_release.txt index 8c4697121..15ea9853e 100644 --- a/docs/about/github_latest_release.txt +++ b/docs/about/github_latest_release.txt @@ -3,6 +3,71 @@ Changelog ========= +Version 2.3.0 (2016-11-25) +-------------------------- + +New Features +~~~~~~~~~~~~ + +* px4 compatability improvements + +Updated Features +~~~~~~~~~~~~~~~~ + +- Documentation fixes +- PIP repository improvements +- mode-setting API improvements +- ardupilot-solo compatability fixes + + +Version 2.2.0 (2016-02-19) +-------------------------- + +Bug Fixes +~~~~~~~~~ + +- Splits outbound messages into its own thread. +- remove of capabilities request on HEARTBEAT listener +- check if mode_mapping has items before iteration + + +Version 2.1.0 (2016-02-16) +-------------------------- + +New Features +~~~~~~~~~~~~ + +- Gimbal control attribute +- Autopilot version attribute +- Autopilot capabilities attribute +- Best Practice guide documentation. +- Performance test example (restructured and docs added) + +Updated Features +~~~~~~~~~~~~~~~~ + +Many documentation fixes: + +- Restructured documentation with Develop (Concepts) and Guide (HowTo) sections +- Docs separated out "Connection Strings" section. +- Improved test and contribution sections. +- Updated examples and documentation to use DroneKit-Sitl for simulation ("zero setup examples") +- Debugging docs updated with additional libraries. +- Flight Replay example fetches data from TLOG rather than droneshare +- Drone Delivery example now uses strart location for home address. +- Disabled web tests (not currently supported/used) +- Updated copyright range to include changes in 2016 + + +Bug Fixes +~~~~~~~~~ + +- Numerous minor docs fixes. +- Harmonise nosetest options across each of the integration platforms +- Fix incorrect property marker for airspeed attribute + + + Version 2.0.0 (2015-11-23) -------------------------- From c3c71322d602a08190338f7eaceb76ad5a209503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Roche?= Date: Thu, 25 Feb 2016 17:14:04 -0800 Subject: [PATCH 330/475] cache ekf_ok callbacks --- dronekit/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index c31cdfe07..5a0d38fc4 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1151,7 +1151,7 @@ def listener(self, name, m): # boolean: EKF's predicted horizontal position (absolute) estimate is good self._ekf_predposhorizabs = (m.flags & ardupilotmega.EKF_PRED_POS_HORIZ_ABS) > 0 - self.notify_attribute_listeners('ekf_ok', self.ekf_ok) + self.notify_attribute_listeners('ekf_ok', self.ekf_ok, cache=True) self._flightmode = 'AUTO' self._armed = False From 0e0782fc19d1ef66aead96677258cebc5bdb4567 Mon Sep 17 00:00:00 2001 From: dtaniwaki Date: Sun, 28 Feb 2016 01:31:27 -0800 Subject: [PATCH 331/475] Fix ports in example documents --- docs/examples/flight_replay.rst | 2 +- docs/examples/vehicle_state.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/examples/flight_replay.rst b/docs/examples/flight_replay.rst index d68b3ad95..63b3d175b 100644 --- a/docs/examples/flight_replay.rst +++ b/docs/examples/flight_replay.rst @@ -53,7 +53,7 @@ In summary, after cloning the repository: Generated 100 waypoints from tlog Starting copter simulator (SITL) SITL already Downloaded. - Connecting to vehicle on: tcp:127.0.0.1:5 + Connecting to vehicle on: tcp:127.0.0.1:5760 >>> APM:Copter V3.3 (d6053245) >>> Frame: QUAD >>> Calibrating barometer diff --git a/docs/examples/vehicle_state.rst b/docs/examples/vehicle_state.rst index f43dfd62a..64a367f39 100644 --- a/docs/examples/vehicle_state.rst +++ b/docs/examples/vehicle_state.rst @@ -37,7 +37,7 @@ In summary, after cloning the repository: .. code:: bash - Connecting to vehicle on: 170.0.0.1:14550 + Connecting to vehicle on: tcp:127.0.0.1:5760 >>> APM:Copter V3.3 (d6053245) >>> Frame: QUAD >>> Calibrating barometer From 3f8fcec988a7a27044812840c134320bb181d4ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Roche?= Date: Fri, 26 Feb 2016 14:38:38 -0800 Subject: [PATCH 332/475] add monotonic lib --- requirements.txt | 1 + setup.py | 1 + 2 files changed, 2 insertions(+) diff --git a/requirements.txt b/requirements.txt index 3257caf2b..c0deaab1d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,4 @@ psutil>=3.0.0 mock>=1.3.0 six>=1.9.0 dronekit-sitl>=3.0,<=3.99999 +monotonic==0.6 diff --git a/setup.py b/setup.py index 7bc24f124..4972966db 100644 --- a/setup.py +++ b/setup.py @@ -12,6 +12,7 @@ author='3D Robotics', install_requires=[ 'pymavlink>=1.1.62', + 'monotonic==0.6' ], author_email='tim@3drobotics.com, kevinh@geeksville.com', classifiers=[ From 5d9edb31d6c3120137a8e8bf41fb84a2d712d9d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Roche?= Date: Fri, 26 Feb 2016 14:39:34 -0800 Subject: [PATCH 333/475] use monotonic clock on heartbeat checks --- dronekit/__init__.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 5a0d38fc4..476fe34a9 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -31,6 +31,7 @@ """ from __future__ import print_function +import monotonic import time import socket import sys @@ -1296,18 +1297,18 @@ def listener(self, name, msg): @handler.forward_loop def listener(_): # Send 1 heartbeat per second - if time.time() - self._heartbeat_lastsent > 1: + if monotonic.monotonic() - self._heartbeat_lastsent > 1: self._master.mav.heartbeat_send(mavutil.mavlink.MAV_TYPE_GCS, mavutil.mavlink.MAV_AUTOPILOT_INVALID, 0, 0, 0) - self._heartbeat_lastsent = time.time() + self._heartbeat_lastsent = monotonic.monotonic() # Timeouts. if self._heartbeat_started: - if self._heartbeat_error and self._heartbeat_error > 0 and time.time( + if self._heartbeat_error and self._heartbeat_error > 0 and monotonic.monotonic( ) - self._heartbeat_lastreceived > self._heartbeat_error: raise APIException('No heartbeat in %s seconds, aborting.' % self._heartbeat_error) - elif time.time() - self._heartbeat_lastreceived > self._heartbeat_warning: + elif monotonic.monotonic() - self._heartbeat_lastreceived > self._heartbeat_warning: if self._heartbeat_timeout == False: errprinter('>>> Link timeout, no heartbeat in last %s seconds' % self._heartbeat_warning) @@ -1316,7 +1317,7 @@ def listener(_): @self.on_message(['HEARTBEAT']) def listener(self, name, msg): self._heartbeat_system = msg.get_srcSystem() - self._heartbeat_lastreceived = time.time() + self._heartbeat_lastreceived = monotonic.monotonic() if self._heartbeat_timeout: errprinter('>>> ...link restored.') self._heartbeat_timeout = False @@ -1326,7 +1327,7 @@ def listener(self, name, msg): @handler.forward_loop def listener(_): if self._heartbeat_lastreceived: - self._last_heartbeat = time.time() - self._heartbeat_lastreceived + self._last_heartbeat = monotonic.monotonic() - self._heartbeat_lastreceived self.notify_attribute_listeners('last_heartbeat', self.last_heartbeat) @property @@ -2044,7 +2045,7 @@ def initialize(self, rate=4, heartbeat_timeout=30): self._handler.start() # Start heartbeat polling. - start = time.time() + start = monotonic.monotonic() self._heartbeat_error = heartbeat_timeout or 0 self._heartbeat_started = True self._heartbeat_lastreceived = start From 66b3f6ba52410e7c7474e92dc1694e11e1ad457f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Roche?= Date: Fri, 26 Feb 2016 14:43:29 -0800 Subject: [PATCH 334/475] use monotonic clock on parameter actions --- dronekit/__init__.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 476fe34a9..511def394 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1232,7 +1232,7 @@ def listener(self, name, msg): self._params_loaded = False self._params_start = False self._params_map = {} - self._params_last = time.time() # Last new param. + self._params_last = monotonic.monotonic() # Last new param. self._params_duration = start_duration self._parameters = Parameters(self) @@ -1246,7 +1246,7 @@ def listener(_): self._params_loaded = True self.notify_attribute_listeners('parameters', self.parameters) - if not self._params_loaded and time.time() - self._params_last > self._params_duration: + if not self._params_loaded and monotonic.monotonic() - self._params_last > self._params_duration: c = 0 for i, v in enumerate(self._params_set): if v == None: @@ -1255,7 +1255,7 @@ def listener(_): if c > 50: break self._params_duration = repeat_duration - self._params_last = time.time() + self._params_last = monotonic.monotonic() @self.on_message(['PARAM_VALUE']) def listener(self, name, msg): @@ -1273,7 +1273,7 @@ def listener(self, name, msg): try: if msg.param_index < msg.param_count and msg: if self._params_set[msg.param_index] == None: - self._params_last = time.time() + self._params_last = monotonic.monotonic() self._params_duration = start_duration self._params_set[msg.param_index] = msg self._params_map[msg.param_id] = msg.param_value @@ -2386,11 +2386,11 @@ def set(self, name, value, retries=3, wait_ready=False): remaining = retries while True: self._vehicle._master.param_set_send(name, value) - tstart = time.time() + tstart = monotonic.monotonic() if remaining == 0: break remaining -= 1 - while time.time() - tstart < 1: + while monotonic.monotonic() - tstart < 1: if name in self._vehicle._params_map and self._vehicle._params_map[name] == value: return True time.sleep(0.1) From 7761a53c6c7ecf2d8098f21240785dff380e8e34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Roche?= Date: Fri, 26 Feb 2016 14:47:32 -0800 Subject: [PATCH 335/475] use monotonic clock on wait_ready for attributes --- dronekit/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 511def394..1105297a9 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -2133,10 +2133,10 @@ def wait_ready(self, *types, **kwargs): # Wait for these attributes to have been set. await = set(types) - start = time.time() + start = monotonic.monotonic() while not await.issubset(self._ready_attrs): time.sleep(0.1) - if time.time() - start > timeout: + if monotonic.monotonic() - start > timeout: if raise_exception: raise APIException('wait_ready experienced a timeout after %s seconds.' % timeout) From 6776725d83e4a092ca22fe02220ae6a399c9e279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Roche?= Date: Mon, 29 Feb 2016 09:59:19 -0800 Subject: [PATCH 336/475] update version check for monotonic package we can modify this if we need to later --- requirements.txt | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index c0deaab1d..7dde864c7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,4 +6,4 @@ psutil>=3.0.0 mock>=1.3.0 six>=1.9.0 dronekit-sitl>=3.0,<=3.99999 -monotonic==0.6 +monotonic<1.0 diff --git a/setup.py b/setup.py index 4972966db..b34ff24c4 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ author='3D Robotics', install_requires=[ 'pymavlink>=1.1.62', - 'monotonic==0.6' + 'monotonic<1.0' ], author_email='tim@3drobotics.com, kevinh@geeksville.com', classifiers=[ From ed9852a864cf4d105aaead724b29ae366d4700bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Roche?= Date: Mon, 29 Feb 2016 14:00:59 -0800 Subject: [PATCH 337/475] bump to v2.4.0 --- CHANGELOG.md | 10 +++- docs/about/github_latest_release.txt | 77 +++++++++++++++++----------- docs/conf.py | 4 +- setup.py | 2 +- 4 files changed, 58 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c9330eec..0e052fefe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,15 @@ # Changelog +## Version 2.4.0 (2016-02-29) -## Version 2.3.0 (2016-11-25) +### Bug Fixes + +* Use monotonic clock for all of the internal timeouts and time + measurements +* Docs fixes + + +## Version 2.3.0 (2016-02-26) ### New Features diff --git a/docs/about/github_latest_release.txt b/docs/about/github_latest_release.txt index 15ea9853e..0ea327a38 100644 --- a/docs/about/github_latest_release.txt +++ b/docs/about/github_latest_release.txt @@ -3,22 +3,31 @@ Changelog ========= -Version 2.3.0 (2016-11-25) +Version 2.4.0 (2016-02-29) +-------------------------- + +Bug Fixes +~~~~~~~~~ + +- Use monotonic clock for all of the internal timeouts and time + measurements +- Docs fixes + +Version 2.3.0 (2016-02-26) -------------------------- New Features ~~~~~~~~~~~~ -* px4 compatability improvements +- px4 compatability improvements Updated Features ~~~~~~~~~~~~~~~~ -- Documentation fixes -- PIP repository improvements -- mode-setting API improvements -- ardupilot-solo compatability fixes - +- Documentation fixes +- PIP repository improvements +- mode-setting API improvements +- ardupilot-solo compatability fixes Version 2.2.0 (2016-02-19) -------------------------- @@ -26,10 +35,9 @@ Version 2.2.0 (2016-02-19) Bug Fixes ~~~~~~~~~ -- Splits outbound messages into its own thread. -- remove of capabilities request on HEARTBEAT listener -- check if mode_mapping has items before iteration - +- Splits outbound messages into its own thread. +- remove of capabilities request on HEARTBEAT listener +- check if mode\_mapping has items before iteration Version 2.1.0 (2016-02-16) -------------------------- @@ -37,36 +45,43 @@ Version 2.1.0 (2016-02-16) New Features ~~~~~~~~~~~~ -- Gimbal control attribute -- Autopilot version attribute -- Autopilot capabilities attribute -- Best Practice guide documentation. -- Performance test example (restructured and docs added) +- Gimbal control attribute +- Autopilot version attribute +- Autopilot capabilities attribute +- Best Practice guide documentation. +- Performance test example (restructured and docs added) -Updated Features -~~~~~~~~~~~~~~~~ +Updated Features: +~~~~~~~~~~~~~~~~~ Many documentation fixes: -- Restructured documentation with Develop (Concepts) and Guide (HowTo) sections -- Docs separated out "Connection Strings" section. -- Improved test and contribution sections. -- Updated examples and documentation to use DroneKit-Sitl for simulation ("zero setup examples") -- Debugging docs updated with additional libraries. -- Flight Replay example fetches data from TLOG rather than droneshare -- Drone Delivery example now uses strart location for home address. -- Disabled web tests (not currently supported/used) -- Updated copyright range to include changes in 2016 - +- Restructured documentation with Develop (Concepts) and Guide (HowTo) + sections +- Docs separated out "Connection Strings" section. +- Improved test and contribution sections. +- Updated examples and documentation to use DroneKit-Sitl for + simulation ("zero setup examples") +- Debugging docs updated with additional libraries. +- Flight Replay example fetches data from TLOG rather than droneshare +- Drone Delivery example now uses strart location for home address. +- Disabled web tests (not currently supported/used) +- Updated copyright range to include changes in 2016 Bug Fixes ~~~~~~~~~ -- Numerous minor docs fixes. -- Harmonise nosetest options across each of the integration platforms -- Fix incorrect property marker for airspeed attribute +- Numerous minor docs fixes. +- Harmonise nosetest options across each of the integration platforms +- Fix incorrect property marker for airspeed attribute +Version 2.0.2 (2015-11-30) +-------------------------- + +Bug Fixes: +~~~~~~~~~~ +- Updates ``requests`` dependency to work >=2.5.0 Version 2.0.0 (2015-11-23) -------------------------- diff --git a/docs/conf.py b/docs/conf.py index 0d934a3d5..2509fc2de 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -49,9 +49,9 @@ # built documents. # # The short X.Y version. -version = '2.3' +version = '2.4' # The full version, including alpha/beta/rc tags. -release = '2.3.0' +release = '2.4.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/setup.py b/setup.py index b34ff24c4..d0b4d8835 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.3.0' +version = '2.4.0' setup(name='dronekit', zip_safe=True, From 78c8d577b42725a066d41702b65db1c9ce5619f6 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 1 Mar 2016 09:16:27 +1100 Subject: [PATCH 338/475] Fix typos in release notes --- CHANGELOG.md | 12 +++++++----- docs/about/github_latest_release.txt | 10 +++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e052fefe..a2fe4c4c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,14 +13,14 @@ ### New Features -* px4 compatability improvements +* PX4 compatibility improvements ### Updated Features * Documentation fixes * PIP repository improvements -* mode-setting API improvements -* ardupilot-solo compatability fixes +* Mode-setting API improvements +* ardupilot-solo compatibility fixes @@ -29,8 +29,10 @@ ### Bug Fixes * Splits outbound messages into its own thread. -* remove of capabilities request on HEARTBEAT listener -* check if mode_mapping has items before iteration +* Remove of capabilities request on HEARTBEAT listener +* Check if mode_mapping has items before iteration + + ## Version 2.1.0 (2016-02-16) diff --git a/docs/about/github_latest_release.txt b/docs/about/github_latest_release.txt index 0ea327a38..102656248 100644 --- a/docs/about/github_latest_release.txt +++ b/docs/about/github_latest_release.txt @@ -19,15 +19,15 @@ Version 2.3.0 (2016-02-26) New Features ~~~~~~~~~~~~ -- px4 compatability improvements +- PX4 compatibility improvements Updated Features ~~~~~~~~~~~~~~~~ - Documentation fixes - PIP repository improvements -- mode-setting API improvements -- ardupilot-solo compatability fixes +- Mode-setting API improvements +- ardupilot-solo compatibility fixes Version 2.2.0 (2016-02-19) -------------------------- @@ -36,8 +36,8 @@ Bug Fixes ~~~~~~~~~ - Splits outbound messages into its own thread. -- remove of capabilities request on HEARTBEAT listener -- check if mode\_mapping has items before iteration +- Remove of capabilities request on HEARTBEAT listener +- Check if mode\_mapping has items before iteration Version 2.1.0 (2016-02-16) -------------------------- From 6c4fe4c16274cbfc5c68ca4d2cd087a27618d7c9 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 24 Feb 2016 11:14:17 -0800 Subject: [PATCH 339/475] Swallow message errors and continue. --- dronekit/__init__.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 1105297a9..03f1e8c41 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1464,9 +1464,21 @@ def remove_message_listener(self, name, fn): def notify_message_listeners(self, name, msg): for fn in self._message_listeners.get(name, []): - fn(self, name, msg) + try: + fn(self, name, msg) + except Exception as e: + errprinter('>>> Exception in message handler for %s' % + msg.get_type()) + errprinter('>>> ' + str(e)) + for fn in self._message_listeners.get('*', []): - fn(self, name, msg) + try: + fn(self, name, msg) + except Exception as e: + errprinter('>>> Exception in message handler for %s' % + msg.get_type()) + errprinter('>>> ' + str(e)) + def close(self): return self._handler.close() From 2235c943c395116fa9c552be2303b476db1d08ac Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Wed, 24 Feb 2016 11:32:59 -0800 Subject: [PATCH 340/475] Swallow attribute errors and continue. --- dronekit/__init__.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 03f1e8c41..ff169b5c5 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -629,9 +629,20 @@ def notify_attribute_listeners(self, attr_name, value, cache=False): # Notify observers. for fn in self._attribute_listeners.get(attr_name, []): - fn(self, attr_name, value) + try: + fn(self, attr_name, value) + except Exception as e: + errprinter('>>> Exception in attribute handler for %s' % + attr_name) + errprinter('>>> ' + str(e)) + for fn in self._attribute_listeners.get('*', []): - fn(self, attr_name, value) + try: + fn(self, attr_name, value) + except Exception as e: + errprinter('>>> Exception in attribute handler for %s' % + attr_name) + errprinter('>>> ' + str(e)) def on_attribute(self, name): """ From 20c399f503f4640cd43860c00adc1481ba3fae3e Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Tue, 1 Mar 2016 22:22:38 +1100 Subject: [PATCH 341/475] Update taking_off.rst Takeoff was not calling simple-takeoff! --- docs/guide/taking_off.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/guide/taking_off.rst b/docs/guide/taking_off.rst index 0d9fc873f..725ce11e5 100644 --- a/docs/guide/taking_off.rst +++ b/docs/guide/taking_off.rst @@ -35,7 +35,7 @@ The code below shows a function to arm a Copter, take off, and fly to a specifie .. code-block:: python # Connect to the Vehicle (in this case a simulator running the same computer) - vehicle = connect('127.0.0.1:14550', wait_ready=True) + vehicle = connect('tcp:127.0.0.1:5760', wait_ready=True) def arm_and_takeoff(aTargetAltitude): """ @@ -59,6 +59,7 @@ The code below shows a function to arm a Copter, take off, and fly to a specifie time.sleep(1) print "Taking off!" + vehicle.simple_takeoff(aTargetAltitude) # Take off to target altitude # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.simple_takeoff will execute immediately). @@ -142,4 +143,4 @@ concerned about reaching a particular height, a simpler implementation might jus break time.sleep(1) -When the function returns the app can continue in ``GUIDED`` mode or switch to ``AUTO`` mode to start a mission. \ No newline at end of file +When the function returns the app can continue in ``GUIDED`` mode or switch to ``AUTO`` mode to start a mission. From f68ed65ef245a070d8dfcc96b7f709cb38ecf759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Roche?= Date: Tue, 1 Mar 2016 19:30:41 -0800 Subject: [PATCH 342/475] circleci use deployment command strategy --- circle.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/circle.yml b/circle.yml index 486707359..9c9c85cb7 100644 --- a/circle.yml +++ b/circle.yml @@ -20,3 +20,9 @@ test: general: build_dir: . + +deployment: + production: + branch: master + commands: + - ./scripts/update-docs.sh From 74c1e83ca277eefeda6137216a5e0691d4278d85 Mon Sep 17 00:00:00 2001 From: Adric Date: Sun, 13 Mar 2016 18:04:45 +1100 Subject: [PATCH 343/475] MAV Type for rover was incorrect. When connecting to AMPRovers this failed due to the incorrect type, This is now corrected --- dronekit/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index ff169b5c5..3bf612108 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -341,7 +341,7 @@ def __str__(self): prefix += "Copter-" elif(self.vehicle_type == mavutil.mavlink.MAV_TYPE_FIXED_WING): prefix += "Plane-" - elif(self.vehicle_type == mavutil.mavlink.MAV_TYPE_ROVER): + elif(self.vehicle_type == mavutil.mavlink.MAV_TYPE_GROUND_ROVER): prefix += "Rover-" else: prefix += "UnknownVehicleType%d-" % (self.vehicle_type) From 5baf4802553c0ed4accf7ac9c2fba19bd5efcd38 Mon Sep 17 00:00:00 2001 From: Fnoop Date: Mon, 4 Apr 2016 13:44:25 +0000 Subject: [PATCH 344/475] #610: Wrap iterable call in try..except to deal with unrecognised vehicle codes --- dronekit/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 3bf612108..c24746fb6 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1521,7 +1521,10 @@ def _mode_mapping_bynumber(self): return mavutil.mode_mapping_bynumber(self._vehicle_type) def _is_mode_available(self, mode_code): - return mode_code in self._mode_mapping_bynumber + try: + return mode_code in self._mode_mapping_bynumber + except: + return False # # Operations to support the standard API. From 485078a62fcbd0499e806af9dd342d32d787cb72 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 6 Apr 2016 08:20:07 +1000 Subject: [PATCH 345/475] Fix broken links on companion computer page --- docs/develop/companion-computers.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/develop/companion-computers.rst b/docs/develop/companion-computers.rst index 2bc19c4da..f18dcb2b7 100644 --- a/docs/develop/companion-computers.rst +++ b/docs/develop/companion-computers.rst @@ -15,21 +15,21 @@ The following computing platforms are known to work with DroneKit, and are suppo RaspberryPi ----------- -* `Communicating with Raspberry Pi via MAVLink `_ -* `Making a Mavlink WiFi bridge using the Raspberry Pi `_ +* `Communicating with Raspberry Pi via MAVLink `_ +* `Making a Mavlink WiFi bridge using the Raspberry Pi `_ Intel Edison ------------ -* `Edison for drones `_ +* `Edison for drones `_ BeagleBoneBlack --------------- -* `BeaglePilot `_ +* `BeaglePilot `_ Odroid ------ -* `Communicating with ODroid via MAVLink `_ -* `ODroid Wifi Access Point for sharing files via Samba `_ +* `Communicating with ODroid via MAVLink `_ +* `ODroid Wifi Access Point for sharing files via Samba `_ From 7d9777a92fca802be719622f13f157325ca7fa47 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 6 Apr 2016 16:54:44 +1000 Subject: [PATCH 346/475] drone_delivery: explain port to connect to --- examples/drone_delivery/drone_delivery.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/drone_delivery/drone_delivery.py b/examples/drone_delivery/drone_delivery.py index b3ff6fb56..c8f9f6e5a 100644 --- a/examples/drone_delivery/drone_delivery.py +++ b/examples/drone_delivery/drone_delivery.py @@ -109,7 +109,10 @@ def _run_server(self): 'log.screen': None }) - print 'http://localhost:8080/' + print('''Server is bound on all addresses, port 8080 +You may connect to it using your web broser using a URL looking like this: +http://localhost:8080/ +''') cherrypy.engine.start() def change_mode(self, mode): From a4f94c541dfcd6b5b445f743580ed23304dab027 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 8 Apr 2016 11:22:11 +1000 Subject: [PATCH 347/475] test_channels.py: remove infinite loop --- dronekit/test/sitl/test_channels.py | 1 + 1 file changed, 1 insertion(+) diff --git a/dronekit/test/sitl/test_channels.py b/dronekit/test/sitl/test_channels.py index 73132d3ab..44c484353 100644 --- a/dronekit/test/sitl/test_channels.py +++ b/dronekit/test/sitl/test_channels.py @@ -151,6 +151,7 @@ def channels_callback(vehicle, name, channels): i = 5 while not result['success'] and i > 0: time.sleep(.1) + i -= 1 assert result['success'], 'channels callback should be invoked.' vehicle.close() From 3723d47c5cc6539ea0aa3a0bba45cf1db87c33c4 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 6 Apr 2016 20:06:49 +1000 Subject: [PATCH 348/475] microgcs: use sitl, update for new API --- examples/gcs/microgcs.py | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/examples/gcs/microgcs.py b/examples/gcs/microgcs.py index 78cf190af..b0db21ec4 100644 --- a/examples/gcs/microgcs.py +++ b/examples/gcs/microgcs.py @@ -12,14 +12,26 @@ #Set up option parsing to get connection string import argparse parser = argparse.ArgumentParser(description='Tracks GPS position of your computer (Linux only). Connects to SITL on local PC by default.') -parser.add_argument('--connect', default='127.0.0.1:14550', - help="vehicle connection target. Default '127.0.0.1:14550'") +parser.add_argument('--connect', + help="vehicle connection target.") args = parser.parse_args() +connection_string = args.connect +sitl = None + +#Start SITL if no connection string specified +if not args.connect: + print "Starting copter simulator (SITL)" + from dronekit_sitl import SITL + sitl = SITL() + sitl.download('copter', '3.3', verbose=True) + sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] + sitl.launch(sitl_args, await_ready=True, restart=True) + connection_string = 'tcp:127.0.0.1:5760' # Connect to the Vehicle -print 'Connecting to vehicle on: %s' % args.connect -vehicle = connect(args.connect, wait_ready=True) +print 'Connecting to vehicle on: %s' % connection_string +vehicle = connect(connection_string, wait_ready=True) def setMode(mode): # Now change the vehicle into auto mode @@ -31,8 +43,7 @@ def updateGUI(label, value): def addObserverAndInit(name, cb): """We go ahead and call our observer once at startup to get an initial value""" - cb(name) - vehicle.add_attribute_observer(name, cb) + vehicle.add_attribute_listener(name, cb) root = Tk() root.wm_title("microGCS - the worlds crummiest GCS") @@ -46,11 +57,15 @@ def addObserverAndInit(name, cb): modeLabel = Label(frame, text = "mode") modeLabel.pack() -addObserverAndInit('attitude', lambda attr: updateGUI(attitudeLabel, vehicle.attitude)) -addObserverAndInit('location', lambda attr: updateGUI(locationLabel, vehicle.location)) -addObserverAndInit('mode', lambda attr: updateGUI(modeLabel, vehicle.mode)) +addObserverAndInit('attitude', lambda vehicle, name, attitude: updateGUI(attitudeLabel, vehicle.attitude)) +addObserverAndInit('location', lambda vehicle, name, location: updateGUI(locationLabel, str(location.global_frame))) +addObserverAndInit('mode', lambda vehicle,name,mode: updateGUI(modeLabel, mode)) Button(frame, text = "Auto", command = lambda : setMode("AUTO")).pack() Button(frame, text = "RTL", command = lambda : setMode("RTL")).pack() -root.mainloop() \ No newline at end of file +root.mainloop() + +# Shut down simulator if it was started. +if sitl is not None: + sitl.stop() From 9c150a2f9b1db8020b9ba851178e5528a7091184 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Tue, 16 Feb 2016 14:56:09 +1100 Subject: [PATCH 349/475] Reorder instructions in quickstart guide --- docs/guide/quick_start.rst | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/guide/quick_start.rst b/docs/guide/quick_start.rst index 38cf20663..03552b06d 100644 --- a/docs/guide/quick_start.rst +++ b/docs/guide/quick_start.rst @@ -13,14 +13,8 @@ Installation ============ DroneKit-Python and the *dronekit-sitl simulator* are installed -from **pip** on all platforms: +from **pip** on all platforms. -.. code-block:: bash - - pip install dronekit - pip install dronekit-sitl - -Mac and Linux require you prefix the command with ``sudo``. On Linux you will first need to install **pip** and **python-dev**: .. code-block:: bash @@ -28,6 +22,14 @@ On Linux you will first need to install **pip** and **python-dev**: sudo apt-get install python-pip python-dev +**pip** is then used to install *dronekit* and *dronekit-sitl*. +Mac and Linux may require you to prefix these commands with ``sudo``: + +.. code-block:: bash + + pip install dronekit + pip install dronekit-sitl + See :doc:`../develop/installation` and `dronekit-sitl `_ for more detailed installation instructions. From 83195d0d7454289a1b38c9f7b63d350322c85c7b Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 5 Feb 2016 11:55:45 +1100 Subject: [PATCH 350/475] Make running dronekit examples possible in Vagrant Add some extra packages. Create a private network to host machine --- Vagrantfile | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Vagrantfile b/Vagrantfile index 77610a6fa..d916140aa 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -3,6 +3,7 @@ Vagrant.configure(2) do |config| config.vm.box = "ubuntu/trusty64" + config.vm.network "private_network", type: "dhcp" config.vm.provision "shell", inline: <<-SHELL apt-get -y update @@ -13,6 +14,12 @@ Vagrant.configure(2) do |config| echo "[DroneKit]: Installing pip ..." apt-get -y install python-pip easy_install -U pip + echo "[DroneKit]: Installing python-cherrypy3 ..." + apt-get -y install python-cherrypy3 + echo "[DroneKit]: Installing python-matplotlib ..." + apt-get -y install python-matplotlib + echo "[DroneKit]: Installing python-gps ..." + apt-get -y install python-gps echo "[DroneKit]: Installing Sphinx ... " pip install sphinx cd /vagrant From c2c4745ef283025d9e4d17690b21ef921bd242a8 Mon Sep 17 00:00:00 2001 From: fnoop Date: Sun, 17 Apr 2016 07:46:58 +0000 Subject: [PATCH 351/475] #610: Add test case that triggers the bug --- dronekit/test/sitl/test_modeavailable.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 dronekit/test/sitl/test_modeavailable.py diff --git a/dronekit/test/sitl/test_modeavailable.py b/dronekit/test/sitl/test_modeavailable.py new file mode 100644 index 000000000..8e7b311fb --- /dev/null +++ b/dronekit/test/sitl/test_modeavailable.py @@ -0,0 +1,24 @@ +""" +This test represents a simple demo for testing. +Feel free to copy and modify at your leisure. +""" + +import time +import sys +import os +from dronekit import connect, VehicleMode +from dronekit.test import with_sitl +from nose.tools import assert_equals + +@with_sitl +def test_timeout(connpath): + v = connect(connpath) + + # Set the vehicle and autopilot type to 'unsupported' types that MissionPlanner uses as of 17.Apr.2016 + v._vehicle_type = 6 + v._autopilot_type = 8 + + # The above types trigger 'TypeError: argument of type 'NoneType' is not iterable' which is addressed in issue #610 + is_available = v._is_mode_available(0) + + v.close() From 7ae2c5196cc450048060bdecd01e936c3a70afd4 Mon Sep 17 00:00:00 2001 From: fnoop Date: Sun, 17 Apr 2016 07:54:24 +0000 Subject: [PATCH 352/475] Update test description --- dronekit/test/sitl/test_modeavailable.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dronekit/test/sitl/test_modeavailable.py b/dronekit/test/sitl/test_modeavailable.py index 8e7b311fb..2796f7ad3 100644 --- a/dronekit/test/sitl/test_modeavailable.py +++ b/dronekit/test/sitl/test_modeavailable.py @@ -1,6 +1,5 @@ """ -This test represents a simple demo for testing. -Feel free to copy and modify at your leisure. +Simple test to trigger a bug in Vehicle class: issue #610 fixed in PR #611 """ import time From 2a66dcc25d403f6371585fe3d2f70f0ec1781f03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Roche?= Date: Wed, 4 May 2016 10:57:42 -0700 Subject: [PATCH 353/475] bump 2.5.0 --- CHANGELOG.md | 18 ++++++++++++++++++ docs/about/github_latest_release.txt | 21 +++++++++++++++++++++ setup.py | 2 +- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2fe4c4c4..7014c0cc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## Version 2.5.0 (2016-05-04) + +### Improvements +* Catch and display message and attribute errors, then continue +* Improved takeoff example docs +* Deploy docs on successful merge into master (from CircleCI) +* Drone delivery example, explain port to connect +* MicroCGS example now uses SITL +* Make running examples possible on Vagrant + +### Bug Fixes +* Mav type for rover was incorrect +* `_is_mode_available` can now handle unrecognized mode codes +* Fix broken links on companion computer page +* Fix infinite loop on channel test + + + ## Version 2.4.0 (2016-02-29) ### Bug Fixes diff --git a/docs/about/github_latest_release.txt b/docs/about/github_latest_release.txt index 102656248..75e5b3248 100644 --- a/docs/about/github_latest_release.txt +++ b/docs/about/github_latest_release.txt @@ -3,6 +3,27 @@ Changelog ========= +Version 2.5.0 (2016-05-04) +-------------------------- + +Improvements +~~~~~~~~~~~~ + +- Catch and display message and attribute errors, then continue +- Improved takeoff example docs +- Deploy docs on successful merge into master (from CircleCI) +- Drone delivery example, explain port to connect +- MicroCGS example now uses SITL +- Make running examples possible on Vagrant + +Bug Fixes +~~~~~~~~~ + +- Mav type for rover was incorrect +- ``_is_mode_available`` can now handle unrecognized mode codes +- Fix broken links on companion computer page +- Fix infinite loop on channel test + Version 2.4.0 (2016-02-29) -------------------------- diff --git a/setup.py b/setup.py index d0b4d8835..96099ecfa 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.4.0' +version = '2.5.0' setup(name='dronekit', zip_safe=True, From dd8d2ce014bbaf3b208e814753b56cfb8adffd5b Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 14 May 2016 16:06:37 +1000 Subject: [PATCH 354/475] Use dronekit_sitl start_default to remove boilerplate --- .../channel_overrides/channel_overrides.py | 12 ++++------- examples/create_attribute/create_attribute.py | 12 ++++------- examples/drone_delivery/drone_delivery.py | 13 +++++------- examples/flight_replay/flight_replay.py | 20 +++---------------- examples/follow_me/follow_me.py | 13 ++++-------- examples/gcs/microgcs.py | 12 ++++------- .../guided_set_speed_yaw.py | 12 ++++------- examples/mission_basic/mission_basic.py | 12 ++++------- .../mission_import_export.py | 12 ++++------- examples/performance_test/performance_test.py | 13 +++++------- examples/simple_goto/simple_goto.py | 12 ++++------- examples/vehicle_state/vehicle_state.py | 12 ++++------- 12 files changed, 49 insertions(+), 106 deletions(-) diff --git a/examples/channel_overrides/channel_overrides.py b/examples/channel_overrides/channel_overrides.py index 424733a23..c6b1a2c81 100644 --- a/examples/channel_overrides/channel_overrides.py +++ b/examples/channel_overrides/channel_overrides.py @@ -27,14 +27,10 @@ #Start SITL if no connection string specified -if not args.connect: - print "Starting copter simulator (SITL)" - from dronekit_sitl import SITL - sitl = SITL() - sitl.download('copter', '3.3', verbose=True) - sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] - sitl.launch(sitl_args, await_ready=True, restart=True) - connection_string = 'tcp:127.0.0.1:5760' +if not connection_string: + import dronekit_sitl + sitl = dronekit_sitl.start_default() + connection_string = sitl.connection_string() # Connect to the Vehicle diff --git a/examples/create_attribute/create_attribute.py b/examples/create_attribute/create_attribute.py index 3fce5693a..ee5c9f373 100644 --- a/examples/create_attribute/create_attribute.py +++ b/examples/create_attribute/create_attribute.py @@ -28,14 +28,10 @@ #Start SITL if no connection string specified -if not args.connect: - print "Starting copter simulator (SITL)" - from dronekit_sitl import SITL - sitl = SITL() - sitl.download('copter', '3.3', verbose=True) - sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] - sitl.launch(sitl_args, await_ready=True, restart=True) - connection_string = 'tcp:127.0.0.1:5760' +if not connection_string: + import dronekit_sitl + sitl = dronekit_sitl.start_default() + connection_string = sitl.connection_string() # Connect to the Vehicle diff --git a/examples/drone_delivery/drone_delivery.py b/examples/drone_delivery/drone_delivery.py index c8f9f6e5a..861f7aee2 100644 --- a/examples/drone_delivery/drone_delivery.py +++ b/examples/drone_delivery/drone_delivery.py @@ -24,14 +24,11 @@ connection_string=args.connect -if not args.connect: - print "Starting copter simulator (SITL)" - from dronekit_sitl import SITL - sitl = SITL() - sitl.download('copter', '3.3', verbose=True) - sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] - sitl.launch(sitl_args, await_ready=True, restart=True) - connection_string='tcp:127.0.0.1:5760' +#Start SITL if no connection string specified +if not connection_string: + import dronekit_sitl + sitl = dronekit_sitl.start_default() + connection_string = sitl.connection_string() local_path=os.path.dirname(os.path.abspath(__file__)) print "local path: %s" % local_path diff --git a/examples/flight_replay/flight_replay.py b/examples/flight_replay/flight_replay.py index 02ac8456b..11e85ef1a 100644 --- a/examples/flight_replay/flight_replay.py +++ b/examples/flight_replay/flight_replay.py @@ -21,22 +21,6 @@ args = parser.parse_args() -def start_default_sitl(lat=None, lon=None): - print "Starting copter simulator (SITL)" - from dronekit_sitl import SITL - sitl = SITL() - sitl.download('copter', '3.3', verbose=True) - if ((lat is not None and lon is None) or - (lat is None and lon is not None)): - print("Supply both lat and lon, or neither") - exit(1) - sitl_args = ['-I0', '--model', 'quad', ] - if lat is not None: - sitl_args.append('--home=%f,%f,584,353' % (lat,lon,)) - sitl.launch(sitl_args, await_ready=True, restart=True) - connection_string='tcp:127.0.0.1:5760' - return (sitl, connection_string) - def get_distance_metres(aLocation1, aLocation2): """ Returns the ground distance in metres between two LocationGlobal objects. @@ -164,7 +148,9 @@ def arm_and_takeoff(aTargetAltitude): start_lat = messages[0].lat/1.0e7 start_lon = messages[0].lon/1.0e7 - (sitl, connection_string) = start_default_sitl(lat=start_lat,lon=start_lon) + import dronekit_sitl + sitl = dronekit_sitl.start_default(lat=start_lat,lon=start_lon) + connection_string = sitl.connection_string() # Connect to the Vehicle print 'Connecting to vehicle on: %s' % connection_string diff --git a/examples/follow_me/follow_me.py b/examples/follow_me/follow_me.py index b62b32a5f..65e4feb52 100644 --- a/examples/follow_me/follow_me.py +++ b/examples/follow_me/follow_me.py @@ -28,15 +28,10 @@ #Start SITL if no connection string specified -if not args.connect: - print "Starting copter simulator (SITL)" - from dronekit_sitl import SITL - sitl = SITL() - sitl.download('copter', '3.3', verbose=True) - sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] - sitl.launch(sitl_args, await_ready=True, restart=True) - connection_string = 'tcp:127.0.0.1:5760' - +if not connection_string: + import dronekit_sitl + sitl = dronekit_sitl.start_default() + connection_string = sitl.connection_string() # Connect to the Vehicle print 'Connecting to vehicle on: %s' % connection_string diff --git a/examples/gcs/microgcs.py b/examples/gcs/microgcs.py index b0db21ec4..d61377f0b 100644 --- a/examples/gcs/microgcs.py +++ b/examples/gcs/microgcs.py @@ -20,14 +20,10 @@ sitl = None #Start SITL if no connection string specified -if not args.connect: - print "Starting copter simulator (SITL)" - from dronekit_sitl import SITL - sitl = SITL() - sitl.download('copter', '3.3', verbose=True) - sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] - sitl.launch(sitl_args, await_ready=True, restart=True) - connection_string = 'tcp:127.0.0.1:5760' +if not connection_string: + import dronekit_sitl + sitl = dronekit_sitl.start_default() + connection_string = sitl.connection_string() # Connect to the Vehicle print 'Connecting to vehicle on: %s' % connection_string diff --git a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py index b81f0bb6f..3d6df8bdc 100644 --- a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py +++ b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py @@ -25,14 +25,10 @@ #Start SITL if no connection string specified -if not args.connect: - print "Starting copter simulator (SITL)" - from dronekit_sitl import SITL - sitl = SITL() - sitl.download('copter', '3.3', verbose=True) - sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] - sitl.launch(sitl_args, await_ready=True, restart=True) - connection_string='tcp:127.0.0.1:5760' +if not connection_string: + import dronekit_sitl + sitl = dronekit_sitl.start_default() + connection_string = sitl.connection_string() # Connect to the Vehicle diff --git a/examples/mission_basic/mission_basic.py b/examples/mission_basic/mission_basic.py index d98f85af9..c3c78a818 100644 --- a/examples/mission_basic/mission_basic.py +++ b/examples/mission_basic/mission_basic.py @@ -22,14 +22,10 @@ #Start SITL if no connection string specified -if not args.connect: - print "Starting copter simulator (SITL)" - from dronekit_sitl import SITL - sitl = SITL() - sitl.download('copter', '3.3', verbose=True) - sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] - sitl.launch(sitl_args, await_ready=True, restart=True) - connection_string='tcp:127.0.0.1:5760' +if not connection_string: + import dronekit_sitl + sitl = dronekit_sitl.start_default() + connection_string = sitl.connection_string() # Connect to the Vehicle diff --git a/examples/mission_import_export/mission_import_export.py b/examples/mission_import_export/mission_import_export.py index 5b5cff6f8..9c805afee 100644 --- a/examples/mission_import_export/mission_import_export.py +++ b/examples/mission_import_export/mission_import_export.py @@ -25,14 +25,10 @@ #Start SITL if no connection string specified -if not args.connect: - print "Starting copter simulator (SITL)" - from dronekit_sitl import SITL - sitl = SITL() - sitl.download('copter', '3.3', verbose=True) - sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] - sitl.launch(sitl_args, await_ready=True, restart=True) - connection_string='tcp:127.0.0.1:5760' +if not connection_string: + import dronekit_sitl + sitl = dronekit_sitl.start_default() + connection_string = sitl.connection_string() # Connect to the Vehicle diff --git a/examples/performance_test/performance_test.py b/examples/performance_test/performance_test.py index 0f7ba1bb0..f349232a5 100644 --- a/examples/performance_test/performance_test.py +++ b/examples/performance_test/performance_test.py @@ -24,14 +24,11 @@ connection_string=args.connect -if not args.connect: - print "Starting copter simulator (SITL)" - from dronekit_sitl import SITL - sitl = SITL() - sitl.download('copter', '3.3', verbose=True) - sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] - sitl.launch(sitl_args, await_ready=True, restart=True) - connection_string='tcp:127.0.0.1:5760' +#Start SITL if no connection string specified +if not connection_string: + import dronekit_sitl + sitl = dronekit_sitl.start_default() + connection_string = sitl.connection_string() # Connect to the Vehicle diff --git a/examples/simple_goto/simple_goto.py b/examples/simple_goto/simple_goto.py index b2e581dc2..208ed1d01 100644 --- a/examples/simple_goto/simple_goto.py +++ b/examples/simple_goto/simple_goto.py @@ -22,14 +22,10 @@ #Start SITL if no connection string specified -if not args.connect: - print "Starting copter simulator (SITL)" - from dronekit_sitl import SITL - sitl = SITL() - sitl.download('copter', '3.3', verbose=True) - sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] - sitl.launch(sitl_args, await_ready=True, restart=True) - connection_string = 'tcp:127.0.0.1:5760' +if not connection_string: + import dronekit_sitl + sitl = dronekit_sitl.start_default() + connection_string = sitl.connection_string() # Connect to the Vehicle diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 1d73e1de4..568351172 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -21,14 +21,10 @@ #Start SITL if no connection string specified -if not args.connect: - print "Starting copter simulator (SITL)" - from dronekit_sitl import SITL - sitl = SITL() - sitl.download('copter', '3.3', verbose=True) - sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] - sitl.launch(sitl_args, await_ready=True, restart=True) - connection_string = 'tcp:127.0.0.1:5760' +if not connection_string: + import dronekit_sitl + sitl = dronekit_sitl.start_default() + connection_string = sitl.connection_string() # Connect to the Vehicle. From 4bb2d7c9155cb94108f64765cb44b9b6c634a37e Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Mon, 16 May 2016 11:18:50 +1000 Subject: [PATCH 355/475] Update quick start guide for start_default --- docs/guide/quick_start.rst | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/guide/quick_start.rst b/docs/guide/quick_start.rst index 03552b06d..7dc795e04 100644 --- a/docs/guide/quick_start.rst +++ b/docs/guide/quick_start.rst @@ -46,18 +46,16 @@ we then use to query the attributes. .. code:: python print "Start simulator (SITL)" - from dronekit_sitl import SITL - sitl = SITL() - sitl.download('copter', '3.3', verbose=True) - sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353'] - sitl.launch(sitl_args, await_ready=True, restart=True) + import dronekit_sitl + sitl = dronekit_sitl.start_default() + connection_string = sitl.connection_string() # Import DroneKit-Python from dronekit import connect, VehicleMode # Connect to the Vehicle. - print "Connecting to vehicle on: 'tcp:127.0.0.1:5760'" - vehicle = connect('tcp:127.0.0.1:5760', wait_ready=True) + print("Connecting to vehicle on: %s" % (connection_string,)) + vehicle = connect(connection_string, wait_ready=True) # Get some vehicle attributes (state) print "Get some vehicle attribute values:" From 55a993b40292e16bc67ec4a6311d6650cc9ee6e1 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Tue, 24 May 2016 09:18:44 +1000 Subject: [PATCH 356/475] Pass kwargs through in monkey-patched sendfn --- dronekit/mavlink.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dronekit/mavlink.py b/dronekit/mavlink.py index c60b0d90e..454882dc2 100644 --- a/dronekit/mavlink.py +++ b/dronekit/mavlink.py @@ -52,9 +52,9 @@ def __init__(self, ip, baud=115200, target_system=0, source_system=255, use_nati # Monkey-patch MAVLink object for fix_targets. sendfn = self.master.mav.send - def newsendfn(mavmsg): + def newsendfn(mavmsg, **kwargs): self.fix_targets(mavmsg) - return sendfn(mavmsg) + return sendfn(mavmsg, kwargs) self.master.mav.send = newsendfn From 8f9e2ac1867182aa622da3d2282a3a93f7d4aa46 Mon Sep 17 00:00:00 2001 From: Brenton Sutherland Date: Thu, 26 May 2016 13:05:40 -0300 Subject: [PATCH 357/475] Added copyright notice to example files. --- examples/channel_overrides/channel_overrides.py | 2 ++ examples/create_attribute/create_attribute.py | 2 ++ examples/create_attribute/my_vehicle.py | 2 ++ examples/drone_delivery/drone_delivery.py | 1 + examples/flight_replay/flight_replay.py | 1 + examples/follow_me/follow_me.py | 1 + examples/gcs/microgcs.py | 3 +++ examples/guided_set_speed_yaw/guided_set_speed_yaw.py | 1 + examples/mission_basic/mission_basic.py | 1 + examples/mission_import_export/mission_import_export.py | 1 + examples/performance_test/performance_test.py | 1 + examples/simple_goto/simple_goto.py | 1 + examples/vehicle_state/vehicle_state.py | 1 + 13 files changed, 18 insertions(+) diff --git a/examples/channel_overrides/channel_overrides.py b/examples/channel_overrides/channel_overrides.py index c6b1a2c81..1d8b879ec 100644 --- a/examples/channel_overrides/channel_overrides.py +++ b/examples/channel_overrides/channel_overrides.py @@ -1,4 +1,6 @@ """ +© Copyright 2015-2016, 3D Robotics. + channel_overrides.py: Demonstrates how set and clear channel-override information. diff --git a/examples/create_attribute/create_attribute.py b/examples/create_attribute/create_attribute.py index ee5c9f373..e3c696f80 100644 --- a/examples/create_attribute/create_attribute.py +++ b/examples/create_attribute/create_attribute.py @@ -1,4 +1,6 @@ """ +© Copyright 2015-2016, 3D Robotics. + create_attribute.py: Demonstrates how to create attributes from MAVLink messages within your DroneKit-Python script diff --git a/examples/create_attribute/my_vehicle.py b/examples/create_attribute/my_vehicle.py index 2b56a352e..72255dcb7 100644 --- a/examples/create_attribute/my_vehicle.py +++ b/examples/create_attribute/my_vehicle.py @@ -1,4 +1,6 @@ """ +© Copyright 2015-2016, 3D Robotics. + my_vehicle.py: Custom Vehicle subclass to add IMU data. diff --git a/examples/drone_delivery/drone_delivery.py b/examples/drone_delivery/drone_delivery.py index 861f7aee2..41f643191 100644 --- a/examples/drone_delivery/drone_delivery.py +++ b/examples/drone_delivery/drone_delivery.py @@ -1,4 +1,5 @@ """ +© Copyright 2015-2016, 3D Robotics. drone_delivery.py: A CherryPy based web application that displays a mapbox map to let you view the current vehicle position and send the vehicle commands to fly to a particular latitude and longitude. diff --git a/examples/flight_replay/flight_replay.py b/examples/flight_replay/flight_replay.py index 11e85ef1a..e64d57141 100644 --- a/examples/flight_replay/flight_replay.py +++ b/examples/flight_replay/flight_replay.py @@ -1,4 +1,5 @@ """ +© Copyright 2015-2016, 3D Robotics. flight_replay.py: This example requests a past flight from Droneshare, and then 'replays' diff --git a/examples/follow_me/follow_me.py b/examples/follow_me/follow_me.py index 65e4feb52..fd8af6738 100644 --- a/examples/follow_me/follow_me.py +++ b/examples/follow_me/follow_me.py @@ -1,4 +1,5 @@ """ +© Copyright 2015-2016, 3D Robotics. followme - Tracks GPS position of your computer (Linux only). This example uses the python gps package to read positions from a GPS attached to your diff --git a/examples/gcs/microgcs.py b/examples/gcs/microgcs.py index d61377f0b..ff8f98c9c 100644 --- a/examples/gcs/microgcs.py +++ b/examples/gcs/microgcs.py @@ -1,3 +1,6 @@ +""" +© Copyright 2015-2016, 3D Robotics. +""" # # This is a small example of the python drone API - an ultra minimal GCS # diff --git a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py index 3d6df8bdc..4dda42cd7 100644 --- a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py +++ b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py @@ -1,5 +1,6 @@ """ +© Copyright 2015-2016, 3D Robotics. guided_set_speed_yaw.py: (Copter Only) This example shows how to move/direct Copter and send commands in GUIDED mode using DroneKit Python. diff --git a/examples/mission_basic/mission_basic.py b/examples/mission_basic/mission_basic.py index c3c78a818..704fd6e6e 100644 --- a/examples/mission_basic/mission_basic.py +++ b/examples/mission_basic/mission_basic.py @@ -1,4 +1,5 @@ """ +© Copyright 2015-2016, 3D Robotics. mission_basic.py: Example demonstrating basic mission operations including creating, clearing and monitoring missions. Full documentation is provided at http://python.dronekit.io/examples/mission_basic.html diff --git a/examples/mission_import_export/mission_import_export.py b/examples/mission_import_export/mission_import_export.py index 9c805afee..201668d82 100644 --- a/examples/mission_import_export/mission_import_export.py +++ b/examples/mission_import_export/mission_import_export.py @@ -1,4 +1,5 @@ """ +© Copyright 2015-2016, 3D Robotics. mission_import_export.py: This example demonstrates how to import and export files in the Waypoint file format diff --git a/examples/performance_test/performance_test.py b/examples/performance_test/performance_test.py index f349232a5..0775431aa 100644 --- a/examples/performance_test/performance_test.py +++ b/examples/performance_test/performance_test.py @@ -1,4 +1,5 @@ """ +© Copyright 2015-2016, 3D Robotics. performance_test.py: This performance test logs the interval between messages being diff --git a/examples/simple_goto/simple_goto.py b/examples/simple_goto/simple_goto.py index 208ed1d01..41c986505 100644 --- a/examples/simple_goto/simple_goto.py +++ b/examples/simple_goto/simple_goto.py @@ -1,4 +1,5 @@ """ +© Copyright 2015-2016, 3D Robotics. simple_goto.py: GUIDED mode "simple goto" example (Copter Only) Demonstrates how to arm and takeoff in Copter and how to navigate to points using Vehicle.simple_goto. diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 568351172..314b034dc 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -1,4 +1,5 @@ """ +© Copyright 2015-2016, 3D Robotics. vehicle_state.py: Demonstrates how to get and set vehicle state and parameter information, From beacf4c3dc24b3bf3c548acd13d2d35fda10b2af Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 1 Jun 2016 13:05:20 +1000 Subject: [PATCH 358/475] Examples: set document character set encoding The recent addition of the copyright symbol into the code causes issues on some versions of Python - the scripts don't run. We now define the encoding according to https://www.python.org/dev/peps/pep-0263/ --- examples/channel_overrides/channel_overrides.py | 3 +++ examples/create_attribute/create_attribute.py | 3 +++ examples/create_attribute/my_vehicle.py | 3 +++ examples/drone_delivery/drone_delivery.py | 3 +++ examples/flight_replay/flight_replay.py | 3 +++ examples/follow_me/follow_me.py | 3 +++ examples/gcs/microgcs.py | 3 +++ examples/guided_set_speed_yaw/guided_set_speed_yaw.py | 2 ++ examples/mission_basic/mission_basic.py | 3 +++ examples/mission_import_export/mission_import_export.py | 3 +++ examples/performance_test/performance_test.py | 3 +++ examples/simple_goto/simple_goto.py | 3 +++ examples/vehicle_state/vehicle_state.py | 3 +++ 13 files changed, 38 insertions(+) diff --git a/examples/channel_overrides/channel_overrides.py b/examples/channel_overrides/channel_overrides.py index 1d8b879ec..a44f4f132 100644 --- a/examples/channel_overrides/channel_overrides.py +++ b/examples/channel_overrides/channel_overrides.py @@ -1,3 +1,6 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + """ © Copyright 2015-2016, 3D Robotics. diff --git a/examples/create_attribute/create_attribute.py b/examples/create_attribute/create_attribute.py index e3c696f80..5aa154f4b 100644 --- a/examples/create_attribute/create_attribute.py +++ b/examples/create_attribute/create_attribute.py @@ -1,3 +1,6 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + """ © Copyright 2015-2016, 3D Robotics. diff --git a/examples/create_attribute/my_vehicle.py b/examples/create_attribute/my_vehicle.py index 72255dcb7..01f12cea1 100644 --- a/examples/create_attribute/my_vehicle.py +++ b/examples/create_attribute/my_vehicle.py @@ -1,3 +1,6 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + """ © Copyright 2015-2016, 3D Robotics. diff --git a/examples/drone_delivery/drone_delivery.py b/examples/drone_delivery/drone_delivery.py index 41f643191..db2229784 100644 --- a/examples/drone_delivery/drone_delivery.py +++ b/examples/drone_delivery/drone_delivery.py @@ -1,3 +1,6 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + """ © Copyright 2015-2016, 3D Robotics. drone_delivery.py: diff --git a/examples/flight_replay/flight_replay.py b/examples/flight_replay/flight_replay.py index e64d57141..04f0a599c 100644 --- a/examples/flight_replay/flight_replay.py +++ b/examples/flight_replay/flight_replay.py @@ -1,3 +1,6 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + """ © Copyright 2015-2016, 3D Robotics. flight_replay.py: diff --git a/examples/follow_me/follow_me.py b/examples/follow_me/follow_me.py index fd8af6738..bd89a4e96 100644 --- a/examples/follow_me/follow_me.py +++ b/examples/follow_me/follow_me.py @@ -1,3 +1,6 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + """ © Copyright 2015-2016, 3D Robotics. followme - Tracks GPS position of your computer (Linux only). diff --git a/examples/gcs/microgcs.py b/examples/gcs/microgcs.py index ff8f98c9c..1ebee38f4 100644 --- a/examples/gcs/microgcs.py +++ b/examples/gcs/microgcs.py @@ -1,3 +1,6 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + """ © Copyright 2015-2016, 3D Robotics. """ diff --git a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py index 4dda42cd7..0c161b6af 100644 --- a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py +++ b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- """ © Copyright 2015-2016, 3D Robotics. diff --git a/examples/mission_basic/mission_basic.py b/examples/mission_basic/mission_basic.py index 704fd6e6e..4255ec25c 100644 --- a/examples/mission_basic/mission_basic.py +++ b/examples/mission_basic/mission_basic.py @@ -1,3 +1,6 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + """ © Copyright 2015-2016, 3D Robotics. mission_basic.py: Example demonstrating basic mission operations including creating, clearing and monitoring missions. diff --git a/examples/mission_import_export/mission_import_export.py b/examples/mission_import_export/mission_import_export.py index 201668d82..13a96c0d3 100644 --- a/examples/mission_import_export/mission_import_export.py +++ b/examples/mission_import_export/mission_import_export.py @@ -1,3 +1,6 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + """ © Copyright 2015-2016, 3D Robotics. mission_import_export.py: diff --git a/examples/performance_test/performance_test.py b/examples/performance_test/performance_test.py index 0775431aa..7758a5440 100644 --- a/examples/performance_test/performance_test.py +++ b/examples/performance_test/performance_test.py @@ -1,3 +1,6 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + """ © Copyright 2015-2016, 3D Robotics. performance_test.py: diff --git a/examples/simple_goto/simple_goto.py b/examples/simple_goto/simple_goto.py index 41c986505..b38e3b2d7 100644 --- a/examples/simple_goto/simple_goto.py +++ b/examples/simple_goto/simple_goto.py @@ -1,3 +1,6 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + """ © Copyright 2015-2016, 3D Robotics. simple_goto.py: GUIDED mode "simple goto" example (Copter Only) diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 314b034dc..4518533e1 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -1,3 +1,6 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + """ © Copyright 2015-2016, 3D Robotics. vehicle_state.py: From d2db2e71f12d6df717c8bae2becec739aa06dbd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Roche?= Date: Fri, 17 Jun 2016 10:27:02 -0700 Subject: [PATCH 359/475] bump 2.6.0 --- CHANGELOG.md | 5 +++++ docs/about/github_latest_release.txt | 8 ++++++++ setup.py | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7014c0cc7..a1bb180e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## Version 2.6.0 (2016-06-17) + +### Bug Fixes +* Fixes patched mavutil sendfn + ## Version 2.5.0 (2016-05-04) ### Improvements diff --git a/docs/about/github_latest_release.txt b/docs/about/github_latest_release.txt index 75e5b3248..c5fe267b6 100644 --- a/docs/about/github_latest_release.txt +++ b/docs/about/github_latest_release.txt @@ -3,6 +3,14 @@ Changelog ========= +Version 2.6.0 (2016-06-17) +-------------------------- + +Bug Fixes +~~~~~~~~~ + +- Fixes patched mavutil sendfn + Version 2.5.0 (2016-05-04) -------------------------- diff --git a/setup.py b/setup.py index 96099ecfa..071d64836 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.5.0' +version = '2.6.0' setup(name='dronekit', zip_safe=True, From 1c9d64327d36c675a9a6a24c5b997bdd748b0f13 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Fri, 17 Jun 2016 10:33:49 -0400 Subject: [PATCH 360/475] Supports udpin: with multiple endpoints. --- dronekit/mavlink.py | 79 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/dronekit/mavlink.py b/dronekit/mavlink.py index 454882dc2..a82ef1e10 100644 --- a/dronekit/mavlink.py +++ b/dronekit/mavlink.py @@ -1,6 +1,7 @@ from __future__ import print_function import time import socket +import errno import sys import os import platform @@ -37,9 +38,85 @@ def read(self): os._exit(43) +class mavudpin_multi(mavutil.mavfile): + '''a UDP mavlink socket''' + def __init__(self, device, baud=None, input=True, broadcast=False, source_system=255, use_native=mavutil.default_native): + a = device.split(':') + if len(a) != 2: + print("UDP ports must be specified as host:port") + sys.exit(1) + self.port = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self.udp_server = input + self.broadcast = False + self.addresses = set() + if input: + self.port.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.port.bind((a[0], int(a[1]))) + else: + self.destination_addr = (a[0], int(a[1])) + if broadcast: + self.port.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + self.broadcast = True + mavutil.set_close_on_exec(self.port.fileno()) + self.port.setblocking(0) + mavutil.mavfile.__init__(self, self.port.fileno(), device, source_system=source_system, input=input, use_native=use_native) + + def close(self): + self.port.close() + + def recv(self,n=None): + try: + try: + data, new_addr = self.port.recvfrom(65535) + except socket.error as e: + if e.errno in [ errno.EAGAIN, errno.EWOULDBLOCK, errno.ECONNREFUSED ]: + return "" + if self.udp_server: + self.addresses.add(new_addr) + elif self.broadcast: + self.addresses = set([new_addr]) + return data + except Exception as e: + print(e) + + def write(self, buf): + try: + try: + if self.udp_server: + for addr in self.addresses: + self.port.sendto(buf, addr) + else: + if len(self.addresses) and self.broadcast: + self.destination_addr = self.addresses[0] + self.broadcast = False + self.port.connect(self.destination_addr) + self.port.sendto(buf, self.destination_addr) + except socket.error: + pass + except Exception as e: + print(e) + + def recv_msg(self): + '''message receive routine for UDP link''' + self.pre_message() + s = self.recv() + if len(s) > 0: + if self.first_byte: + self.auto_mavlink_version(s) + + m = self.mav.parse_char(s) + if m is not None: + self.post_message(m) + + return m + + class MAVConnection(object): def __init__(self, ip, baud=115200, target_system=0, source_system=255, use_native=False): - self.master = mavutil.mavlink_connection(ip, baud=baud, source_system=source_system) + if ip.startswith("udpin:"): + self.master = mavudpin_multi(ip[6:], input=True, baud=baud, source_system=source_system) + else: + self.master = mavutil.mavlink_connection(ip, baud=baud, source_system=source_system) # TODO get rid of "master" object as exposed, # keep it private, expose something smaller for dronekit From d8460293f374f1eb9cc721ff28f608665cd1157b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Roche?= Date: Mon, 20 Jun 2016 16:48:48 -0700 Subject: [PATCH 361/475] whitespace killer :knife: --- .editorconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.editorconfig b/.editorconfig index 08c10f020..2470cbc7e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -20,6 +20,8 @@ trim_trailing_whitespace = true [*.py] indent_style = space indent_size = 4 +trim_trailing_whitespace = true +end_of_line = LF [*.mk] indent_style = tab From f60b81a50595e1403556b1b783b85ca4f611f865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Roche?= Date: Tue, 21 Jun 2016 16:00:07 -0700 Subject: [PATCH 362/475] bump 2.7.0 --- CHANGELOG.md | 5 +++++ docs/about/github_latest_release.txt | 8 ++++++++ setup.py | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1bb180e0..f9359eeb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## Version 2.7.0 (2016-06-21) + +### Improvements +* Adds udpin-multi support + ## Version 2.6.0 (2016-06-17) ### Bug Fixes diff --git a/docs/about/github_latest_release.txt b/docs/about/github_latest_release.txt index c5fe267b6..49740b98b 100644 --- a/docs/about/github_latest_release.txt +++ b/docs/about/github_latest_release.txt @@ -3,6 +3,14 @@ Changelog ========= +Version 2.7.0 (2016-06-21) +-------------------------- + +Improvements +~~~~~~~~~~~~ + +- Adds udpin-multi support + Version 2.6.0 (2016-06-17) -------------------------- diff --git a/setup.py b/setup.py index 071d64836..2c5f3857c 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.6.0' +version = '2.7.0' setup(name='dronekit', zip_safe=True, From 41fc0d23b11b81aa0bef22b624701e13dd4c2431 Mon Sep 17 00:00:00 2001 From: George Hines Date: Thu, 14 Jul 2016 13:01:21 -0700 Subject: [PATCH 363/475] add listener to set home location when a HOME_POSITION message is received from the vehicle --- dronekit/__init__.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index c24746fb6..336a830f0 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1200,6 +1200,11 @@ def listener(self, name, msg): self._wploader.expected_count = msg.count self._master.waypoint_request_send(0) + + @self.on_message(['HOME_POSITION']) + def listener(self, name, msg): + self._home_location = LocationGlobal(msg.latitude/1.0e7, msg.longitude/1.0e7, msg.altitude/1000.0); + @self.on_message(['WAYPOINT', 'MISSION_ITEM']) def listener(self, name, msg): if not self._wp_loaded: @@ -1904,7 +1909,7 @@ def home_location(self, pos): # Send MAVLink update. self.send_mavlink(self.message_factory.command_long_encode( 0, 0, # target system, target component - mavutil.mavlink.MAV_CMD_DO_SET_HOME, # command + mavutil.mavlink.MAV_CMD_DO_SETH_OME, # command 0, # confirmation 2, # param 1: 1 to use current position, 2 to use the entered values. 0, 0, 0, # params 2-4 From e733072a7a5b16326b7f8a0630e267298dfe5eb1 Mon Sep 17 00:00:00 2001 From: George Hines Date: Thu, 14 Jul 2016 13:04:39 -0700 Subject: [PATCH 364/475] correct a typo from messing up an emacs shortcut --- dronekit/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 336a830f0..97bdcd9b2 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1909,7 +1909,7 @@ def home_location(self, pos): # Send MAVLink update. self.send_mavlink(self.message_factory.command_long_encode( 0, 0, # target system, target component - mavutil.mavlink.MAV_CMD_DO_SETH_OME, # command + mavutil.mavlink.MAV_CMD_DO_SET_HOME, # command 0, # confirmation 2, # param 1: 1 to use current position, 2 to use the entered values. 0, 0, 0, # params 2-4 From 51e9fe9bf6d5e47e8d62d4ea48bba857035e3948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Roche?= Date: Fri, 15 Jul 2016 10:50:18 -0700 Subject: [PATCH 365/475] bump 2.8.0 --- CHANGELOG.md | 6 ++++++ docs/about/github_latest_release.txt | 9 +++++++++ setup.py | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9359eeb0..a35f51c75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Version 2.8.0 (2016-07-15) + +### Bug Fixes +* Makes sure we are listening to `HOME_LOCATION` message, befor we + would only set home location if received by waypoints. + ## Version 2.7.0 (2016-06-21) ### Improvements diff --git a/docs/about/github_latest_release.txt b/docs/about/github_latest_release.txt index 49740b98b..1f357ec3c 100644 --- a/docs/about/github_latest_release.txt +++ b/docs/about/github_latest_release.txt @@ -3,6 +3,15 @@ Changelog ========= +Version 2.8.0 (2016-07-15) +-------------------------- + +Bug Fixes +~~~~~~~~~ + +- Makes sure we are listening to ``HOME_LOCATION`` message, befor we + would only set home location if received by waypoints. + Version 2.7.0 (2016-06-21) -------------------------- diff --git a/setup.py b/setup.py index 2c5f3857c..87175b6b9 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.7.0' +version = '2.8.0' setup(name='dronekit', zip_safe=True, From 0b177a854e37d5861d47415f23bb0caa9abbb086 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Thu, 14 Jul 2016 00:02:22 +1000 Subject: [PATCH 366/475] MAVConnection: stop threads on exit and connection close --- dronekit/mavlink.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/dronekit/mavlink.py b/dronekit/mavlink.py index a82ef1e10..0fee82f87 100644 --- a/dronekit/mavlink.py +++ b/dronekit/mavlink.py @@ -112,6 +112,15 @@ def recv_msg(self): class MAVConnection(object): + + def stop_threads(self): + if self.mavlink_thread_in is not None: + self.mavlink_thread_in.join() + self.mavlink_thread_in = None + if self.mavlink_thread_out is not None: + self.mavlink_thread_out.join() + self.mavlink_thread_out = None + def __init__(self, ip, baud=115200, target_system=0, source_system=255, use_native=False): if ip.startswith("udpin:"): self.master = mavudpin_multi(ip[6:], input=True, baud=baud, source_system=source_system) @@ -151,6 +160,7 @@ def newsendfn(mavmsg, **kwargs): def onexit(): self._alive = False + self.stop_threads() atexit.register(onexit) @@ -192,7 +202,7 @@ def mavlink_thread_out(): def mavlink_thread_in(): # Huge try catch in case we see http://bugs.python.org/issue1856 try: - while True: + while self._alive: # Downtime time.sleep(0.05) @@ -289,6 +299,7 @@ def close(self): self._alive = False while not self.out_queue.empty(): time.sleep(0.1) + self.stop_threads() self.master.close() def pipe(self, target): From 8a5191adc8737c1ed638cd51d88117368caeaced Mon Sep 17 00:00:00 2001 From: Mikael Ferland Date: Sun, 14 Aug 2016 00:26:21 -0400 Subject: [PATCH 367/475] Make dronekit working with the PX4 Pro as https://github.com/mavlink/mavlink/pull/603 will be merged. --- dronekit/__init__.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 97bdcd9b2..f9c0461f8 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1177,9 +1177,12 @@ def listener(self, name, m): self.notify_attribute_listeners('armed', self.armed, cache=True) self._autopilot_type = m.autopilot self._vehicle_type = m.type - if self._is_mode_available(m.custom_mode) == False: + if self._is_mode_available(m.base_mode,m.custom_mode) == False: raise APIException("mode %s not available on mavlink definition" % m.custom_mode) - self._flightmode = self._mode_mapping_bynumber[m.custom_mode] + if self._autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_PX4: + self._flightmode = mavutil.interpret_px4_mode(m.base_mode, m.custom_mode) + else: + self._flightmode = self._mode_mapping_bynumber[m.custom_mode] self.notify_attribute_listeners('mode', self.mode, cache=True) self._system_status = m.system_status self.notify_attribute_listeners('system_status', self.system_status, cache=True) @@ -1525,9 +1528,12 @@ def _mode_mapping(self): def _mode_mapping_bynumber(self): return mavutil.mode_mapping_bynumber(self._vehicle_type) - def _is_mode_available(self, mode_code): - try: - return mode_code in self._mode_mapping_bynumber + def _is_mode_available(self,basemode_code, custommode_code): + try: + if self._autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_PX4: + mode = mavutil.interpret_px4_mode(basemode_code, custommode_code) + return mode in self._mode_mapping + return custommode_code in self._mode_mapping_bynumber except: return False @@ -1546,7 +1552,10 @@ def mode(self): @mode.setter def mode(self, v): - self._master.set_mode(self._mode_mapping[v.name]) + if self._autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_PX4: + self._master.set_mode(v.name) + else: + self._master.set_mode(self._mode_mapping[v.name]) @property def location(self): From 59dc3681ef597d994d542824aae167c0c63d6403 Mon Sep 17 00:00:00 2001 From: Mikael Ferland Date: Sun, 14 Aug 2016 11:21:03 -0400 Subject: [PATCH 368/475] base_mode is now optional to success on unit tests --- dronekit/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index f9c0461f8..b0c4ca1c4 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1177,7 +1177,7 @@ def listener(self, name, m): self.notify_attribute_listeners('armed', self.armed, cache=True) self._autopilot_type = m.autopilot self._vehicle_type = m.type - if self._is_mode_available(m.base_mode,m.custom_mode) == False: + if self._is_mode_available(m.custom_mode, m.base_mode) == False: raise APIException("mode %s not available on mavlink definition" % m.custom_mode) if self._autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_PX4: self._flightmode = mavutil.interpret_px4_mode(m.base_mode, m.custom_mode) @@ -1528,7 +1528,7 @@ def _mode_mapping(self): def _mode_mapping_bynumber(self): return mavutil.mode_mapping_bynumber(self._vehicle_type) - def _is_mode_available(self,basemode_code, custommode_code): + def _is_mode_available(self, custommode_code, basemode_code=0): try: if self._autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_PX4: mode = mavutil.interpret_px4_mode(basemode_code, custommode_code) From 63943a363d9b8150c397757aaab47167bee1f329 Mon Sep 17 00:00:00 2001 From: peng Date: Mon, 22 Aug 2016 18:52:06 -0400 Subject: [PATCH 369/475] fix a bug where global_frame is used in case which global_relative_frame should be used instead, it causes the drone to take off using a very low sea-level altitude, so it won't leave the ground and its engine will be disarmed shortly after. --- dronekit/test/sitl/test_goto.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dronekit/test/sitl/test_goto.py b/dronekit/test/sitl/test_goto.py index 2269bc31e..ebe06d24d 100644 --- a/dronekit/test/sitl/test_goto.py +++ b/dronekit/test/sitl/test_goto.py @@ -1,7 +1,7 @@ """ simple_goto.py: GUIDED mode "simple goto" example (Copter Only) -The example demonstrates how to arm and takeoff in Copter and how to navigate to +The example demonstrates how to arm and takeoff in Copter and how to navigate to points using Vehicle.simple_goto. Full documentation is provided at http://python.dronekit.io/examples/simple_goto.html @@ -60,9 +60,9 @@ def arm_and_takeoff(aTargetAltitude): # processing the goto (otherwise the command after # Vehicle.simple_takeoff will execute immediately). while True: - # print " Altitude: ", vehicle.location.alt + # print " Altitude: ", vehicle.location.global_relative_frame.alt # Test for altitude just below target, in case of undershoot. - if vehicle.location.global_frame.alt >= aTargetAltitude * 0.95: + if vehicle.location.global_relative_frame.alt >= aTargetAltitude * 0.95: # print "Reached target altitude" break From 5a71f1613c1f563f183f05239ee5d141c53993cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Roche?= Date: Mon, 29 Aug 2016 13:04:01 -0700 Subject: [PATCH 370/475] bump pymavlink - greatly increases PX4 Pro compatibility - makes sure we don't fall behind on pymavlink upgrades - cleans up dependencies, its long overdue. --- requirements.txt | 15 ++++++--------- setup.py | 4 ++-- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/requirements.txt b/requirements.txt index 7dde864c7..cbe1f925b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,6 @@ -requests>=2.5.0,<=2.99999 -pymavlink>=1.1.62 -sphinx-3dr-theme>=0.0.6 -nose>=1.3.7 -psutil>=3.0.0 -mock>=1.3.0 -six>=1.9.0 -dronekit-sitl>=3.0,<=3.99999 -monotonic<1.0 +pymavlink==2.0.6 +monotonic==1.2 +nose==1.3.7 +mock==2.0.0 +dronekit-sitl==3.1.0 +sphinx-3dr-theme>=0.4.3 diff --git a/setup.py b/setup.py index 87175b6b9..24b81c36c 100644 --- a/setup.py +++ b/setup.py @@ -11,8 +11,8 @@ url='https://github.com/dronekit/dronekit-python', author='3D Robotics', install_requires=[ - 'pymavlink>=1.1.62', - 'monotonic<1.0' + 'pymavlink==2.0.6', + 'monotonic==1.2' ], author_email='tim@3drobotics.com, kevinh@geeksville.com', classifiers=[ From fac629cff66a92a63017e96f7c8a8d27a06a6189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Roche?= Date: Mon, 29 Aug 2016 13:40:34 -0700 Subject: [PATCH 371/475] bump 2.9.0 --- CHANGELOG.md | 11 +++++++++++ docs/about/github_latest_release.txt | 16 ++++++++++++++++ setup.py | 2 +- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a35f51c75..f97d9e763 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## Version 2.9.0 (2016-08-29) + +### Bug Fixes +* MAVConnection stops threads on exit and close +* PX4 Pro flight modes are now properly supported +* go to test now uses correct `global_relative_frame` alt + +### Improvements +* Updated pymavlink dependency to v2 from v1 hoping we don't fall behind + again. + ## Version 2.8.0 (2016-07-15) ### Bug Fixes diff --git a/docs/about/github_latest_release.txt b/docs/about/github_latest_release.txt index 1f357ec3c..a644a3bd7 100644 --- a/docs/about/github_latest_release.txt +++ b/docs/about/github_latest_release.txt @@ -3,6 +3,22 @@ Changelog ========= +Version 2.9.0 (2016-08-29) +-------------------------- + +Bug Fixes +~~~~~~~~~ + +- MAVConnection stops threads on exit and close +- PX4 Pro flight modes are now properly supported +- go to test now uses correct ``global_relative_frame`` alt + +Improvements +~~~~~~~~~~~~ + +- Updated pymavlink dependency to v2 from v1 hoping we don't fall + behind again. + Version 2.8.0 (2016-07-15) -------------------------- diff --git a/setup.py b/setup.py index 24b81c36c..08090ba7a 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.8.0' +version = '2.9.0' setup(name='dronekit', zip_safe=True, From fe6226fb087301b058824916568d88ec0d4607e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Roche?= Date: Mon, 29 Aug 2016 14:17:03 -0700 Subject: [PATCH 372/475] there is no :cloud: --- .travis.yml | 1 - appveyor.yml | 3 +- circle.yml | 1 - docs/contributing/contributions_api.rst | 75 +++++++++---------------- dronekit/cloud/CloudClient.py | 52 ----------------- dronekit/cloud/__init__.py | 1 - dronekit/test/web/__init__.py | 1 - dronekit/test/web/cloud_client_test.py | 65 --------------------- setup.py | 2 +- 9 files changed, 30 insertions(+), 171 deletions(-) delete mode 100644 dronekit/cloud/CloudClient.py delete mode 100644 dronekit/cloud/__init__.py delete mode 100644 dronekit/test/web/__init__.py delete mode 100644 dronekit/test/web/cloud_client_test.py diff --git a/.travis.yml b/.travis.yml index 82a6a9da7..f3bf8eaa3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,6 @@ install: - 'sudo pip install -r requirements.txt -UI' script: -# - '[ "${TRAVIS_PULL_REQUEST}" != "false" ] || nosetests -svx dronekit.test.web' - 'nosetests -svx dronekit.test.unit' - 'nosetests -svx dronekit.test.sitl' diff --git a/appveyor.yml b/appveyor.yml index 86dda3947..63fab30ca 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,7 +15,7 @@ install: [wheel] wheel-dir = c:/Users/appveyor/.pip-wheelhouse '@ | out-file -Encoding ascii -FilePath c:\Users\appveyor\pip\pip.ini - + - cmd: 'SET PATH=%PYTHON%;c:\\Python27\\Scripts;%PATH%' - cmd: 'SET PYTHONUNBUFFERED=1' @@ -24,7 +24,6 @@ install: - cmd: 'pip install -r requirements.txt -UI' build_script: -# - cmd: 'nosetests -svx dronekit.test.web' - cmd: 'nosetests -svx dronekit.test.unit' - cmd: 'nosetests -svx dronekit.test.sitl' diff --git a/circle.yml b/circle.yml index 9c9c85cb7..c10398ce3 100644 --- a/circle.yml +++ b/circle.yml @@ -14,7 +14,6 @@ test: - 'cd docs; make clean; make html' # code -# - 'nosetests -svx dronekit.test.web' - 'nosetests -svx dronekit.test.unit' - 'nosetests -svx dronekit.test.sitl' diff --git a/docs/contributing/contributions_api.rst b/docs/contributing/contributions_api.rst index 8cdafc8ee..9a3c97b7f 100644 --- a/docs/contributing/contributions_api.rst +++ b/docs/contributing/contributions_api.rst @@ -6,16 +6,16 @@ Contributing to the API This article provides a high level overview of how to contribute changes to the DroneKit-Python source code. -.. tip:: +.. tip:: - We highly recommend that changes and ideas are `discussed with the project team - `_ before starting work! + We highly recommend that changes and ideas are `discussed with the project team + `_ before starting work! Submitting changes ================== -Contributors should fork the main `dronekit/dronekit-python/ `_ +Contributors should fork the main `dronekit/dronekit-python/ `_ repository and contribute changes back to the project master branch using pull requests * Changes should be :ref:`tested locally ` before submission. @@ -32,9 +32,8 @@ Test code There are three test suites in DroneKit-Python: -* **Unit tests** (:file:`tests/unit`) — verify all code paths of the API. +* **Unit tests** (:file:`tests/unit`) — verify all code paths of the API. * **Integration tests** (:file:`tests/sitl`) — verify real-world code, examples, and documentation as they would perform in a real environment. -* **Web client tests** (:file:`tests/web`) — specifically verify the Python library's capability to talk to `DroneKit Cloud `_. Test code should be used to verify new and changed functionality. New tests should: @@ -46,12 +45,12 @@ Test code should be used to verify new and changed functionality. New tests shou Setting up local testing ------------------------ -Follow the links below to set up a development environment on your Linux or Windows computer. +Follow the links below to set up a development environment on your Linux or Windows computer. * :ref:`dronekit_development_linux` * :ref:`dronekit_development_windows` -The tests require additional pip modules, including `nose `_, a +The tests require additional pip modules, including `nose `_, a Python library and tool for writing and running test scripts. These can be installed separately using either of the commands below: .. code:: bash @@ -59,7 +58,7 @@ Python library and tool for writing and running test scripts. These can be insta # Install just the additional requirements for tests pip install requests nose mock - # (or) Install all requirements for dronekit, tests, and building documentation + # (or) Install all requirements for dronekit, tests, and building documentation pip install -r requirements.txt For several tests, you may be required to set an **environment variable**. In your command line, you can set the name of a variable to equal a value using the following invocation, depending on your OS: @@ -73,35 +72,35 @@ For several tests, you may be required to set an **environment variable**. In yo Unit tests ---------- -All new features should be created with accompanying unit tests. +All new features should be created with accompanying unit tests. DroneKit-Python unit tests are based on the `nose `_ test framework, -and use `mock `_ to simulate objects and APIs and +and use `mock `_ to simulate objects and APIs and ensure correct results. -To run the tests and display a summary of the results (on any OS), -navigate to the **dronekit-python** folder and enter the following +To run the tests and display a summary of the results (on any OS), +navigate to the **dronekit-python** folder and enter the following command on a terminal/prompt: .. code:: bash nosetests dronekit.test.unit - + Writing a new unit test ^^^^^^^^^^^^^^^^^^^^^^^ -Create any file named :file:`test_XXX.py` in the :file:`tests/unit` folder to add it as a test. +Create any file named :file:`test_XXX.py` in the :file:`tests/unit` folder to add it as a test. Feel free to copy from existing tests to get started. When *nosetests* is run, it will add your new test to its summary. -Tests names should be named based on their associated Github issue (for example, -``test_12.py`` for `issue #12 `_) -or describe the functionality covered (for example, ``test_waypoints.py`` +Tests names should be named based on their associated Github issue (for example, +``test_12.py`` for `issue #12 `_) +or describe the functionality covered (for example, ``test_waypoints.py`` for a unit test for the waypoints API). - -Use assertions to test your code is consistent. You can use the built-in Python ``assert`` macro as well as ``assert_equals`` and ``assert_not_equals`` + +Use assertions to test your code is consistent. You can use the built-in Python ``assert`` macro as well as ``assert_equals`` and ``assert_not_equals`` from the ``notestools`` module: .. note:: @@ -116,7 +115,7 @@ from the ``notestools`` module: assert the_number_two > 0, '2 should be greater than zero!' assert_equals(the_number_two, 2, '2 should equal two!') assert_not_equals(the_number_two, 1, '2 should equal one!') - + Please add documentation to each test function describing what behavior it verifies. @@ -129,8 +128,8 @@ Integrated tests use a custom test runner that is similar to *nosetests*. On any cd dronekit-python nosetests dronekit.test.sitl - -You can choose to run a specific tests. The example below shows how to run + +You can choose to run a specific tests. The example below shows how to run **\dronekit-python\dronekit\test\sitl\test_12.py**. .. code:: bash @@ -160,12 +159,12 @@ Integration tests should be written or improved whenever: You can write a new integrated test by adding (or copying) a file with the naming scheme :file:`test_XXX.py` to the :file:`tests/sitl` directory. -Tests names should be named based on their associated Github issue (for example, -``test_12.py`` for `issue #12 `_) -or describe the functionality covered (for example, ``test_waypoints.py`` +Tests names should be named based on their associated Github issue (for example, +``test_12.py`` for `issue #12 `_) +or describe the functionality covered (for example, ``test_waypoints.py`` for an integration test for the waypoints API). -Tests should minimally use the imports shown below and decorate test functions with ``@with_sitl`` +Tests should minimally use the imports shown below and decorate test functions with ``@with_sitl`` (this sets up the test and passes in a connection string for SITL). .. code:: python @@ -184,13 +183,13 @@ Tests should minimally use the imports shown below and decorate test functions w vehicle.close() -Use assertions to test your code is consistent. You can use the built-in Python ``assert`` macro as well as ``assert_equals`` and ``assert_not_equals`` +Use assertions to test your code is consistent. You can use the built-in Python ``assert`` macro as well as ``assert_equals`` and ``assert_not_equals`` from the ``testlib`` module: .. note:: Avoiding printing any data from your test! - + .. code:: python @@ -202,21 +201,3 @@ from the ``testlib`` module: assert_equals(the_number_two, 2, '2 should equal two!' Please add documentation to each test function describing what behavior it verifies. - -Web client tests ----------------- - -.. warning:: - - The web client library is being rewritten. Please `discuss with the project team - `_ if you intend to develop with or for the present version of the web client. - -Web client tests use *nosetests*. To run these, you will need to sign up for API keys from `cloud.dronekit.io `_. -With these, export a variable named ``DRONEAPI_KEY`` with a value in the format ``.`` to your environment. - -On any OS, enter the following command on a terminal/prompt to run the web-client tests (and display summary results): - -.. code:: bash - - cd dronekit-python - nosetests tests/web diff --git a/dronekit/cloud/CloudClient.py b/dronekit/cloud/CloudClient.py deleted file mode 100644 index 6b3443807..000000000 --- a/dronekit/cloud/CloudClient.py +++ /dev/null @@ -1,52 +0,0 @@ -import requests - - -class CloudError(Exception): - def __init__(self, type, message, response): - self.type = type - self.message = message - self.response = response - - def __str__(self): - return "%s [%s] (%s)" % (self.type, self.response.url, self.message) - - def __repr__(self): - return "%s(type=%s)" % (self.__class__.__name__, self.type) - - -class CloudClient(object): - BASE_URL = 'http://api.droneshare.com/api/v1/' - REST_CALLS = { - 'staticMap': 'staticMap', - 'analysis': 'analysis.json', - 'geo': 'messages.geo.json', - 'messages': 'messages.json', - 'parameters': 'parameters.json' - } - - def __init__(self, api_key): - self.api_key = api_key - self.headers = {'Authorization': "DroneApi apikey=\"%s\"" % self.apikey} - - def __getattr__(self, name): - def method(*args): - find_action = name.split('_') - find_args = args - action_url = find_action[0] - if (len(find_action) > 1): - if (find_action[1] in self.REST_CALLS): - if (len(args) > 0): - action_url += "/%s/%s" % (str(args[0]), self.REST_CALLS[find_action[1]]) - else: - action_url += "/%s" % find_action[1] - else: - action_url += "/%s/%s" % (str(args[0]), find_action[1]) - return self._request(action_url, args[1:]) - - return method - - def _request(self, url, data): - self.response = requests.get("%s%s" % (self.BASE_URL, url), headers=self.headers) - if self.response.status_code == 404: - raise CloudError(self.response.status_code, 'Unknown Endpoint', self.response) - return self.response diff --git a/dronekit/cloud/__init__.py b/dronekit/cloud/__init__.py deleted file mode 100644 index 8b1378917..000000000 --- a/dronekit/cloud/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/dronekit/test/web/__init__.py b/dronekit/test/web/__init__.py deleted file mode 100644 index 8b1378917..000000000 --- a/dronekit/test/web/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/dronekit/test/web/cloud_client_test.py b/dronekit/test/web/cloud_client_test.py deleted file mode 100644 index 005dcb631..000000000 --- a/dronekit/test/web/cloud_client_test.py +++ /dev/null @@ -1,65 +0,0 @@ -import os -from nose.tools import assert_raises -from dronekit.cloud.CloudClient import * - - -def setup_module(): - global api - api_key = os.environ['DRONEAPI_KEY'] - api = CloudClient(api_key) - - -def teardown_module(): - pass - - -def test_unhandled_endpoint(): - assert_raises(CloudError, api.bogus) - - -def test_mission_endpoint(): - api.mission() - - -def test_mission_static_map(): - api.mission_staticMap() - - -def test_mission_by_id_endpoint(): - api.mission_(1141) - - -def test_mission_by_id_analysis_endpoint(): - api.mission_analysis(1141) - - -def test_mission_by_id_geo_endpoint(): - api.mission_geo(1141) - - -def test_mission_by_id_messages_endpoint(): - api.mission_messages(1141) - - -def test_mission_by_id_parameters_endpoint(): - api.mission_parameters(1141) - - -def test_mission_by_id_dseries_endpoint(): - api.mission_dseries(1141) - - -def test_vehicle_endpoint(): - api.vehicle() - - -def test_vehicle_by_id_endpoint(): - api.vehicle_(218) - - -def test_user_endpoint(): - api.user() - - -def test_user_by_login_endpoint(): - api.user('mrpollo') diff --git a/setup.py b/setup.py index 08090ba7a..d875c8b77 100644 --- a/setup.py +++ b/setup.py @@ -26,6 +26,6 @@ ], license='apache', packages=[ - 'dronekit', 'dronekit.cloud', 'dronekit.test' + 'dronekit', 'dronekit.test' ], ext_modules=[]) From 1e871786a834e3e1e0d67c2bee564ec8cec8d4e0 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 31 Aug 2016 03:19:31 +1000 Subject: [PATCH 373/475] adds notification whenever home location is changed (#650) --- dronekit/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index b0c4ca1c4..9e6f77b1d 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1207,6 +1207,7 @@ def listener(self, name, msg): @self.on_message(['HOME_POSITION']) def listener(self, name, msg): self._home_location = LocationGlobal(msg.latitude/1.0e7, msg.longitude/1.0e7, msg.altitude/1000.0); + self.notify_attribute_listeners('home_location', self.home_location, cache=True) @self.on_message(['WAYPOINT', 'MISSION_ITEM']) def listener(self, name, msg): From f2a531a9a3a173cbc5b9b5f0eb5e6d7a90e64244 Mon Sep 17 00:00:00 2001 From: Ramon Roche Date: Wed, 31 Aug 2016 19:47:25 -0700 Subject: [PATCH 374/475] notify ci status to gitter (#658) --- .travis.yml | 8 ++++++-- circle.yml | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index f3bf8eaa3..e02b56d21 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,8 +21,12 @@ language: objective-c notifications: email: false - slack: - secure: IYgZ83X065I/LljGrPEACZms+KDwrojiQbboFHhvNxL2Zkc5jHqwBK6PD1BsJh2JVun9fCZ1v2R8KuDsf+Qz2dCximdOZcHI81L9JUOZYuSJ2TVlbKiC00WdXpcQ6g7pDTLm/mGBoPxC+MuC5l8zZdbpPBpEa0F/YCe/n7tbT+g= + webhooks: + urls: + - https://webhooks.gitter.im/e/f3f81b74f930dac9583a + on_success: change + on_failure: always + on_start: never matrix: fast_finish: true diff --git a/circle.yml b/circle.yml index c10398ce3..077606919 100644 --- a/circle.yml +++ b/circle.yml @@ -25,3 +25,7 @@ deployment: branch: master commands: - ./scripts/update-docs.sh + +notify: + webhooks: + - url: https://webhooks.gitter.im/e/27b0e1a9fede99dbbe6c From fb004baddbedc510e17726474e8c40af88ccb208 Mon Sep 17 00:00:00 2001 From: Ramon Roche Date: Mon, 19 Sep 2016 19:50:27 -0700 Subject: [PATCH 375/475] basic python 3 support (#655) * basic python 3 support * pyenv support * test python 2 and 3 on travis * test py 2.7 3.5 on circleci * debug travis nose tests * install to virtualenv --- .gitignore | 1 + .travis.yml | 13 +++++-------- circle.yml | 2 ++ dronekit/__init__.py | 12 ++++++------ dronekit/mavlink.py | 2 +- requirements.txt | 1 + setup.py | 3 ++- 7 files changed, 18 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index eb6b83785..7df502175 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .project .pydevproject +.python-version dronekit.egg-info dist build diff --git a/.travis.yml b/.travis.yml index e02b56d21..b8495e401 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,19 +5,19 @@ env: python: - "2.7" + - "3.5" install: - - 'sudo pip install . -UI' - - 'sudo pip install -r requirements.txt -UI' + - 'pip install -r requirements.txt' script: - - 'nosetests -svx dronekit.test.unit' - - 'nosetests -svx dronekit.test.sitl' + - 'nosetests --debug=nose,nose.importer --debug-log=nose_debug -svx dronekit.test.unit' + - 'nosetests --debug=nose,nose.importer --debug-log=nose_debug -svx dronekit.test.sitl' git: depth: 10 -language: objective-c +language: python notifications: email: false @@ -34,6 +34,3 @@ matrix: branches: only: - master - - patch - - major - - minor diff --git a/circle.yml b/circle.yml index 077606919..5ee47fc59 100644 --- a/circle.yml +++ b/circle.yml @@ -1,4 +1,6 @@ machine: + post: + - pyenv global 2.7.10 3.5.0 environment: SITL_SPEEDUP: 10 SITL_RATE: 200 diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 9e6f77b1d..7d98364f4 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -40,7 +40,7 @@ import re from dronekit.util import errprinter from pymavlink import mavutil, mavwp -from Queue import Queue, Empty +from queue import Queue, Empty from threading import Thread import types import threading @@ -1208,7 +1208,7 @@ def listener(self, name, msg): def listener(self, name, msg): self._home_location = LocationGlobal(msg.latitude/1.0e7, msg.longitude/1.0e7, msg.altitude/1000.0); self.notify_attribute_listeners('home_location', self.home_location, cache=True) - + @self.on_message(['WAYPOINT', 'MISSION_ITEM']) def listener(self, name, msg): if not self._wp_loaded: @@ -1530,10 +1530,10 @@ def _mode_mapping_bynumber(self): return mavutil.mode_mapping_bynumber(self._vehicle_type) def _is_mode_available(self, custommode_code, basemode_code=0): - try: - if self._autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_PX4: + try: + if self._autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_PX4: mode = mavutil.interpret_px4_mode(basemode_code, custommode_code) - return mode in self._mode_mapping + return mode in self._mode_mapping return custommode_code in self._mode_mapping_bynumber except: return False @@ -1553,7 +1553,7 @@ def mode(self): @mode.setter def mode(self, v): - if self._autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_PX4: + if self._autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_PX4: self._master.set_mode(v.name) else: self._master.set_mode(self._mode_mapping[v.name]) diff --git a/dronekit/mavlink.py b/dronekit/mavlink.py index 0fee82f87..dd2f0d131 100644 --- a/dronekit/mavlink.py +++ b/dronekit/mavlink.py @@ -11,7 +11,7 @@ from dronekit import APIException from dronekit.util import errprinter from pymavlink import mavutil, mavwp -from Queue import Queue, Empty +from queue import Queue, Empty from threading import Thread import types diff --git a/requirements.txt b/requirements.txt index cbe1f925b..968f2956a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,6 @@ pymavlink==2.0.6 monotonic==1.2 +future==0.15.2 nose==1.3.7 mock==2.0.0 dronekit-sitl==3.1.0 diff --git a/setup.py b/setup.py index d875c8b77..465743374 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,8 @@ author='3D Robotics', install_requires=[ 'pymavlink==2.0.6', - 'monotonic==1.2' + 'monotonic==1.2', + 'future==0.15.2' ], author_email='tim@3drobotics.com, kevinh@geeksville.com', classifiers=[ From 3a5442cda9e367e0c511a1caffb15685f54cae26 Mon Sep 17 00:00:00 2001 From: Ramon Roche Date: Thu, 22 Sep 2016 00:22:40 -0700 Subject: [PATCH 376/475] update sitl (#660) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 968f2956a..7a7076abe 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,5 +3,5 @@ monotonic==1.2 future==0.15.2 nose==1.3.7 mock==2.0.0 -dronekit-sitl==3.1.0 +dronekit-sitl==3.2.0 sphinx-3dr-theme>=0.4.3 From 0d77e600de0a97afe887b2b2fa9d864e959f9dc7 Mon Sep 17 00:00:00 2001 From: glemero Date: Thu, 23 Feb 2017 12:30:42 +0100 Subject: [PATCH 377/475] fix missing ** operator --- dronekit/mavlink.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/mavlink.py b/dronekit/mavlink.py index dd2f0d131..b47f67fed 100644 --- a/dronekit/mavlink.py +++ b/dronekit/mavlink.py @@ -140,7 +140,7 @@ def __init__(self, ip, baud=115200, target_system=0, source_system=255, use_nati def newsendfn(mavmsg, **kwargs): self.fix_targets(mavmsg) - return sendfn(mavmsg, kwargs) + return sendfn(mavmsg, **kwargs) self.master.mav.send = newsendfn From 270e9d7502e256c4182506591bb9a86541540a4a Mon Sep 17 00:00:00 2001 From: glemero Date: Fri, 3 Mar 2017 12:56:59 +0100 Subject: [PATCH 378/475] adding *args to send method in case pymavlink modifies its send method signature --- dronekit/mavlink.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dronekit/mavlink.py b/dronekit/mavlink.py index b47f67fed..f5f3cf38d 100644 --- a/dronekit/mavlink.py +++ b/dronekit/mavlink.py @@ -138,9 +138,9 @@ def __init__(self, ip, baud=115200, target_system=0, source_system=255, use_nati # Monkey-patch MAVLink object for fix_targets. sendfn = self.master.mav.send - def newsendfn(mavmsg, **kwargs): + def newsendfn(mavmsg, *args, **kwargs): self.fix_targets(mavmsg) - return sendfn(mavmsg, **kwargs) + return sendfn(mavmsg, *args, **kwargs) self.master.mav.send = newsendfn From 12e18a5dd39fd24295bb730eca0f32e988f56b1a Mon Sep 17 00:00:00 2001 From: cclauss Date: Tue, 18 Apr 2017 19:22:36 +0200 Subject: [PATCH 379/475] Step up testing to Python 2.7.13 and 3.6.0 (#702) * Step up testing to Python 3.6 * Python 2.7.13 and 3.6.0 * Python 2.7.13 * allow_failures: python: 3.6 --- .travis.yml | 6 ++++-- circle.yml | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index b8495e401..b143309cb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,8 @@ env: - SITL_RATE=200 python: - - "2.7" - - "3.5" + - 2.7.13 + - 3.6 install: - 'pip install -r requirements.txt' @@ -29,6 +29,8 @@ notifications: on_start: never matrix: + allow_failures: + - python: 3.6 fast_finish: true branches: diff --git a/circle.yml b/circle.yml index 5ee47fc59..2e9e6a804 100644 --- a/circle.yml +++ b/circle.yml @@ -1,6 +1,6 @@ machine: post: - - pyenv global 2.7.10 3.5.0 + - pyenv global 2.7.13 3.6.0 environment: SITL_SPEEDUP: 10 SITL_RATE: 200 From 7604bd976088dc5e7de6979851890256c172d409 Mon Sep 17 00:00:00 2001 From: Will Silva Date: Tue, 18 Apr 2017 10:56:57 -0700 Subject: [PATCH 380/475] add support for a logger function in errprinter (#681) * add support for a logger function in errprinter * this enables other software to monkey patch the logger function to capture dronekit output and exceptions * moved print to stderr to logger function * monkey patching logger will replace the print to stderr functionality instead of supplement it --- dronekit/util.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dronekit/util.py b/dronekit/util.py index f5800985b..081ffd2be 100644 --- a/dronekit/util.py +++ b/dronekit/util.py @@ -3,5 +3,8 @@ def errprinter(*args): + logger(*args) + +def logger(*args): print(*args, file=sys.stderr) sys.stderr.flush() From aa6ae753f992ea79d3d4cf63a490194ec8d361b0 Mon Sep 17 00:00:00 2001 From: Will Silva Date: Tue, 18 Apr 2017 11:01:16 -0700 Subject: [PATCH 381/475] =?UTF-8?q?adds=20a=20method=20to=20LocationLocal?= =?UTF-8?q?=20that=20returns=20distance=20from=20home,=20in=20me=E2=80=A6?= =?UTF-8?q?=20(#679)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * adds a method to LocationLocal that returns distance from home, in meters * Return 3D distance to home if `down` is known, otherwise return 2D distance * also, rename `distance` to `distance_home` --- dronekit/__init__.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 7d98364f4..a11b9eb50 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -184,6 +184,17 @@ def __init__(self, north, east, down): def __str__(self): return "LocationLocal:north=%s,east=%s,down=%s" % (self.north, self.east, self.down) + def distance_home(self): + """ + Distance away from home, in meters. Returns 3D distance if `down` is known, otherwise 2D distance. + """ + + if self.north is not None and self.east is not None: + if self.down is not None: + return math.sqrt(self.north**2 + self.east**2 + self.down**2) + else: + return math.sqrt(self.north**2 + self.east**2) + class GPSInfo(object): """ From 9f96bfc4e49d40081dad78e2b225d40a0d745236 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 21 Apr 2017 10:53:10 +1000 Subject: [PATCH 382/475] requirements: any pymavlink gte 2.0.6 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7a7076abe..c71a2d161 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -pymavlink==2.0.6 +pymavlink>=2.0.6 monotonic==1.2 future==0.15.2 nose==1.3.7 From 62eb6880393065558293f737bd4c40231e327db7 Mon Sep 17 00:00:00 2001 From: Amilcar Lucas Date: Fri, 21 Apr 2017 19:52:23 +0200 Subject: [PATCH 383/475] Fix windows installer, it is called dronekit, not droneapi. (#708) Improve documentation a bit --- windows/{droneapiWinBuild.bat => dronekitWinBuild.bat} | 3 ++- windows/{droneapi_installer.iss => dronekit_installer.iss} | 0 2 files changed, 2 insertions(+), 1 deletion(-) rename windows/{droneapiWinBuild.bat => dronekitWinBuild.bat} (67%) rename windows/{droneapi_installer.iss => dronekit_installer.iss} (100%) diff --git a/windows/droneapiWinBuild.bat b/windows/dronekitWinBuild.bat similarity index 67% rename from windows/droneapiWinBuild.bat rename to windows/dronekitWinBuild.bat index 1344267f3..95c8a79bb 100644 --- a/windows/droneapiWinBuild.bat +++ b/windows/dronekitWinBuild.bat @@ -1,5 +1,6 @@ rem build the standalone Dronekit.exe for Windows. -rem This assumes Python is installed in C:\Python27 +rem This assumes Python2 is installed in C:\Python27 +rem This assumes Inno Setup 5 is installed in C:\Program Files (x86)\Inno Setup 5 SETLOCAL enableextensions rem get the version diff --git a/windows/droneapi_installer.iss b/windows/dronekit_installer.iss similarity index 100% rename from windows/droneapi_installer.iss rename to windows/dronekit_installer.iss From 4d05c05363cf2300ddcc2b60af729f66c8f18fd4 Mon Sep 17 00:00:00 2001 From: Amilcar Lucas Date: Fri, 21 Apr 2017 19:53:19 +0200 Subject: [PATCH 384/475] convert paratenter set value to single precision floating point number (the type used by low level mavlink messages) before sending/comparing it (#707) This fixes bougus "timeout setting parameter x to y" messages when the passed double value and it's single representation differ --- dronekit/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index a11b9eb50..ad0baa045 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -45,6 +45,7 @@ import types import threading import math +import struct import copy import collections from pymavlink.dialects.v10 import ardupilotmega @@ -2433,7 +2434,8 @@ def set(self, name, value, retries=3, wait_ready=False): # instead just wait until the value itself was changed name = name.upper() - value = float(value) + # convert to single precision floating point number (the type used by low level mavlink messages) + value = float(struct.unpack('f', struct.pack('f', value))[0]) success = False remaining = retries while True: From c633a5ca514ac6464a00814f578237e031fef486 Mon Sep 17 00:00:00 2001 From: cclauss Date: Fri, 21 Apr 2017 20:35:06 +0200 Subject: [PATCH 385/475] Python 3: define basestring, use bytes.decode() (#705) * Run flake8 tests against both Python 2 and 3 * Python 3: from past.builtins import basestring * Python 3: from __future__ import print_function * Update simple_goto.py * flake8 --max-line-length=127 * Python 3: from __future__ import print_function * Separate flak8 run just for syntax errors --- .travis.yml | 20 ++++++-- dronekit/__init__.py | 34 +++++++------ examples/drone_delivery/drone_delivery.py | 58 ++++++++++------------ examples/simple_goto/simple_goto.py | 60 ++++++++++++----------- 4 files changed, 92 insertions(+), 80 deletions(-) diff --git a/.travis.yml b/.travis.yml index b143309cb..cc7d067ef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,5 @@ +language: python + env: global: - SITL_SPEEDUP=10 @@ -7,18 +9,26 @@ python: - 2.7.13 - 3.6 +before_install: + - pip install --upgrade pip + install: - - 'pip install -r requirements.txt' + - pip install -r requirements.txt + - pip install flake8 + +before_script: + # --exit-zero means that flake8 will not stop the build + # 127 characters is the width of a GitHub editor + - flake8 . --count --exit-zero --max-line-length=127 --select=E999 --statistics # syntax errors + - flake8 . --count --exit-zero --max-line-length=127 --statistics script: - - 'nosetests --debug=nose,nose.importer --debug-log=nose_debug -svx dronekit.test.unit' - - 'nosetests --debug=nose,nose.importer --debug-log=nose_debug -svx dronekit.test.sitl' + - nosetests --debug=nose,nose.importer --debug-log=nose_debug -svx dronekit.test.unit + - nosetests --debug=nose,nose.importer --debug-log=nose_debug -svx dronekit.test.sitl git: depth: 10 -language: python - notifications: email: false webhooks: diff --git a/dronekit/__init__.py b/dronekit/__init__.py index ad0baa045..9a573c9e1 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -31,23 +31,26 @@ """ from __future__ import print_function -import monotonic -import time -import socket -import sys +import collections +import copy +import math import os +import struct import platform -import re -from dronekit.util import errprinter -from pymavlink import mavutil, mavwp from queue import Queue, Empty +import re +import socket +import sys +import threading from threading import Thread +import time import types -import threading -import math -import struct -import copy -import collections + +import monotonic +from past.builtins import basestring +from dronekit.util import errprinter + +from pymavlink import mavutil, mavwp from pymavlink.dialects.v10 import ardupilotmega @@ -88,7 +91,8 @@ def __init__(self, pitch, yaw, roll): self.roll = roll def __str__(self): - return "Attitude:pitch=%s,yaw=%s,roll=%s" % (self.pitch, self.yaw, self.roll) + fmt = '{}:pitch={pitch},yaw={yaw},roll={roll}' + return fmt.format(self.__class__.__name__, **vars(self)) class LocationGlobal(object): @@ -2747,7 +2751,7 @@ def __len__(self): def __getitem__(self, index): if isinstance(index, slice): - return [self[ii] for ii in xrange(*index.indices(len(self)))] + return [self[ii] for ii in range(*index.indices(len(self)))] elif isinstance(index, int): item = self._vehicle._wploader.wp(index + 1) if not item: @@ -2835,7 +2839,7 @@ def connect(ip, @vehicle.on_message('STATUSTEXT') def listener(self, name, m): - status_printer(re.sub(r'(^|\n)', '>>> ', m.text.rstrip())) + status_printer(re.sub(r'(^|\n)', '>>> ', m.text.decode('utf-8').rstrip())) if _initialize: vehicle.initialize(rate=rate, heartbeat_timeout=heartbeat_timeout) diff --git a/examples/drone_delivery/drone_delivery.py b/examples/drone_delivery/drone_delivery.py index db2229784..10848877c 100644 --- a/examples/drone_delivery/drone_delivery.py +++ b/examples/drone_delivery/drone_delivery.py @@ -3,39 +3,39 @@ """ © Copyright 2015-2016, 3D Robotics. -drone_delivery.py: +drone_delivery.py: A CherryPy based web application that displays a mapbox map to let you view the current vehicle position and send the vehicle commands to fly to a particular latitude and longitude. Full documentation is provided at http://python.dronekit.io/examples/drone_delivery.html """ +from __future__ import print_function import os import simplejson import time -from pymavlink import mavutil + from dronekit import connect, VehicleMode, LocationGlobal, LocationGlobalRelative import cherrypy -from cherrypy.process import wspbus, plugins from jinja2 import Environment, FileSystemLoader -#Set up option parsing to get connection string -import argparse +# Set up option parsing to get connection string +import argparse parser = argparse.ArgumentParser(description='Creates a CherryPy based web application that displays a mapbox map to let you view the current vehicle position and send the vehicle commands to fly to a particular latitude and longitude. Will start and connect to SITL if no connection string specified.') -parser.add_argument('--connect', - help="vehicle connection target string. If not specified, SITL is automatically started and used.") +parser.add_argument('--connect', + help="vehicle connection target string. If not specified, SITL is automatically started and used.") args = parser.parse_args() -connection_string=args.connect +connection_string = args.connect -#Start SITL if no connection string specified +# Start SITL if no connection string specified if not connection_string: import dronekit_sitl sitl = dronekit_sitl.start_default() connection_string = sitl.connection_string() -local_path=os.path.dirname(os.path.abspath(__file__)) -print "local path: %s" % local_path +local_path = os.path.dirname(os.path.abspath(__file__)) +print("local path: %s" % local_path) cherrypy_conf = { @@ -89,11 +89,10 @@ def takeoff(self): self._log("Taking off") self.vehicle.simple_takeoff(30.0) - def arm(self, value=True): if value: self._log('Waiting for arming...') - self.vehicle.armed = True + self.vehicle.armed = True while not self.vehicle.armed: time.sleep(.1) else: @@ -104,11 +103,9 @@ def _run_server(self): # Start web server if enabled cherrypy.tree.mount(DroneDelivery(self), '/', config=cherrypy_conf) - cherrypy.config.update({ - 'server.socket_port': 8080, - 'server.socket_host': '0.0.0.0', - 'log.screen': None - }) + cherrypy.config.update({'server.socket_port': 8080, + 'server.socket_host': '0.0.0.0', + 'log.screen': None}) print('''Server is bound on all addresses, port 8080 You may connect to it using your web broser using a URL looking like this: @@ -153,28 +150,26 @@ def location_callback(self, vehicle, name, location): self.current_location = location.global_relative_frame def _log(self, message): - print "[DEBUG]: {0}".format(message) + print("[DEBUG]: {0}".format(message)) + class Templates: def __init__(self, home_coords): self.home_coords = home_coords self.options = self.get_options() - self.environment = Environment(loader=FileSystemLoader( local_path + '/html')) + self.environment = Environment(loader=FileSystemLoader(local_path + '/html')) def get_options(self): - return { - 'width': 670, + return {'width': 670, 'height': 470, 'zoom': 13, 'format': 'png', 'access_token': 'pk.eyJ1Ijoia2V2aW4zZHIiLCJhIjoiY2lrOGoxN2s2MDJzYnR6a3drbTYwdGxmMiJ9.bv5u7QgmcJd6dZfLDGoykw', 'mapid': 'kevin3dr.n56ffjoo', 'home_coords': self.home_coords, - 'menu': [ - {'name': 'Home', 'location': '/'}, - {'name': 'Track', 'location': '/track'}, - {'name': 'Command', 'location': '/command'} - ], + 'menu': [{'name': 'Home', 'location': '/'}, + {'name': 'Track', 'location': '/track'}, + {'name': 'Command', 'location': '/command'}], 'current_url': '/', 'json': '' } @@ -198,9 +193,10 @@ def command(self, current_coords): return self.get_template('command') def get_template(self, file_name): - template = self.environment.get_template( file_name + '.html') + template = self.environment.get_template(file_name + '.html') return template.render(options=self.options) + class DroneDelivery(object): def __init__(self, drone): self.drone = drone @@ -230,13 +226,13 @@ def track(self, lat=None, lon=None): # Connect to the Vehicle -print 'Connecting to vehicle on: %s' % connection_string +print('Connecting to vehicle on: %s' % connection_string) vehicle = connect(connection_string, wait_ready=True) -print 'Launching Drone...' +print('Launching Drone...') Drone().launch() -print 'Waiting for cherrypy engine...' +print('Waiting for cherrypy engine...') cherrypy.engine.block() if not args.connect: diff --git a/examples/simple_goto/simple_goto.py b/examples/simple_goto/simple_goto.py index b38e3b2d7..9fe54ee2f 100644 --- a/examples/simple_goto/simple_goto.py +++ b/examples/simple_goto/simple_goto.py @@ -10,22 +10,23 @@ Full documentation is provided at http://python.dronekit.io/examples/simple_goto.html """ -from dronekit import connect, VehicleMode, LocationGlobalRelative +from __future__ import print_function import time +from dronekit import connect, VehicleMode, LocationGlobalRelative -#Set up option parsing to get connection string -import argparse +# Set up option parsing to get connection string +import argparse parser = argparse.ArgumentParser(description='Commands vehicle using vehicle.simple_goto.') -parser.add_argument('--connect', - help="Vehicle connection target string. If not specified, SITL automatically started and used.") +parser.add_argument('--connect', + help="Vehicle connection target string. If not specified, SITL automatically started and used.") args = parser.parse_args() connection_string = args.connect sitl = None -#Start SITL if no connection string specified +# Start SITL if no connection string specified if not connection_string: import dronekit_sitl sitl = dronekit_sitl.start_default() @@ -33,7 +34,7 @@ # Connect to the Vehicle -print 'Connecting to vehicle on: %s' % connection_string +print('Connecting to vehicle on: %s' % connection_string) vehicle = connect(connection_string, wait_ready=True) @@ -42,62 +43,63 @@ def arm_and_takeoff(aTargetAltitude): Arms vehicle and fly to aTargetAltitude. """ - print "Basic pre-arm checks" + print("Basic pre-arm checks") # Don't try to arm until autopilot is ready while not vehicle.is_armable: - print " Waiting for vehicle to initialise..." + print(" Waiting for vehicle to initialise...") time.sleep(1) - - print "Arming motors" + print("Arming motors") # Copter should arm in GUIDED mode vehicle.mode = VehicleMode("GUIDED") - vehicle.armed = True + vehicle.armed = True # Confirm vehicle armed before attempting to take off - while not vehicle.armed: - print " Waiting for arming..." + while not vehicle.armed: + print(" Waiting for arming...") time.sleep(1) - print "Taking off!" - vehicle.simple_takeoff(aTargetAltitude) # Take off to target altitude + print("Taking off!") + vehicle.simple_takeoff(aTargetAltitude) # Take off to target altitude - # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command - # after Vehicle.simple_takeoff will execute immediately). + # Wait until the vehicle reaches a safe height before processing the goto + # (otherwise the command after Vehicle.simple_takeoff will execute + # immediately). while True: - print " Altitude: ", vehicle.location.global_relative_frame.alt - #Break and return from function just below target altitude. - if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: - print "Reached target altitude" + print(" Altitude: ", vehicle.location.global_relative_frame.alt) + # Break and return from function just below target altitude. + if vehicle.location.global_relative_frame.alt >= aTargetAltitude * 0.95: + print("Reached target altitude") break time.sleep(1) + arm_and_takeoff(10) -print "Set default/target airspeed to 3" +print("Set default/target airspeed to 3") vehicle.airspeed = 3 -print "Going towards first point for 30 seconds ..." +print("Going towards first point for 30 seconds ...") point1 = LocationGlobalRelative(-35.361354, 149.165218, 20) vehicle.simple_goto(point1) # sleep so we can see the change in map time.sleep(30) -print "Going towards second point for 30 seconds (groundspeed set to 10 m/s) ..." +print("Going towards second point for 30 seconds (groundspeed set to 10 m/s) ...") point2 = LocationGlobalRelative(-35.363244, 149.168801, 20) vehicle.simple_goto(point2, groundspeed=10) # sleep so we can see the change in map time.sleep(30) -print "Returning to Launch" +print("Returning to Launch") vehicle.mode = VehicleMode("RTL") -#Close vehicle object before exiting script -print "Close vehicle object" +# Close vehicle object before exiting script +print("Close vehicle object") vehicle.close() # Shut down simulator if it was started. -if sitl is not None: +if sitl: sitl.stop() From 3d6479a42ba8601ef9a5c771a85fa090336c9928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Roche?= Date: Fri, 21 Apr 2017 11:42:04 -0700 Subject: [PATCH 386/475] bump 2.9.1 --- CHANGELOG.md | 15 +++++++++++++++ docs/about/github_latest_release.txt | 22 ++++++++++++++++++++++ setup.py | 2 +- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f97d9e763..21331ab2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## Version 2.9.1 (2017-04-21) + +### Improvements +* home locatin notifications +* notify ci status to gitter +* basic python 3 support +* isolated logger function so implementers can override +* rename windows installer + +### Cleanup +* removed legacy cloud integrations + +### Bug Fixes +* fix missing ** operator for pymavlink compatibility + ## Version 2.9.0 (2016-08-29) ### Bug Fixes diff --git a/docs/about/github_latest_release.txt b/docs/about/github_latest_release.txt index a644a3bd7..9a67880ee 100644 --- a/docs/about/github_latest_release.txt +++ b/docs/about/github_latest_release.txt @@ -3,6 +3,28 @@ Changelog ========= +Version 2.9.1 (2017-04-21) +-------------------------- + +Improvements +~~~~~~~~~~~~ + +- home locatin notifications +- notify ci status to gitter +- basic python 3 support +- isolated logger function so implementers can override +- rename windows installer + +Cleanup +~~~~~~~ + +- removed legacy cloud integrations + +Bug Fixes +~~~~~~~~~ + +- fix missing \*\* operator for pymavlink compatibility + Version 2.9.0 (2016-08-29) -------------------------- diff --git a/setup.py b/setup.py index 465743374..f9b215d5a 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, Extension import platform -version = '2.9.0' +version = '2.9.1' setup(name='dronekit', zip_safe=True, From fa5e50c15827fb2a67624845fbe4f10701323ff2 Mon Sep 17 00:00:00 2001 From: cclauss Date: Fri, 7 Oct 2016 21:31:20 +0200 Subject: [PATCH 387/475] pymavlink==2.0.8 --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index c71a2d161..432e11ef2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ pymavlink>=2.0.6 -monotonic==1.2 -future==0.15.2 +monotonic>=1.3 +future>=0.15.2 nose==1.3.7 mock==2.0.0 dronekit-sitl==3.2.0 From ad9c438820708e645557162e8f2b82875a6665b1 Mon Sep 17 00:00:00 2001 From: "Dr.-Ing. Amilcar Do Carmo Lucas" Date: Mon, 13 Feb 2017 11:06:41 +0100 Subject: [PATCH 388/475] Ignore Visual studio file --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 7df502175..dec06d5da 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ build .idea *.pyc env +vs/.vs/dronekit-python/v14/*.suo From 5d2614f79092cc3ea03062a084579eb16577cd22 Mon Sep 17 00:00:00 2001 From: Jerry Lynch Date: Wed, 26 Apr 2017 21:08:40 -0400 Subject: [PATCH 389/475] fix BaseException.message deprecated in 2.6 and now an error in 3.x --- dronekit/mavlink.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dronekit/mavlink.py b/dronekit/mavlink.py index f5f3cf38d..7cff501df 100644 --- a/dronekit/mavlink.py +++ b/dronekit/mavlink.py @@ -182,7 +182,7 @@ def mavlink_thread_out(): errprinter('>>> mav send error:', e) break except APIException as e: - errprinter('>>> ' + str(e.message)) + errprinter('>>> ' + str(e)) self._alive = False self.master.close() self._death_error = e @@ -237,7 +237,7 @@ def mavlink_thread_in(): errprinter('>>> ' + str(e)) except APIException as e: - errprinter('>>> ' + str(e.message)) + errprinter('>>> ' + str(e)) self._alive = False self.master.close() self._death_error = e From 0cf17f8a6548d0c78452de471e6b81940af085e5 Mon Sep 17 00:00:00 2001 From: moobsen Date: Tue, 16 May 2017 13:46:31 +0200 Subject: [PATCH 390/475] Update README.md updated dead link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d93fc20cd..057eef556 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ The API is primarily intended for use in onboard companion computers (to support ## Getting Started -The [Getting Started](http://python.dronekit.io/guide/getting_started.html) guide explains how to set up DroneKit on each of the supported platforms (Linux, Mac OSX, Windows) and how to write a script to connect to a vehicle (real or simulated). +The [Quick Start](http://python.dronekit.io/guide/quick_start.html) guide explains how to set up DroneKit on each of the supported platforms (Linux, Mac OSX, Windows) and how to write a script to connect to a vehicle (real or simulated). A basic script looks like this: From 5f6a6e7c2e8ba173b5c9d393be56d7792f4b1f9a Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Thu, 1 Jun 2017 17:50:42 +1000 Subject: [PATCH 391/475] Add play_tune() method on vehicle, example for same --- dronekit/__init__.py | 5 ++++ examples/play_tune/play_tune.py | 42 +++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 examples/play_tune/play_tune.py diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 9a573c9e1..0d6ab1d6b 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -2146,6 +2146,11 @@ def send_capabilties_request(self, vehicle, name, m): capability_msg = vehicle.message_factory.command_long_encode(0, 0, mavutil.mavlink.MAV_CMD_REQUEST_AUTOPILOT_CAPABILITIES, 0, 1, 0, 0, 0, 0, 0, 0) vehicle.send_mavlink(capability_msg) + def play_tune(self, tune): + '''Request an AUTOPILOT_VERSION packet''' + msg = self.message_factory.play_tune_encode(0, 0, tune) + self.send_mavlink(msg) + def wait_ready(self, *types, **kwargs): """ Waits for specified attributes to be populated from the vehicle (values are initially ``None``). diff --git a/examples/play_tune/play_tune.py b/examples/play_tune/play_tune.py new file mode 100644 index 000000000..df0995222 --- /dev/null +++ b/examples/play_tune/play_tune.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +© Copyright 2017, Peter Barker +play_tune.py: GUIDED mode "simple goto" example (Copter Only) + +Demonstrates how to play a custom tune on a vehicle using the vehicle's buzzer + +Full documentation is provided at http://python.dronekit.io/examples/play_tune.html +""" + +from __future__ import print_function +import time +from dronekit import connect + + +# Set up option parsing to get connection string +import argparse +parser = argparse.ArgumentParser(description='Play tune on vehicle buzzer.') +parser.add_argument('--connect', + help="Vehicle connection target string. If not specified, SITL automatically started and used.") +parser.add_argument('--tune', type=str, help="tune to play", default="AAAA") +args = parser.parse_args() + +connection_string = args.connect +sitl = None + + +# Start SITL if no connection string specified +if not connection_string: + print("SITL doesn't do tunes?!") + import dronekit_sitl + sitl = dronekit_sitl.start_default() + connection_string = sitl.connection_string() + + +# Connect to the Vehicle +print('Connecting to vehicle on: %s' % connection_string) +vehicle = connect(connection_string, wait_ready=True) + +vehicle.play_tune(args.tune) From 07c3cd5ab93b041fd98e50b07073e04505d4a91a Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Mon, 19 Jun 2017 12:53:43 +1000 Subject: [PATCH 392/475] Improve diagnostics for heartbeat flight mode issues --- dronekit/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 0d6ab1d6b..68cf82c54 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1194,7 +1194,7 @@ def listener(self, name, m): self._autopilot_type = m.autopilot self._vehicle_type = m.type if self._is_mode_available(m.custom_mode, m.base_mode) == False: - raise APIException("mode %s not available on mavlink definition" % m.custom_mode) + raise APIException("mode (%s, %s) not available on mavlink definition" % (m.custom_mode, m.base_mode)) if self._autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_PX4: self._flightmode = mavutil.interpret_px4_mode(m.base_mode, m.custom_mode) else: From e89084eb4ead9c9bd0c9ecadc65e9d566f160af4 Mon Sep 17 00:00:00 2001 From: mhefny Date: Thu, 29 Jun 2017 06:34:18 +0200 Subject: [PATCH 393/475] fixing altitude float --- dronekit/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 68cf82c54..d962956d7 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1983,7 +1983,7 @@ def simple_takeoff(self, alt=None): """ if alt is not None: altitude = float(alt) - if math.isnan(alt) or math.isinf(alt): + if math.isnan(altitude) or math.isinf(altitude): raise ValueError("Altitude was NaN or Infinity. Please provide a real number") self._master.mav.command_long_send(0, 0, mavutil.mavlink.MAV_CMD_NAV_TAKEOFF, 0, 0, 0, 0, 0, 0, 0, altitude) From 5cdd73a41998d9b342605351844def2bc0302c3e Mon Sep 17 00:00:00 2001 From: Lars Kellogg-Stedman Date: Wed, 14 Jun 2017 23:08:04 -0400 Subject: [PATCH 394/475] allow setting flight mode using a string value This modifies mode.setter so that we can write: vehicle.mode = 'LOITER' Rather than: vehicle.mode = VehicleMode('LOITER') --- dronekit/__init__.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index d962956d7..aec069bae 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1561,7 +1561,26 @@ def _is_mode_available(self, custommode_code, basemode_code=0): @property def mode(self): """ - This attribute is used to get and set the current flight mode (:py:class:`VehicleMode`). + This attribute is used to get and set the current flight mode. You + can specify the value as a :py:class:`VehicleMode`, like this: + + .. code-block:: python + + vehicle.mode = VehicleMode('LOITER') + + Or as a simple string: + + .. code-block:: python + + vehicle.mode = 'LOITER' + + If you are targeting ArduPilot you can also specify the flight mode + using a numeric value (this will not work with PX4 autopilots): + + .. code-block:: python + + # set mode to LOITER + vehicle.mode = 5 """ if not self._flightmode: return None @@ -1569,8 +1588,13 @@ def mode(self): @mode.setter def mode(self, v): + if isinstance(v, basestring): + v = VehicleMode(v) + if self._autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_PX4: self._master.set_mode(v.name) + elif isinstance(v, int): + self._master.set_mode(v) else: self._master.set_mode(self._mode_mapping[v.name]) From ea252db8e73d5d499ca63e1c4b035db3b5641974 Mon Sep 17 00:00:00 2001 From: auturgy Date: Mon, 10 Jul 2017 23:05:37 +1000 Subject: [PATCH 395/475] Update requirements.txt update pymavlink --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 432e11ef2..b621f67c5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -pymavlink>=2.0.6 +pymavlink>=2.2.3 monotonic>=1.3 future>=0.15.2 nose==1.3.7 From 79b68eec98b0713ef302410c720dd2e852fc7387 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Mon, 24 Jul 2017 16:35:06 +1000 Subject: [PATCH 396/475] setup.py: bump pymavlink requirement to 2.2.3 to match requirements.txt --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index f9b215d5a..3824ee523 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ url='https://github.com/dronekit/dronekit-python', author='3D Robotics', install_requires=[ - 'pymavlink==2.0.6', + 'pymavlink>=2.2.3', 'monotonic==1.2', 'future==0.15.2' ], From 803ead0efa1dd33d8e5a83b743d5183182f0ff3f Mon Sep 17 00:00:00 2001 From: sanderux Date: Mon, 24 Jul 2017 01:05:38 +0200 Subject: [PATCH 397/475] Ignore heartbeats from groundstations --- dronekit/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index aec069bae..51c659ec4 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1189,6 +1189,9 @@ def listener(self, name, m): @self.on_message('HEARTBEAT') def listener(self, name, m): + # ignore groundstations + if m.type == mavutil.mavlink.MAV_TYPE_GCS: + return self._armed = (m.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED) != 0 self.notify_attribute_listeners('armed', self.armed, cache=True) self._autopilot_type = m.autopilot @@ -1352,6 +1355,9 @@ def listener(_): @self.on_message(['HEARTBEAT']) def listener(self, name, msg): + # ignore groundstations + if msg.type == mavutil.mavlink.MAV_TYPE_GCS: + return self._heartbeat_system = msg.get_srcSystem() self._heartbeat_lastreceived = monotonic.monotonic() if self._heartbeat_timeout: From 92ee230792f7f3005556e2ad772d12bbd43f6684 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Thu, 27 Jul 2017 11:04:35 +1000 Subject: [PATCH 398/475] examples: vehicle_state no longer arms the vehicle --- examples/vehicle_state/vehicle_state.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index 4518533e1..c4d7d55c6 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -127,12 +127,12 @@ # If required, you can provide additional information about initialisation # using `vehicle.gps_0.fix_type` and `vehicle.mode.name`. -print "\nSet Vehicle.armed=True (currently: %s)" % vehicle.armed -vehicle.armed = True -while not vehicle.armed: - print " Waiting for arming..." - time.sleep(1) -print " Vehicle is armed: %s" % vehicle.armed +#print "\nSet Vehicle.armed=True (currently: %s)" % vehicle.armed +#vehicle.armed = True +#while not vehicle.armed: +# print " Waiting for arming..." +# time.sleep(1) +#print " Vehicle is armed: %s" % vehicle.armed # Add and remove and attribute callbacks @@ -250,7 +250,7 @@ def any_parameter_callback(self, attr_name, value): ## Reset variables to sensible values. print "\nReset vehicle attributes/parameters and exit" vehicle.mode = VehicleMode("STABILIZE") -vehicle.armed = False +#vehicle.armed = False vehicle.parameters['THR_MIN']=130 vehicle.parameters['THR_MID']=500 From 754ce6223dd26179045eaa394d5df0a5f787ebb2 Mon Sep 17 00:00:00 2001 From: cclauss Date: Mon, 4 Sep 2017 13:55:19 +0200 Subject: [PATCH 399/475] Define name `time_max` in sitl/test_110.py Without this change, a NameError is raised on line 50. --- dronekit/test/sitl/test_110.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dronekit/test/sitl/test_110.py b/dronekit/test/sitl/test_110.py index 8386ba0b2..9ab32c6c0 100644 --- a/dronekit/test/sitl/test_110.py +++ b/dronekit/test/sitl/test_110.py @@ -43,7 +43,8 @@ def armed_callback(vehicle, attribute, value): vehicle.armed = True # Wait for ACK. - wait_for(lambda : armed_callback.called, 10) + time_max = 10 + wait_for(lambda : armed_callback.called, time_max) # Ensure the callback was called. assert armed_callback.called > 0, "Callback should have been called within %d seconds" % (time_max,) From d8cca696b5b96a344d6f466662b52d2da253cbbf Mon Sep 17 00:00:00 2001 From: cclauss Date: Thu, 14 Sep 2017 13:22:45 +0200 Subject: [PATCH 400/475] Modernize Python 2 code to get ready for Python 3 --- .travis.yml | 11 +- .../channel_overrides/channel_overrides.py | 59 +-- examples/create_attribute/create_attribute.py | 9 +- examples/flight_replay/flight_replay.py | 32 +- examples/follow_me/follow_me.py | 27 +- examples/gcs/microgcs.py | 3 +- .../guided_set_speed_yaw.py | 27 +- examples/mission_basic/mission_basic.py | 433 +++++++++--------- .../mission_import_export.py | 345 +++++++------- examples/performance_test/performance_test.py | 5 +- examples/vehicle_state/vehicle_state.py | 161 +++---- windows/returnVersion.py | 23 +- 12 files changed, 572 insertions(+), 563 deletions(-) diff --git a/.travis.yml b/.travis.yml index cc7d067ef..9fc8157b9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ env: - SITL_RATE=200 python: - - 2.7.13 + - 2.7 - 3.6 before_install: @@ -17,10 +17,10 @@ install: - pip install flake8 before_script: - # --exit-zero means that flake8 will not stop the build - # 127 characters is the width of a GitHub editor - - flake8 . --count --exit-zero --max-line-length=127 --select=E999 --statistics # syntax errors - - flake8 . --count --exit-zero --max-line-length=127 --statistics + # stop the build if there are Python syntax errors or undefined names + - flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics script: - nosetests --debug=nose,nose.importer --debug-log=nose_debug -svx dronekit.test.unit @@ -41,7 +41,6 @@ notifications: matrix: allow_failures: - python: 3.6 - fast_finish: true branches: only: diff --git a/examples/channel_overrides/channel_overrides.py b/examples/channel_overrides/channel_overrides.py index a44f4f132..358a7ea51 100644 --- a/examples/channel_overrides/channel_overrides.py +++ b/examples/channel_overrides/channel_overrides.py @@ -17,6 +17,7 @@ Full documentation is provided at http://python.dronekit.io/examples/channel_overrides.html """ +from __future__ import print_function from dronekit import connect @@ -39,61 +40,61 @@ # Connect to the Vehicle -print 'Connecting to vehicle on: %s' % connection_string +print('Connecting to vehicle on: %s' % connection_string) vehicle = connect(connection_string, wait_ready=True) # Get all original channel values (before override) -print "Channel values from RC Tx:", vehicle.channels +print("Channel values from RC Tx:", vehicle.channels) # Access channels individually -print "Read channels individually:" -print " Ch1: %s" % vehicle.channels['1'] -print " Ch2: %s" % vehicle.channels['2'] -print " Ch3: %s" % vehicle.channels['3'] -print " Ch4: %s" % vehicle.channels['4'] -print " Ch5: %s" % vehicle.channels['5'] -print " Ch6: %s" % vehicle.channels['6'] -print " Ch7: %s" % vehicle.channels['7'] -print " Ch8: %s" % vehicle.channels['8'] -print "Number of channels: %s" % len(vehicle.channels) +print("Read channels individually:") +print(" Ch1: %s" % vehicle.channels['1']) +print(" Ch2: %s" % vehicle.channels['2']) +print(" Ch3: %s" % vehicle.channels['3']) +print(" Ch4: %s" % vehicle.channels['4']) +print(" Ch5: %s" % vehicle.channels['5']) +print(" Ch6: %s" % vehicle.channels['6']) +print(" Ch7: %s" % vehicle.channels['7']) +print(" Ch8: %s" % vehicle.channels['8']) +print("Number of channels: %s" % len(vehicle.channels)) # Override channels -print "\nChannel overrides: %s" % vehicle.channels.overrides +print("\nChannel overrides: %s" % vehicle.channels.overrides) -print "Set Ch2 override to 200 (indexing syntax)" +print("Set Ch2 override to 200 (indexing syntax)") vehicle.channels.overrides['2'] = 200 -print " Channel overrides: %s" % vehicle.channels.overrides -print " Ch2 override: %s" % vehicle.channels.overrides['2'] +print(" Channel overrides: %s" % vehicle.channels.overrides) +print(" Ch2 override: %s" % vehicle.channels.overrides['2']) -print "Set Ch3 override to 300 (dictionary syntax)" +print("Set Ch3 override to 300 (dictionary syntax)") vehicle.channels.overrides = {'3':300} -print " Channel overrides: %s" % vehicle.channels.overrides +print(" Channel overrides: %s" % vehicle.channels.overrides) -print "Set Ch1-Ch8 overrides to 110-810 respectively" +print("Set Ch1-Ch8 overrides to 110-810 respectively") vehicle.channels.overrides = {'1': 110, '2': 210,'3': 310,'4':4100, '5':510,'6':610,'7':710,'8':810} -print " Channel overrides: %s" % vehicle.channels.overrides +print(" Channel overrides: %s" % vehicle.channels.overrides) # Clear override by setting channels to None -print "\nCancel Ch2 override (indexing syntax)" +print("\nCancel Ch2 override (indexing syntax)") vehicle.channels.overrides['2'] = None -print " Channel overrides: %s" % vehicle.channels.overrides +print(" Channel overrides: %s" % vehicle.channels.overrides) -print "Clear Ch3 override (del syntax)" +print("Clear Ch3 override (del syntax)") del vehicle.channels.overrides['3'] -print " Channel overrides: %s" % vehicle.channels.overrides +print(" Channel overrides: %s" % vehicle.channels.overrides) -print "Clear Ch5, Ch6 override and set channel 3 to 500 (dictionary syntax)" +print("Clear Ch5, Ch6 override and set channel 3 to 500 (dictionary syntax)") vehicle.channels.overrides = {'5':None, '6':None,'3':500} -print " Channel overrides: %s" % vehicle.channels.overrides +print(" Channel overrides: %s" % vehicle.channels.overrides) -print "Clear all overrides" +print("Clear all overrides") vehicle.channels.overrides = {} -print " Channel overrides: %s" % vehicle.channels.overrides +print(" Channel overrides: %s" % vehicle.channels.overrides) #Close vehicle object before exiting script -print "\nClose vehicle object" +print("\nClose vehicle object") vehicle.close() # Shut down simulator if it was started. diff --git a/examples/create_attribute/create_attribute.py b/examples/create_attribute/create_attribute.py index 5aa154f4b..5d8a20e15 100644 --- a/examples/create_attribute/create_attribute.py +++ b/examples/create_attribute/create_attribute.py @@ -14,6 +14,7 @@ Full documentation is provided at http://python.dronekit.io/examples/create_attribute.html """ +from __future__ import print_function from dronekit import connect, Vehicle from my_vehicle import MyVehicle #Our custom vehicle class @@ -40,7 +41,7 @@ # Connect to the Vehicle -print 'Connecting to vehicle on: %s' % connection_string +print('Connecting to vehicle on: %s' % connection_string) vehicle = connect(connection_string, wait_ready=True, vehicle_class=MyVehicle) # Add observer for the custom attribute @@ -48,17 +49,17 @@ def raw_imu_callback(self, attr_name, value): # attr_name == 'raw_imu' # value == vehicle.raw_imu - print value + print(value) vehicle.add_attribute_listener('raw_imu', raw_imu_callback) -print 'Display RAW_IMU messages for 5 seconds and then exit.' +print('Display RAW_IMU messages for 5 seconds and then exit.') time.sleep(5) #The message listener can be unset using ``vehicle.remove_message_listener`` #Close vehicle object before exiting script -print "Close vehicle object" +print("Close vehicle object") vehicle.close() # Shut down simulator if it was started. diff --git a/examples/flight_replay/flight_replay.py b/examples/flight_replay/flight_replay.py index 04f0a599c..a7564abd1 100644 --- a/examples/flight_replay/flight_replay.py +++ b/examples/flight_replay/flight_replay.py @@ -10,6 +10,7 @@ Full documentation is provided at http://python.dronekit.io/examples/flight_replay.html """ +from __future__ import print_function from dronekit import connect, Command, VehicleMode, LocationGlobalRelative from pymavlink import mavutil @@ -107,7 +108,7 @@ def arm_and_takeoff(aTargetAltitude): # Don't try to arm until autopilot is ready while not vehicle.is_armable: - print " Waiting for vehicle to initialise..." + print(" Waiting for vehicle to initialise...") time.sleep(1) # Set mode to GUIDED for arming and takeoff: @@ -118,10 +119,10 @@ def arm_and_takeoff(aTargetAltitude): # Confirm vehicle armed before attempting to take off while not vehicle.armed: vehicle.armed = True - print " Waiting for arming..." + print(" Waiting for arming...") time.sleep(1) - print " Taking off!" + print(" Taking off!") vehicle.simple_takeoff(aTargetAltitude) # Take off to target altitude # Wait until the vehicle reaches a safe height @@ -130,16 +131,16 @@ def arm_and_takeoff(aTargetAltitude): requiredAlt = aTargetAltitude*0.95 #Break and return from function just below target altitude. if vehicle.location.global_relative_frame.alt>=requiredAlt: - print " Reached target altitude of ~%f" % (aTargetAltitude) + print(" Reached target altitude of ~%f" % (aTargetAltitude)) break - print " Altitude: %f < %f" % (vehicle.location.global_relative_frame.alt, - requiredAlt) + print(" Altitude: %f < %f" % (vehicle.location.global_relative_frame.alt, + requiredAlt)) time.sleep(1) print("Generating waypoints from tlog...") messages = position_messages_from_tlog(args.tlog) -print " Generated %d waypoints from tlog" % len(messages) +print(" Generated %d waypoints from tlog" % len(messages)) if len(messages) == 0: print("No position messages found in log") exit(0) @@ -157,7 +158,7 @@ def arm_and_takeoff(aTargetAltitude): connection_string = sitl.connection_string() # Connect to the Vehicle -print 'Connecting to vehicle on: %s' % connection_string +print('Connecting to vehicle on: %s' % connection_string) vehicle = connect(connection_string, wait_ready=True) @@ -168,8 +169,7 @@ def arm_and_takeoff(aTargetAltitude): cmds = vehicle.commands cmds.clear() -for i in xrange(0, len(messages)): - pt = messages[i] +for pt in messages: #print "Point: %d %d" % (pt.lat, pt.lon,) lat = pt.lat lon = pt.lon @@ -189,11 +189,11 @@ def arm_and_takeoff(aTargetAltitude): print("Uploading %d waypoints to vehicle..." % len(messages)) cmds.upload() -print "Arm and Takeoff" +print("Arm and Takeoff") arm_and_takeoff(30) -print "Starting mission" +print("Starting mission") # Reset mission set to first (0) waypoint vehicle.commands.next=0 @@ -207,20 +207,20 @@ def arm_and_takeoff(aTargetAltitude): time_start = time.time() while time.time() - time_start < 60: nextwaypoint=vehicle.commands.next - print 'Distance to waypoint (%s): %s' % (nextwaypoint, distance_to_current_waypoint()) + print('Distance to waypoint (%s): %s' % (nextwaypoint, distance_to_current_waypoint())) if nextwaypoint==len(messages): - print "Exit 'standard' mission when start heading to final waypoint" + print("Exit 'standard' mission when start heading to final waypoint") break; time.sleep(1) -print 'Return to launch' +print('Return to launch') while (vehicle.mode.name != "RTL"): vehicle.mode = VehicleMode("RTL") time.sleep(0.1) #Close vehicle object before exiting script -print "Close vehicle object" +print("Close vehicle object") vehicle.close() # Shut down simulator if it was started. diff --git a/examples/follow_me/follow_me.py b/examples/follow_me/follow_me.py index bd89a4e96..aa489d26b 100644 --- a/examples/follow_me/follow_me.py +++ b/examples/follow_me/follow_me.py @@ -13,6 +13,7 @@ Example documentation: http://python.dronekit.io/examples/follow_me.html """ +from __future__ import print_function from dronekit import connect, VehicleMode, LocationGlobalRelative import gps @@ -38,7 +39,7 @@ connection_string = sitl.connection_string() # Connect to the Vehicle -print 'Connecting to vehicle on: %s' % connection_string +print('Connecting to vehicle on: %s' % connection_string) vehicle = connect(connection_string, wait_ready=True) @@ -48,31 +49,31 @@ def arm_and_takeoff(aTargetAltitude): Arms vehicle and fly to aTargetAltitude. """ - print "Basic pre-arm checks" + print("Basic pre-arm checks") # Don't let the user try to arm until autopilot is ready while not vehicle.is_armable: - print " Waiting for vehicle to initialise..." + print(" Waiting for vehicle to initialise...") time.sleep(1) - print "Arming motors" + print("Arming motors") # Copter should arm in GUIDED mode vehicle.mode = VehicleMode("GUIDED") vehicle.armed = True while not vehicle.armed: - print " Waiting for arming..." + print(" Waiting for arming...") time.sleep(1) - print "Taking off!" + print("Taking off!") vehicle.simple_takeoff(aTargetAltitude) # Take off to target altitude # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.simple_takeoff will execute immediately). while True: - print " Altitude: ", vehicle.location.global_relative_frame.alt + print(" Altitude: ", vehicle.location.global_relative_frame.alt) if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: #Trigger just below target alt. - print "Reached target altitude" + print("Reached target altitude") break time.sleep(1) @@ -88,17 +89,17 @@ def arm_and_takeoff(aTargetAltitude): while True: if vehicle.mode.name != "GUIDED": - print "User has changed flight modes - aborting follow-me" + print("User has changed flight modes - aborting follow-me") break # Read the GPS state from the laptop - gpsd.next() + next(gpsd) # Once we have a valid location (see gpsd documentation) we can start moving our vehicle around if (gpsd.valid & gps.LATLON_SET) != 0: altitude = 30 # in meters dest = LocationGlobalRelative(gpsd.fix.latitude, gpsd.fix.longitude, altitude) - print "Going to: %s" % dest + print("Going to: %s" % dest) # A better implementation would only send new waypoints if the position had changed significantly vehicle.simple_goto(dest) @@ -108,11 +109,11 @@ def arm_and_takeoff(aTargetAltitude): time.sleep(2) except socket.error: - print "Error: gpsd service does not seem to be running, plug in USB GPS or run run-fake-gps.sh" + print("Error: gpsd service does not seem to be running, plug in USB GPS or run run-fake-gps.sh") sys.exit(1) #Close vehicle object before exiting script -print "Close vehicle object" +print("Close vehicle object") vehicle.close() # Shut down simulator if it was started. diff --git a/examples/gcs/microgcs.py b/examples/gcs/microgcs.py index 1ebee38f4..a3d33aaca 100644 --- a/examples/gcs/microgcs.py +++ b/examples/gcs/microgcs.py @@ -4,6 +4,7 @@ """ © Copyright 2015-2016, 3D Robotics. """ +from __future__ import print_function # # This is a small example of the python drone API - an ultra minimal GCS # @@ -32,7 +33,7 @@ connection_string = sitl.connection_string() # Connect to the Vehicle -print 'Connecting to vehicle on: %s' % connection_string +print('Connecting to vehicle on: %s' % connection_string) vehicle = connect(connection_string, wait_ready=True) def setMode(mode): diff --git a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py index 0c161b6af..3dee73025 100644 --- a/examples/guided_set_speed_yaw/guided_set_speed_yaw.py +++ b/examples/guided_set_speed_yaw/guided_set_speed_yaw.py @@ -9,6 +9,7 @@ Example documentation: http://python.dronekit.io/examples/guided-set-speed-yaw-demo.html """ +from __future__ import print_function from dronekit import connect, VehicleMode, LocationGlobal, LocationGlobalRelative from pymavlink import mavutil # Needed for command message definitions @@ -35,7 +36,7 @@ # Connect to the Vehicle -print 'Connecting to vehicle on: %s' % connection_string +print('Connecting to vehicle on: %s' % connection_string) vehicle = connect(connection_string, wait_ready=True) @@ -44,31 +45,31 @@ def arm_and_takeoff(aTargetAltitude): Arms vehicle and fly to aTargetAltitude. """ - print "Basic pre-arm checks" + print("Basic pre-arm checks") # Don't let the user try to arm until autopilot is ready while not vehicle.is_armable: - print " Waiting for vehicle to initialise..." + print(" Waiting for vehicle to initialise...") time.sleep(1) - print "Arming motors" + print("Arming motors") # Copter should arm in GUIDED mode vehicle.mode = VehicleMode("GUIDED") vehicle.armed = True while not vehicle.armed: - print " Waiting for arming..." + print(" Waiting for arming...") time.sleep(1) - print "Taking off!" + print("Taking off!") vehicle.simple_takeoff(aTargetAltitude) # Take off to target altitude # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command # after Vehicle.simple_takeoff will execute immediately). while True: - print " Altitude: ", vehicle.location.global_relative_frame.alt + print(" Altitude: ", vehicle.location.global_relative_frame.alt) if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: #Trigger just below target alt. - print "Reached target altitude" + print("Reached target altitude") break time.sleep(1) @@ -316,9 +317,9 @@ def goto(dNorth, dEast, gotoFunction=vehicle.simple_goto): while vehicle.mode.name=="GUIDED": #Stop action if we are no longer in guided mode. #print "DEBUG: mode: %s" % vehicle.mode.name remainingDistance=get_distance_metres(vehicle.location.global_relative_frame, targetLocation) - print "Distance to target: ", remainingDistance + print("Distance to target: ", remainingDistance) if remainingDistance<=targetDistance*0.01: #Just below target, in case of undershoot. - print "Reached target" + print("Reached target") break; time.sleep(2) @@ -605,12 +606,12 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z, duration): print("Set new home location to current location") vehicle.home_location=vehicle.location.global_frame -print "Get new home location" +print("Get new home location") #This reloads the home location in DroneKit and GCSs cmds = vehicle.commands cmds.download() cmds.wait_ready() -print " Home Location: %s" % vehicle.home_location +print(" Home Location: %s" % vehicle.home_location) print("Yaw 90 relative (to previous yaw heading)") @@ -638,7 +639,7 @@ def send_global_velocity(velocity_x, velocity_y, velocity_z, duration): #Close vehicle object before exiting script -print "Close vehicle object" +print("Close vehicle object") vehicle.close() # Shut down simulator if it was started. diff --git a/examples/mission_basic/mission_basic.py b/examples/mission_basic/mission_basic.py index 4255ec25c..8e394e4db 100644 --- a/examples/mission_basic/mission_basic.py +++ b/examples/mission_basic/mission_basic.py @@ -1,216 +1,217 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -© Copyright 2015-2016, 3D Robotics. -mission_basic.py: Example demonstrating basic mission operations including creating, clearing and monitoring missions. - -Full documentation is provided at http://python.dronekit.io/examples/mission_basic.html -""" - -from dronekit import connect, VehicleMode, LocationGlobalRelative, LocationGlobal, Command -import time -import math -from pymavlink import mavutil - - -#Set up option parsing to get connection string -import argparse -parser = argparse.ArgumentParser(description='Demonstrates basic mission operations.') -parser.add_argument('--connect', - help="vehicle connection target string. If not specified, SITL automatically started and used.") -args = parser.parse_args() - -connection_string = args.connect -sitl = None - - -#Start SITL if no connection string specified -if not connection_string: - import dronekit_sitl - sitl = dronekit_sitl.start_default() - connection_string = sitl.connection_string() - - -# Connect to the Vehicle -print 'Connecting to vehicle on: %s' % connection_string -vehicle = connect(connection_string, wait_ready=True) - - -def get_location_metres(original_location, dNorth, dEast): - """ - Returns a LocationGlobal object containing the latitude/longitude `dNorth` and `dEast` metres from the - specified `original_location`. The returned Location has the same `alt` value - as `original_location`. - - The function is useful when you want to move the vehicle around specifying locations relative to - the current vehicle position. - The algorithm is relatively accurate over small distances (10m within 1km) except close to the poles. - For more information see: - http://gis.stackexchange.com/questions/2951/algorithm-for-offsetting-a-latitude-longitude-by-some-amount-of-meters - """ - earth_radius=6378137.0 #Radius of "spherical" earth - #Coordinate offsets in radians - dLat = dNorth/earth_radius - dLon = dEast/(earth_radius*math.cos(math.pi*original_location.lat/180)) - - #New position in decimal degrees - newlat = original_location.lat + (dLat * 180/math.pi) - newlon = original_location.lon + (dLon * 180/math.pi) - return LocationGlobal(newlat, newlon,original_location.alt) - - -def get_distance_metres(aLocation1, aLocation2): - """ - Returns the ground distance in metres between two LocationGlobal objects. - - This method is an approximation, and will not be accurate over large distances and close to the - earth's poles. It comes from the ArduPilot test code: - https://github.com/diydrones/ardupilot/blob/master/Tools/autotest/common.py - """ - dlat = aLocation2.lat - aLocation1.lat - dlong = aLocation2.lon - aLocation1.lon - return math.sqrt((dlat*dlat) + (dlong*dlong)) * 1.113195e5 - - - -def distance_to_current_waypoint(): - """ - Gets distance in metres to the current waypoint. - It returns None for the first waypoint (Home location). - """ - nextwaypoint = vehicle.commands.next - if nextwaypoint==0: - return None - missionitem=vehicle.commands[nextwaypoint-1] #commands are zero indexed - lat = missionitem.x - lon = missionitem.y - alt = missionitem.z - targetWaypointLocation = LocationGlobalRelative(lat,lon,alt) - distancetopoint = get_distance_metres(vehicle.location.global_frame, targetWaypointLocation) - return distancetopoint - - -def download_mission(): - """ - Download the current mission from the vehicle. - """ - cmds = vehicle.commands - cmds.download() - cmds.wait_ready() # wait until download is complete. - - - -def adds_square_mission(aLocation, aSize): - """ - Adds a takeoff command and four waypoint commands to the current mission. - The waypoints are positioned to form a square of side length 2*aSize around the specified LocationGlobal (aLocation). - - The function assumes vehicle.commands matches the vehicle mission state - (you must have called download at least once in the session and after clearing the mission) - """ - - cmds = vehicle.commands - - print " Clear any existing commands" - cmds.clear() - - print " Define/add new commands." - # Add new commands. The meaning/order of the parameters is documented in the Command class. - - #Add MAV_CMD_NAV_TAKEOFF command. This is ignored if the vehicle is already in the air. - cmds.add(Command( 0, 0, 0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_TAKEOFF, 0, 0, 0, 0, 0, 0, 0, 0, 10)) - - #Define the four MAV_CMD_NAV_WAYPOINT locations and add the commands - point1 = get_location_metres(aLocation, aSize, -aSize) - point2 = get_location_metres(aLocation, aSize, aSize) - point3 = get_location_metres(aLocation, -aSize, aSize) - point4 = get_location_metres(aLocation, -aSize, -aSize) - cmds.add(Command( 0, 0, 0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0, point1.lat, point1.lon, 11)) - cmds.add(Command( 0, 0, 0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0, point2.lat, point2.lon, 12)) - cmds.add(Command( 0, 0, 0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0, point3.lat, point3.lon, 13)) - cmds.add(Command( 0, 0, 0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0, point4.lat, point4.lon, 14)) - #add dummy waypoint "5" at point 4 (lets us know when have reached destination) - cmds.add(Command( 0, 0, 0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0, point4.lat, point4.lon, 14)) - - print " Upload new commands to vehicle" - cmds.upload() - - -def arm_and_takeoff(aTargetAltitude): - """ - Arms vehicle and fly to aTargetAltitude. - """ - - print "Basic pre-arm checks" - # Don't let the user try to arm until autopilot is ready - while not vehicle.is_armable: - print " Waiting for vehicle to initialise..." - time.sleep(1) - - - print "Arming motors" - # Copter should arm in GUIDED mode - vehicle.mode = VehicleMode("GUIDED") - vehicle.armed = True - - while not vehicle.armed: - print " Waiting for arming..." - time.sleep(1) - - print "Taking off!" - vehicle.simple_takeoff(aTargetAltitude) # Take off to target altitude - - # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command - # after Vehicle.simple_takeoff will execute immediately). - while True: - print " Altitude: ", vehicle.location.global_relative_frame.alt - if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: #Trigger just below target alt. - print "Reached target altitude" - break - time.sleep(1) - - -print 'Create a new mission (for current location)' -adds_square_mission(vehicle.location.global_frame,50) - - -# From Copter 3.3 you will be able to take off using a mission item. Plane must take off using a mission item (currently). -arm_and_takeoff(10) - -print "Starting mission" -# Reset mission set to first (0) waypoint -vehicle.commands.next=0 - -# Set mode to AUTO to start mission -vehicle.mode = VehicleMode("AUTO") - - -# Monitor mission. -# Demonstrates getting and setting the command number -# Uses distance_to_current_waypoint(), a convenience function for finding the -# distance to the next waypoint. - -while True: - nextwaypoint=vehicle.commands.next - print 'Distance to waypoint (%s): %s' % (nextwaypoint, distance_to_current_waypoint()) - - if nextwaypoint==3: #Skip to next waypoint - print 'Skipping to Waypoint 5 when reach waypoint 3' - vehicle.commands.next = 5 - if nextwaypoint==5: #Dummy waypoint - as soon as we reach waypoint 4 this is true and we exit. - print "Exit 'standard' mission when start heading to final waypoint (5)" - break; - time.sleep(1) - -print 'Return to launch' -vehicle.mode = VehicleMode("RTL") - - -#Close vehicle object before exiting script -print "Close vehicle object" -vehicle.close() - -# Shut down simulator if it was started. -if sitl is not None: - sitl.stop() +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +© Copyright 2015-2016, 3D Robotics. +mission_basic.py: Example demonstrating basic mission operations including creating, clearing and monitoring missions. + +Full documentation is provided at http://python.dronekit.io/examples/mission_basic.html +""" +from __future__ import print_function + +from dronekit import connect, VehicleMode, LocationGlobalRelative, LocationGlobal, Command +import time +import math +from pymavlink import mavutil + + +#Set up option parsing to get connection string +import argparse +parser = argparse.ArgumentParser(description='Demonstrates basic mission operations.') +parser.add_argument('--connect', + help="vehicle connection target string. If not specified, SITL automatically started and used.") +args = parser.parse_args() + +connection_string = args.connect +sitl = None + + +#Start SITL if no connection string specified +if not connection_string: + import dronekit_sitl + sitl = dronekit_sitl.start_default() + connection_string = sitl.connection_string() + + +# Connect to the Vehicle +print('Connecting to vehicle on: %s' % connection_string) +vehicle = connect(connection_string, wait_ready=True) + + +def get_location_metres(original_location, dNorth, dEast): + """ + Returns a LocationGlobal object containing the latitude/longitude `dNorth` and `dEast` metres from the + specified `original_location`. The returned Location has the same `alt` value + as `original_location`. + + The function is useful when you want to move the vehicle around specifying locations relative to + the current vehicle position. + The algorithm is relatively accurate over small distances (10m within 1km) except close to the poles. + For more information see: + http://gis.stackexchange.com/questions/2951/algorithm-for-offsetting-a-latitude-longitude-by-some-amount-of-meters + """ + earth_radius=6378137.0 #Radius of "spherical" earth + #Coordinate offsets in radians + dLat = dNorth/earth_radius + dLon = dEast/(earth_radius*math.cos(math.pi*original_location.lat/180)) + + #New position in decimal degrees + newlat = original_location.lat + (dLat * 180/math.pi) + newlon = original_location.lon + (dLon * 180/math.pi) + return LocationGlobal(newlat, newlon,original_location.alt) + + +def get_distance_metres(aLocation1, aLocation2): + """ + Returns the ground distance in metres between two LocationGlobal objects. + + This method is an approximation, and will not be accurate over large distances and close to the + earth's poles. It comes from the ArduPilot test code: + https://github.com/diydrones/ardupilot/blob/master/Tools/autotest/common.py + """ + dlat = aLocation2.lat - aLocation1.lat + dlong = aLocation2.lon - aLocation1.lon + return math.sqrt((dlat*dlat) + (dlong*dlong)) * 1.113195e5 + + + +def distance_to_current_waypoint(): + """ + Gets distance in metres to the current waypoint. + It returns None for the first waypoint (Home location). + """ + nextwaypoint = vehicle.commands.next + if nextwaypoint==0: + return None + missionitem=vehicle.commands[nextwaypoint-1] #commands are zero indexed + lat = missionitem.x + lon = missionitem.y + alt = missionitem.z + targetWaypointLocation = LocationGlobalRelative(lat,lon,alt) + distancetopoint = get_distance_metres(vehicle.location.global_frame, targetWaypointLocation) + return distancetopoint + + +def download_mission(): + """ + Download the current mission from the vehicle. + """ + cmds = vehicle.commands + cmds.download() + cmds.wait_ready() # wait until download is complete. + + + +def adds_square_mission(aLocation, aSize): + """ + Adds a takeoff command and four waypoint commands to the current mission. + The waypoints are positioned to form a square of side length 2*aSize around the specified LocationGlobal (aLocation). + + The function assumes vehicle.commands matches the vehicle mission state + (you must have called download at least once in the session and after clearing the mission) + """ + + cmds = vehicle.commands + + print(" Clear any existing commands") + cmds.clear() + + print(" Define/add new commands.") + # Add new commands. The meaning/order of the parameters is documented in the Command class. + + #Add MAV_CMD_NAV_TAKEOFF command. This is ignored if the vehicle is already in the air. + cmds.add(Command( 0, 0, 0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_TAKEOFF, 0, 0, 0, 0, 0, 0, 0, 0, 10)) + + #Define the four MAV_CMD_NAV_WAYPOINT locations and add the commands + point1 = get_location_metres(aLocation, aSize, -aSize) + point2 = get_location_metres(aLocation, aSize, aSize) + point3 = get_location_metres(aLocation, -aSize, aSize) + point4 = get_location_metres(aLocation, -aSize, -aSize) + cmds.add(Command( 0, 0, 0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0, point1.lat, point1.lon, 11)) + cmds.add(Command( 0, 0, 0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0, point2.lat, point2.lon, 12)) + cmds.add(Command( 0, 0, 0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0, point3.lat, point3.lon, 13)) + cmds.add(Command( 0, 0, 0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0, point4.lat, point4.lon, 14)) + #add dummy waypoint "5" at point 4 (lets us know when have reached destination) + cmds.add(Command( 0, 0, 0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 0, 0, 0, 0, 0, point4.lat, point4.lon, 14)) + + print(" Upload new commands to vehicle") + cmds.upload() + + +def arm_and_takeoff(aTargetAltitude): + """ + Arms vehicle and fly to aTargetAltitude. + """ + + print("Basic pre-arm checks") + # Don't let the user try to arm until autopilot is ready + while not vehicle.is_armable: + print(" Waiting for vehicle to initialise...") + time.sleep(1) + + + print("Arming motors") + # Copter should arm in GUIDED mode + vehicle.mode = VehicleMode("GUIDED") + vehicle.armed = True + + while not vehicle.armed: + print(" Waiting for arming...") + time.sleep(1) + + print("Taking off!") + vehicle.simple_takeoff(aTargetAltitude) # Take off to target altitude + + # Wait until the vehicle reaches a safe height before processing the goto (otherwise the command + # after Vehicle.simple_takeoff will execute immediately). + while True: + print(" Altitude: ", vehicle.location.global_relative_frame.alt) + if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95: #Trigger just below target alt. + print("Reached target altitude") + break + time.sleep(1) + + +print('Create a new mission (for current location)') +adds_square_mission(vehicle.location.global_frame,50) + + +# From Copter 3.3 you will be able to take off using a mission item. Plane must take off using a mission item (currently). +arm_and_takeoff(10) + +print("Starting mission") +# Reset mission set to first (0) waypoint +vehicle.commands.next=0 + +# Set mode to AUTO to start mission +vehicle.mode = VehicleMode("AUTO") + + +# Monitor mission. +# Demonstrates getting and setting the command number +# Uses distance_to_current_waypoint(), a convenience function for finding the +# distance to the next waypoint. + +while True: + nextwaypoint=vehicle.commands.next + print('Distance to waypoint (%s): %s' % (nextwaypoint, distance_to_current_waypoint())) + + if nextwaypoint==3: #Skip to next waypoint + print('Skipping to Waypoint 5 when reach waypoint 3') + vehicle.commands.next = 5 + if nextwaypoint==5: #Dummy waypoint - as soon as we reach waypoint 4 this is true and we exit. + print("Exit 'standard' mission when start heading to final waypoint (5)") + break; + time.sleep(1) + +print('Return to launch') +vehicle.mode = VehicleMode("RTL") + + +#Close vehicle object before exiting script +print("Close vehicle object") +vehicle.close() + +# Shut down simulator if it was started. +if sitl is not None: + sitl.stop() diff --git a/examples/mission_import_export/mission_import_export.py b/examples/mission_import_export/mission_import_export.py index 13a96c0d3..d0c77e04c 100644 --- a/examples/mission_import_export/mission_import_export.py +++ b/examples/mission_import_export/mission_import_export.py @@ -1,172 +1,173 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -© Copyright 2015-2016, 3D Robotics. -mission_import_export.py: - -This example demonstrates how to import and export files in the Waypoint file format -(http://qgroundcontrol.org/mavlink/waypoint_protocol#waypoint_file_format). The commands are imported -into a list, and can be modified before saving and/or uploading. - -Documentation is provided at http://python.dronekit.io/examples/mission_import_export.html -""" - - -from dronekit import connect, Command -import time - - -#Set up option parsing to get connection string -import argparse -parser = argparse.ArgumentParser(description='Demonstrates mission import/export from a file.') -parser.add_argument('--connect', - help="Vehicle connection target string. If not specified, SITL automatically started and used.") -args = parser.parse_args() - -connection_string = args.connect -sitl = None - - -#Start SITL if no connection string specified -if not connection_string: - import dronekit_sitl - sitl = dronekit_sitl.start_default() - connection_string = sitl.connection_string() - - -# Connect to the Vehicle -print 'Connecting to vehicle on: %s' % connection_string -vehicle = connect(connection_string, wait_ready=True) - -# Check that vehicle is armable. -# This ensures home_location is set (needed when saving WP file) - -while not vehicle.is_armable: - print " Waiting for vehicle to initialise..." - time.sleep(1) - - -def readmission(aFileName): - """ - Load a mission from a file into a list. The mission definition is in the Waypoint file - format (http://qgroundcontrol.org/mavlink/waypoint_protocol#waypoint_file_format). - - This function is used by upload_mission(). - """ - print "\nReading mission from file: %s" % aFileName - cmds = vehicle.commands - missionlist=[] - with open(aFileName) as f: - for i, line in enumerate(f): - if i==0: - if not line.startswith('QGC WPL 110'): - raise Exception('File is not supported WP version') - else: - linearray=line.split('\t') - ln_index=int(linearray[0]) - ln_currentwp=int(linearray[1]) - ln_frame=int(linearray[2]) - ln_command=int(linearray[3]) - ln_param1=float(linearray[4]) - ln_param2=float(linearray[5]) - ln_param3=float(linearray[6]) - ln_param4=float(linearray[7]) - ln_param5=float(linearray[8]) - ln_param6=float(linearray[9]) - ln_param7=float(linearray[10]) - ln_autocontinue=int(linearray[11].strip()) - cmd = Command( 0, 0, 0, ln_frame, ln_command, ln_currentwp, ln_autocontinue, ln_param1, ln_param2, ln_param3, ln_param4, ln_param5, ln_param6, ln_param7) - missionlist.append(cmd) - return missionlist - - -def upload_mission(aFileName): - """ - Upload a mission from a file. - """ - #Read mission from file - missionlist = readmission(aFileName) - - print "\nUpload mission from a file: %s" % import_mission_filename - #Clear existing mission from vehicle - print ' Clear mission' - cmds = vehicle.commands - cmds.clear() - #Add new mission to vehicle - for command in missionlist: - cmds.add(command) - print ' Upload mission' - vehicle.commands.upload() - - -def download_mission(): - """ - Downloads the current mission and returns it in a list. - It is used in save_mission() to get the file information to save. - """ - print " Download mission from vehicle" - missionlist=[] - cmds = vehicle.commands - cmds.download() - cmds.wait_ready() - for cmd in cmds: - missionlist.append(cmd) - return missionlist - -def save_mission(aFileName): - """ - Save a mission in the Waypoint file format - (http://qgroundcontrol.org/mavlink/waypoint_protocol#waypoint_file_format). - """ - print "\nSave mission from Vehicle to file: %s" % export_mission_filename - #Download mission from vehicle - missionlist = download_mission() - #Add file-format information - output='QGC WPL 110\n' - #Add home location as 0th waypoint - home = vehicle.home_location - output+="%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" % (0,1,0,16,0,0,0,0,home.lat,home.lon,home.alt,1) - #Add commands - for cmd in missionlist: - commandline="%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" % (cmd.seq,cmd.current,cmd.frame,cmd.command,cmd.param1,cmd.param2,cmd.param3,cmd.param4,cmd.x,cmd.y,cmd.z,cmd.autocontinue) - output+=commandline - with open(aFileName, 'w') as file_: - print " Write mission to file" - file_.write(output) - - -def printfile(aFileName): - """ - Print a mission file to demonstrate "round trip" - """ - print "\nMission file: %s" % aFileName - with open(aFileName) as f: - for line in f: - print ' %s' % line.strip() - - -import_mission_filename = 'mpmission.txt' -export_mission_filename = 'exportedmission.txt' - - -#Upload mission from file -upload_mission(import_mission_filename) - -#Download mission we just uploaded and save to a file -save_mission(export_mission_filename) - -#Close vehicle object before exiting script -print "Close vehicle object" -vehicle.close() - -# Shut down simulator if it was started. -if sitl is not None: - sitl.stop() - - -print "\nShow original and uploaded/downloaded files:" -#Print original file (for demo purposes only) -printfile(import_mission_filename) -#Print exported file (for demo purposes only) -printfile(export_mission_filename) +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +© Copyright 2015-2016, 3D Robotics. +mission_import_export.py: + +This example demonstrates how to import and export files in the Waypoint file format +(http://qgroundcontrol.org/mavlink/waypoint_protocol#waypoint_file_format). The commands are imported +into a list, and can be modified before saving and/or uploading. + +Documentation is provided at http://python.dronekit.io/examples/mission_import_export.html +""" +from __future__ import print_function + + +from dronekit import connect, Command +import time + + +#Set up option parsing to get connection string +import argparse +parser = argparse.ArgumentParser(description='Demonstrates mission import/export from a file.') +parser.add_argument('--connect', + help="Vehicle connection target string. If not specified, SITL automatically started and used.") +args = parser.parse_args() + +connection_string = args.connect +sitl = None + + +#Start SITL if no connection string specified +if not connection_string: + import dronekit_sitl + sitl = dronekit_sitl.start_default() + connection_string = sitl.connection_string() + + +# Connect to the Vehicle +print('Connecting to vehicle on: %s' % connection_string) +vehicle = connect(connection_string, wait_ready=True) + +# Check that vehicle is armable. +# This ensures home_location is set (needed when saving WP file) + +while not vehicle.is_armable: + print(" Waiting for vehicle to initialise...") + time.sleep(1) + + +def readmission(aFileName): + """ + Load a mission from a file into a list. The mission definition is in the Waypoint file + format (http://qgroundcontrol.org/mavlink/waypoint_protocol#waypoint_file_format). + + This function is used by upload_mission(). + """ + print("\nReading mission from file: %s" % aFileName) + cmds = vehicle.commands + missionlist=[] + with open(aFileName) as f: + for i, line in enumerate(f): + if i==0: + if not line.startswith('QGC WPL 110'): + raise Exception('File is not supported WP version') + else: + linearray=line.split('\t') + ln_index=int(linearray[0]) + ln_currentwp=int(linearray[1]) + ln_frame=int(linearray[2]) + ln_command=int(linearray[3]) + ln_param1=float(linearray[4]) + ln_param2=float(linearray[5]) + ln_param3=float(linearray[6]) + ln_param4=float(linearray[7]) + ln_param5=float(linearray[8]) + ln_param6=float(linearray[9]) + ln_param7=float(linearray[10]) + ln_autocontinue=int(linearray[11].strip()) + cmd = Command( 0, 0, 0, ln_frame, ln_command, ln_currentwp, ln_autocontinue, ln_param1, ln_param2, ln_param3, ln_param4, ln_param5, ln_param6, ln_param7) + missionlist.append(cmd) + return missionlist + + +def upload_mission(aFileName): + """ + Upload a mission from a file. + """ + #Read mission from file + missionlist = readmission(aFileName) + + print("\nUpload mission from a file: %s" % import_mission_filename) + #Clear existing mission from vehicle + print(' Clear mission') + cmds = vehicle.commands + cmds.clear() + #Add new mission to vehicle + for command in missionlist: + cmds.add(command) + print(' Upload mission') + vehicle.commands.upload() + + +def download_mission(): + """ + Downloads the current mission and returns it in a list. + It is used in save_mission() to get the file information to save. + """ + print(" Download mission from vehicle") + missionlist=[] + cmds = vehicle.commands + cmds.download() + cmds.wait_ready() + for cmd in cmds: + missionlist.append(cmd) + return missionlist + +def save_mission(aFileName): + """ + Save a mission in the Waypoint file format + (http://qgroundcontrol.org/mavlink/waypoint_protocol#waypoint_file_format). + """ + print("\nSave mission from Vehicle to file: %s" % export_mission_filename) + #Download mission from vehicle + missionlist = download_mission() + #Add file-format information + output='QGC WPL 110\n' + #Add home location as 0th waypoint + home = vehicle.home_location + output+="%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" % (0,1,0,16,0,0,0,0,home.lat,home.lon,home.alt,1) + #Add commands + for cmd in missionlist: + commandline="%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" % (cmd.seq,cmd.current,cmd.frame,cmd.command,cmd.param1,cmd.param2,cmd.param3,cmd.param4,cmd.x,cmd.y,cmd.z,cmd.autocontinue) + output+=commandline + with open(aFileName, 'w') as file_: + print(" Write mission to file") + file_.write(output) + + +def printfile(aFileName): + """ + Print a mission file to demonstrate "round trip" + """ + print("\nMission file: %s" % aFileName) + with open(aFileName) as f: + for line in f: + print(' %s' % line.strip()) + + +import_mission_filename = 'mpmission.txt' +export_mission_filename = 'exportedmission.txt' + + +#Upload mission from file +upload_mission(import_mission_filename) + +#Download mission we just uploaded and save to a file +save_mission(export_mission_filename) + +#Close vehicle object before exiting script +print("Close vehicle object") +vehicle.close() + +# Shut down simulator if it was started. +if sitl is not None: + sitl.stop() + + +print("\nShow original and uploaded/downloaded files:") +#Print original file (for demo purposes only) +printfile(import_mission_filename) +#Print exported file (for demo purposes only) +printfile(export_mission_filename) diff --git a/examples/performance_test/performance_test.py b/examples/performance_test/performance_test.py index 7758a5440..2be53b46c 100644 --- a/examples/performance_test/performance_test.py +++ b/examples/performance_test/performance_test.py @@ -12,6 +12,7 @@ Full documentation is provided at http://python.dronekit.io/examples/performance_test.html """ +from __future__ import print_function from dronekit import connect from pymavlink import mavutil import time @@ -36,7 +37,7 @@ # Connect to the Vehicle -print 'Connecting to vehicle on: %s' % connection_string +print('Connecting to vehicle on: %s' % connection_string) vehicle = connect(connection_string, wait_ready=True) #global vehicle @@ -107,7 +108,7 @@ def send_testpackets(): #Start logging by sending a test packet send_testpackets() -print "Logging for 30 seconds" +print("Logging for 30 seconds") for x in range(1,30): time.sleep(1) diff --git a/examples/vehicle_state/vehicle_state.py b/examples/vehicle_state/vehicle_state.py index c4d7d55c6..3fd3717d0 100644 --- a/examples/vehicle_state/vehicle_state.py +++ b/examples/vehicle_state/vehicle_state.py @@ -10,6 +10,7 @@ Full documentation is provided at http://python.dronekit.io/examples/vehicle_state.html """ +from __future__ import print_function from dronekit import connect, VehicleMode import time @@ -33,55 +34,55 @@ # Connect to the Vehicle. # Set `wait_ready=True` to ensure default attributes are populated before `connect()` returns. -print "\nConnecting to vehicle on: %s" % connection_string +print("\nConnecting to vehicle on: %s" % connection_string) vehicle = connect(connection_string, wait_ready=True) vehicle.wait_ready('autopilot_version') # Get all vehicle attributes (state) -print "\nGet all vehicle attribute values:" -print " Autopilot Firmware version: %s" % vehicle.version -print " Major version number: %s" % vehicle.version.major -print " Minor version number: %s" % vehicle.version.minor -print " Patch version number: %s" % vehicle.version.patch -print " Release type: %s" % vehicle.version.release_type() -print " Release version: %s" % vehicle.version.release_version() -print " Stable release?: %s" % vehicle.version.is_stable() -print " Autopilot capabilities" -print " Supports MISSION_FLOAT message type: %s" % vehicle.capabilities.mission_float -print " Supports PARAM_FLOAT message type: %s" % vehicle.capabilities.param_float -print " Supports MISSION_INT message type: %s" % vehicle.capabilities.mission_int -print " Supports COMMAND_INT message type: %s" % vehicle.capabilities.command_int -print " Supports PARAM_UNION message type: %s" % vehicle.capabilities.param_union -print " Supports ftp for file transfers: %s" % vehicle.capabilities.ftp -print " Supports commanding attitude offboard: %s" % vehicle.capabilities.set_attitude_target -print " Supports commanding position and velocity targets in local NED frame: %s" % vehicle.capabilities.set_attitude_target_local_ned -print " Supports set position + velocity targets in global scaled integers: %s" % vehicle.capabilities.set_altitude_target_global_int -print " Supports terrain protocol / data handling: %s" % vehicle.capabilities.terrain -print " Supports direct actuator control: %s" % vehicle.capabilities.set_actuator_target -print " Supports the flight termination command: %s" % vehicle.capabilities.flight_termination -print " Supports mission_float message type: %s" % vehicle.capabilities.mission_float -print " Supports onboard compass calibration: %s" % vehicle.capabilities.compass_calibration -print " Global Location: %s" % vehicle.location.global_frame -print " Global Location (relative altitude): %s" % vehicle.location.global_relative_frame -print " Local Location: %s" % vehicle.location.local_frame -print " Attitude: %s" % vehicle.attitude -print " Velocity: %s" % vehicle.velocity -print " GPS: %s" % vehicle.gps_0 -print " Gimbal status: %s" % vehicle.gimbal -print " Battery: %s" % vehicle.battery -print " EKF OK?: %s" % vehicle.ekf_ok -print " Last Heartbeat: %s" % vehicle.last_heartbeat -print " Rangefinder: %s" % vehicle.rangefinder -print " Rangefinder distance: %s" % vehicle.rangefinder.distance -print " Rangefinder voltage: %s" % vehicle.rangefinder.voltage -print " Heading: %s" % vehicle.heading -print " Is Armable?: %s" % vehicle.is_armable -print " System status: %s" % vehicle.system_status.state -print " Groundspeed: %s" % vehicle.groundspeed # settable -print " Airspeed: %s" % vehicle.airspeed # settable -print " Mode: %s" % vehicle.mode.name # settable -print " Armed: %s" % vehicle.armed # settable +print("\nGet all vehicle attribute values:") +print(" Autopilot Firmware version: %s" % vehicle.version) +print(" Major version number: %s" % vehicle.version.major) +print(" Minor version number: %s" % vehicle.version.minor) +print(" Patch version number: %s" % vehicle.version.patch) +print(" Release type: %s" % vehicle.version.release_type()) +print(" Release version: %s" % vehicle.version.release_version()) +print(" Stable release?: %s" % vehicle.version.is_stable()) +print(" Autopilot capabilities") +print(" Supports MISSION_FLOAT message type: %s" % vehicle.capabilities.mission_float) +print(" Supports PARAM_FLOAT message type: %s" % vehicle.capabilities.param_float) +print(" Supports MISSION_INT message type: %s" % vehicle.capabilities.mission_int) +print(" Supports COMMAND_INT message type: %s" % vehicle.capabilities.command_int) +print(" Supports PARAM_UNION message type: %s" % vehicle.capabilities.param_union) +print(" Supports ftp for file transfers: %s" % vehicle.capabilities.ftp) +print(" Supports commanding attitude offboard: %s" % vehicle.capabilities.set_attitude_target) +print(" Supports commanding position and velocity targets in local NED frame: %s" % vehicle.capabilities.set_attitude_target_local_ned) +print(" Supports set position + velocity targets in global scaled integers: %s" % vehicle.capabilities.set_altitude_target_global_int) +print(" Supports terrain protocol / data handling: %s" % vehicle.capabilities.terrain) +print(" Supports direct actuator control: %s" % vehicle.capabilities.set_actuator_target) +print(" Supports the flight termination command: %s" % vehicle.capabilities.flight_termination) +print(" Supports mission_float message type: %s" % vehicle.capabilities.mission_float) +print(" Supports onboard compass calibration: %s" % vehicle.capabilities.compass_calibration) +print(" Global Location: %s" % vehicle.location.global_frame) +print(" Global Location (relative altitude): %s" % vehicle.location.global_relative_frame) +print(" Local Location: %s" % vehicle.location.local_frame) +print(" Attitude: %s" % vehicle.attitude) +print(" Velocity: %s" % vehicle.velocity) +print(" GPS: %s" % vehicle.gps_0) +print(" Gimbal status: %s" % vehicle.gimbal) +print(" Battery: %s" % vehicle.battery) +print(" EKF OK?: %s" % vehicle.ekf_ok) +print(" Last Heartbeat: %s" % vehicle.last_heartbeat) +print(" Rangefinder: %s" % vehicle.rangefinder) +print(" Rangefinder distance: %s" % vehicle.rangefinder.distance) +print(" Rangefinder voltage: %s" % vehicle.rangefinder.voltage) +print(" Heading: %s" % vehicle.heading) +print(" Is Armable?: %s" % vehicle.is_armable) +print(" System status: %s" % vehicle.system_status.state) +print(" Groundspeed: %s" % vehicle.groundspeed) # settable +print(" Airspeed: %s" % vehicle.airspeed) # settable +print(" Mode: %s" % vehicle.mode.name) # settable +print(" Armed: %s" % vehicle.armed) # settable @@ -91,38 +92,38 @@ cmds.download() cmds.wait_ready() if not vehicle.home_location: - print " Waiting for home location ..." + print(" Waiting for home location ...") # We have a home location, so print it! -print "\n Home location: %s" % vehicle.home_location +print("\n Home location: %s" % vehicle.home_location) # Set vehicle home_location, mode, and armed attributes (the only settable attributes) -print "\nSet new home location" +print("\nSet new home location") # Home location must be within 50km of EKF home location (or setting will fail silently) # In this case, just set value to current location with an easily recognisable altitude (222) my_location_alt = vehicle.location.global_frame my_location_alt.alt = 222.0 vehicle.home_location = my_location_alt -print " New Home Location (from attribute - altitude should be 222): %s" % vehicle.home_location +print(" New Home Location (from attribute - altitude should be 222): %s" % vehicle.home_location) #Confirm current value on vehicle by re-downloading commands cmds = vehicle.commands cmds.download() cmds.wait_ready() -print " New Home Location (from vehicle - altitude should be 222): %s" % vehicle.home_location +print(" New Home Location (from vehicle - altitude should be 222): %s" % vehicle.home_location) -print "\nSet Vehicle.mode = GUIDED (currently: %s)" % vehicle.mode.name +print("\nSet Vehicle.mode = GUIDED (currently: %s)" % vehicle.mode.name) vehicle.mode = VehicleMode("GUIDED") while not vehicle.mode.name=='GUIDED': #Wait until mode has changed - print " Waiting for mode change ..." + print(" Waiting for mode change ...") time.sleep(1) # Check that vehicle is armable while not vehicle.is_armable: - print " Waiting for vehicle to initialise..." + print(" Waiting for vehicle to initialise...") time.sleep(1) # If required, you can provide additional information about initialisation # using `vehicle.gps_0.fix_type` and `vehicle.mode.name`. @@ -146,87 +147,87 @@ def attitude_callback(self, attr_name, value): global last_attitude_cache # Only publish when value changes if value!=last_attitude_cache: - print " CALLBACK: Attitude changed to", value + print(" CALLBACK: Attitude changed to", value) last_attitude_cache=value -print "\nAdd `attitude` attribute callback/observer on `vehicle`" +print("\nAdd `attitude` attribute callback/observer on `vehicle`") vehicle.add_attribute_listener('attitude', attitude_callback) -print " Wait 2s so callback invoked before observer removed" +print(" Wait 2s so callback invoked before observer removed") time.sleep(2) -print " Remove Vehicle.attitude observer" +print(" Remove Vehicle.attitude observer") # Remove observer added with `add_attribute_listener()` specifying the attribute and callback function vehicle.remove_attribute_listener('attitude', attitude_callback) # Add mode attribute callback using decorator (callbacks added this way cannot be removed). -print "\nAdd `mode` attribute callback/observer using decorator" +print("\nAdd `mode` attribute callback/observer using decorator") @vehicle.on_attribute('mode') def decorated_mode_callback(self, attr_name, value): # `attr_name` is the observed attribute (used if callback is used for multiple attributes) # `attr_name` - the observed attribute (used if callback is used for multiple attributes) # `value` is the updated attribute value. - print " CALLBACK: Mode changed to", value + print(" CALLBACK: Mode changed to", value) -print " Set mode=STABILIZE (currently: %s) and wait for callback" % vehicle.mode.name +print(" Set mode=STABILIZE (currently: %s) and wait for callback" % vehicle.mode.name) vehicle.mode = VehicleMode("STABILIZE") -print " Wait 2s so callback invoked before moving to next example" +print(" Wait 2s so callback invoked before moving to next example") time.sleep(2) -print "\n Attempt to remove observer added with `on_attribute` decorator (should fail)" +print("\n Attempt to remove observer added with `on_attribute` decorator (should fail)") try: vehicle.remove_attribute_listener('mode', decorated_mode_callback) except: - print " Exception: Cannot remove observer added using decorator" + print(" Exception: Cannot remove observer added using decorator") # Demonstrate getting callback on any attribute change def wildcard_callback(self, attr_name, value): - print " CALLBACK: (%s): %s" % (attr_name,value) + print(" CALLBACK: (%s): %s" % (attr_name,value)) -print "\nAdd attribute callback detecting ANY attribute change" +print("\nAdd attribute callback detecting ANY attribute change") vehicle.add_attribute_listener('*', wildcard_callback) -print " Wait 1s so callback invoked before observer removed" +print(" Wait 1s so callback invoked before observer removed") time.sleep(1) -print " Remove Vehicle attribute observer" +print(" Remove Vehicle attribute observer") # Remove observer added with `add_attribute_listener()` vehicle.remove_attribute_listener('*', wildcard_callback) # Get/Set Vehicle Parameters -print "\nRead and write parameters" -print " Read vehicle param 'THR_MIN': %s" % vehicle.parameters['THR_MIN'] +print("\nRead and write parameters") +print(" Read vehicle param 'THR_MIN': %s" % vehicle.parameters['THR_MIN']) -print " Write vehicle param 'THR_MIN' : 10" +print(" Write vehicle param 'THR_MIN' : 10") vehicle.parameters['THR_MIN']=10 -print " Read new value of param 'THR_MIN': %s" % vehicle.parameters['THR_MIN'] +print(" Read new value of param 'THR_MIN': %s" % vehicle.parameters['THR_MIN']) -print "\nPrint all parameters (iterate `vehicle.parameters`):" +print("\nPrint all parameters (iterate `vehicle.parameters`):") for key, value in vehicle.parameters.iteritems(): - print " Key:%s Value:%s" % (key,value) + print(" Key:%s Value:%s" % (key,value)) -print "\nCreate parameter observer using decorator" +print("\nCreate parameter observer using decorator") # Parameter string is case-insensitive # Value is cached (listeners are only updated on change) # Observer added using decorator can't be removed. @vehicle.parameters.on_attribute('THR_MIN') def decorated_thr_min_callback(self, attr_name, value): - print " PARAMETER CALLBACK: %s changed to: %s" % (attr_name, value) + print(" PARAMETER CALLBACK: %s changed to: %s" % (attr_name, value)) -print "Write vehicle param 'THR_MIN' : 20 (and wait for callback)" +print("Write vehicle param 'THR_MIN' : 20 (and wait for callback)") vehicle.parameters['THR_MIN']=20 for x in range(1,5): #Callbacks may not be updated for a few seconds @@ -236,19 +237,19 @@ def decorated_thr_min_callback(self, attr_name, value): #Callback function for "any" parameter -print "\nCreate (removable) observer for any parameter using wildcard string" +print("\nCreate (removable) observer for any parameter using wildcard string") def any_parameter_callback(self, attr_name, value): - print " ANY PARAMETER CALLBACK: %s changed to: %s" % (attr_name, value) + print(" ANY PARAMETER CALLBACK: %s changed to: %s" % (attr_name, value)) #Add observer for the vehicle's any/all parameters parameter (defined using wildcard string ``'*'``) vehicle.parameters.add_attribute_listener('*', any_parameter_callback) -print " Change THR_MID and THR_MIN parameters (and wait for callback)" +print(" Change THR_MID and THR_MIN parameters (and wait for callback)") vehicle.parameters['THR_MID']=400 vehicle.parameters['THR_MIN']=30 ## Reset variables to sensible values. -print "\nReset vehicle attributes/parameters and exit" +print("\nReset vehicle attributes/parameters and exit") vehicle.mode = VehicleMode("STABILIZE") #vehicle.armed = False vehicle.parameters['THR_MIN']=130 @@ -256,7 +257,7 @@ def any_parameter_callback(self, attr_name, value): #Close vehicle object before exiting script -print "\nClose vehicle object" +print("\nClose vehicle object") vehicle.close() # Shut down simulator if it was started. diff --git a/windows/returnVersion.py b/windows/returnVersion.py index a15976f88..ec9ebbadc 100644 --- a/windows/returnVersion.py +++ b/windows/returnVersion.py @@ -1,12 +1,13 @@ -# This script reads the setup.py and returns the current version number -# Used as part of building the WIndows setup file (DronekitWinBuild.bat) -# It assumes there is a line like this: -# version = "12344" - -# glob supports Unix style pathname extensions -with open("../setup.py") as f: - searchlines = f.readlines() - for i, line in enumerate(searchlines): - if "version = " in line: - print line[11:len(line)-2] +from __future__ import print_function +# This script reads the setup.py and returns the current version number +# Used as part of building the WIndows setup file (DronekitWinBuild.bat) +# It assumes there is a line like this: +# version = "12344" + +# glob supports Unix style pathname extensions +with open("../setup.py") as f: + searchlines = f.readlines() + for i, line in enumerate(searchlines): + if "version = " in line: + print(line[11:len(line)-2]) break \ No newline at end of file From bd3048a63c8278ecea826a1b34ee0267c4a55ca9 Mon Sep 17 00:00:00 2001 From: Lars Kellogg-Stedman Date: Tue, 31 Oct 2017 22:47:25 -0400 Subject: [PATCH 401/475] send_capabilities_request was misspelled this corrects the spelling of "capabilities" and adds an alias to the old name to avoid breaking existing code. --- dronekit/__init__.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 51c659ec4..b4dae41b8 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1110,7 +1110,7 @@ def listener(vehicle, name, m): # ArduPilot <3.4 fails to send capabilities correctly # straight after boot, and even older versions send # this back as always-0. - vehicle.remove_message_listener('HEARTBEAT', self.send_capabilties_request) + vehicle.remove_message_listener('HEARTBEAT', self.send_capabilities_request) self.notify_attribute_listeners('autopilot_version', self._raw_version) # gimbal @@ -2160,7 +2160,7 @@ def initialize(self, rate=4, heartbeat_timeout=30): self._master.mav.request_data_stream_send(0, 0, mavutil.mavlink.MAV_DATA_STREAM_ALL, rate, 1) - self.add_message_listener('HEARTBEAT', self.send_capabilties_request) + self.add_message_listener('HEARTBEAT', self.send_capabilities_request) # Ensure initial parameter download has started. while True: @@ -2172,6 +2172,14 @@ def initialize(self, rate=4, heartbeat_timeout=30): break def send_capabilties_request(self, vehicle, name, m): + '''An alias for send_capabilities_request. + + The word "capabilities" was misspelled in previous versions of this code. This is simply + an alias to send_capabilities_request using the legacy name. + ''' + return self.send_capabilities_request(vehicle, name, m) + + def send_capabilities_request(self, vehicle, name, m): '''Request an AUTOPILOT_VERSION packet''' capability_msg = vehicle.message_factory.command_long_encode(0, 0, mavutil.mavlink.MAV_CMD_REQUEST_AUTOPILOT_CAPABILITIES, 0, 1, 0, 0, 0, 0, 0, 0) vehicle.send_mavlink(capability_msg) From f9991fde389d55ce1cb030a80b5dbbf02e13657d Mon Sep 17 00:00:00 2001 From: Lars Kellogg-Stedman Date: Fri, 3 Nov 2017 14:53:51 -0400 Subject: [PATCH 402/475] raise ValueError if we are passed a bad value Given a bad value, we were sometimes raising a bare Exception, sometimes raising a ValueError, and sometimes raising an APIError. This commit attempts to make things consistent by raising ValueError when that's what we mean. There is also a drive-by correction to the spelling of "Expecting". --- dronekit/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index b4dae41b8..d369fc788 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1957,7 +1957,7 @@ def home_location(self, pos): """ if not isinstance(pos, LocationGlobal): - raise Exception('Excepting home_location to be set to a LocationGlobal.') + raise ValueError('Expecting home_location to be set to a LocationGlobal.') # Set cached home location. self._home_location = copy.copy(pos) @@ -2058,7 +2058,7 @@ def simple_goto(self, location, airspeed=None, groundspeed=None): self.commands.wait_ready() alt = location.alt - self.home_location.alt else: - raise APIException('Expecting location to be LocationGlobal or LocationGlobalRelative.') + raise ValueError('Expecting location to be LocationGlobal or LocationGlobalRelative.') self._master.mav.mission_item_send(0, 0, 0, frame, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 2, 0, 0, @@ -2229,7 +2229,7 @@ def wait_ready(self, *types, **kwargs): types = self._default_ready_attrs if not all(isinstance(item, basestring) for item in types): - raise APIException('wait_ready expects one or more string arguments.') + raise ValueError('wait_ready expects one or more string arguments.') # Wait for these attributes to have been set. await = set(types) @@ -2387,7 +2387,7 @@ def target_location(self,roi): self.commands.wait_ready() alt = roi.alt - self.home_location.alt else: - raise APIException('Expecting location to be LocationGlobal or LocationGlobalRelative.') + raise ValueError('Expecting location to be LocationGlobal or LocationGlobalRelative.') #set the ROI msg = self._vehicle.message_factory.command_long_encode( From 200fbaf50208e0d7a99dbd026d2324ff6b26a03b Mon Sep 17 00:00:00 2001 From: Lars Kellogg-Stedman Date: Fri, 3 Nov 2017 15:03:29 -0400 Subject: [PATCH 403/475] raise KeyError instead of a bare Exception This removes the last instance of the code raising a bare Exception. Since this is a failure in a __setitem__ method it seems reasonable to raise a KeyError. --- dronekit/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index d369fc788..277bfec5e 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -730,7 +730,7 @@ def __getitem__(self, key): def __setitem__(self, key, value): if not (int(key) > 0 and int(key) <= self._count): - raise Exception('Invalid channel index %s' % key) + raise KeyError('Invalid channel index %s' % key) if not value: try: dict.__delitem__(self, str(key)) From b5eaa1874780f0f9d7fa1c1dfb1e47becf557639 Mon Sep 17 00:00:00 2001 From: Lars Kellogg-Stedman Date: Fri, 3 Nov 2017 14:52:58 -0400 Subject: [PATCH 404/475] add convenience methods for common synchronous operations this adds wait_for_armable, arm, disarm, wait_for_mode, and wait_for_alt methods that wrap common operations with wait-for-complete behavior with an optional timeout. --- dronekit/__init__.py | 120 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 117 insertions(+), 3 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 277bfec5e..10e04a213 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -61,8 +61,9 @@ class APIException(Exception): :param String message: Message string describing the exception """ - def __init__(self, message): - super(APIException, self).__init__(message) + +class TimeoutError(APIException): + '''Raised by operations that have timeouts.''' class Attitude(object): @@ -1989,6 +1990,119 @@ def parameters(self): """ return self._parameters + def wait_for(self, condition, timeout=None, interval=0.1, errmsg=None): + '''Wait for a condition to be True. + + Wait for condition, a callable, to return True. If timeout is + nonzero, raise a TimeoutError(errmsg) if the condition is not + True after timeout seconds. Check the condition everal + interval seconds. + ''' + + t0 = time.time() + while not condition(): + t1 = time.time() + if timeout and (t1 - t0) >= timeout: + raise TimeoutError(errmsg) + + time.sleep(interval) + + def wait_for_armable(self, timeout=None): + '''Wait for the vehicle to become armable. + + If timeout is nonzero, raise a TimeoutError if the vehicle + is not armable after timeout seconds. + ''' + + def check_armable(): + return self.is_armable + + self.wait_for(check_armable, timeout=timeout) + + def arm(self, wait=True, timeout=None): + '''Arm the vehicle. + + If wait is True, wait for arm operation to complete before + returning. If timeout is nonzero, raise a TimeouTerror if the + vehicle has not armed after timeout seconds. + ''' + + self.armed = True + + if wait: + self.wait_for(lambda: self.armed, timeout=timeout, + errmsg='failed to arm vehicle') + + def disarm(self, wait=True, timeout=None): + '''Disarm the vehicle. + + If wait is True, wait for disarm operation to complete before + returning. If timeout is nonzero, raise a TimeouTerror if the + vehicle has not disarmed after timeout seconds. + ''' + self.armed = False + + if wait: + self.wait_for(lambda: not self.armed, timeout=timeout, + errmsg='failed to disarm vehicle') + + def wait_for_mode(self, mode, timeout=None): + '''Set the flight mode. + + If wait is True, wait for the mode to change before returning. + If timeout is nonzero, raise a TimeoutError if the flight mode + hasn't changed after timeout seconds. + ''' + + if not isinstance(mode, VehicleMode): + mode = VehicleMode(mode) + + self.mode = mode + + self.wait_for(lambda: self.mode.name == mode.name, + timeout=timeout, + errmsg='failed to set flight mode') + + def wait_for_alt(self, alt, epsilon=0.1, rel=True, timeout=None): + '''Wait for the vehicle to reach the specified altitude. + + Wait for the vehicle to get within epsilon meters of the + given altitude. If rel is True (the default), use the + global_relative_frame. If rel is False, use the global_frame. + If timeout is nonzero, raise a TimeoutError if the specified + altitude has not been reached after timeout seconds. + ''' + + def get_alt(): + if rel: + alt = self.location.global_relative_frame.alt + else: + alt = self.location.global_frame.alt + + return alt + + def check_alt(): + cur = get_alt() + delta = abs(alt-cur) + + return ( + (delta < epsilon) or + (start < alt and cur > alt) or + (start > alt and cur < alt) + ) + + start = get_alt() + + self.wait_for( + check_alt, + timeout=timeout, + errmsg='failed to reach specified altitude') + + def wait_simple_takeoff(self, alt=None, epsilon=0.1, timeout=None): + self.simple_takeoff(alt) + + if alt is not None: + self.wait_for_alt(alt, epsilon=epsilon, timeout=timeout) def simple_takeoff(self, alt=None): """ @@ -2238,7 +2352,7 @@ def wait_ready(self, *types, **kwargs): time.sleep(0.1) if monotonic.monotonic() - start > timeout: if raise_exception: - raise APIException('wait_ready experienced a timeout after %s seconds.' % + raise TimeoutError('wait_ready experienced a timeout after %s seconds.' % timeout) else: return False From c337ba52e54e212a76ee17b01336f78b9531018f Mon Sep 17 00:00:00 2001 From: SJKim Date: Thu, 27 Apr 2017 20:57:40 +0900 Subject: [PATCH 405/475] Examples: add example for set_attitude_target Add an example code for movement in GUIDED_NOGPS mode Add the caution to the preface comment and delete the copyright Unify the format of print function Unify the format of comments Change the format of printing current altitude to improve the message visibility in Python 2 Add console messages to give users more information about current status --- .../set_attitude_target.py | 175 ++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 examples/set_attitude_target/set_attitude_target.py diff --git a/examples/set_attitude_target/set_attitude_target.py b/examples/set_attitude_target/set_attitude_target.py new file mode 100644 index 000000000..c6ebd0ed3 --- /dev/null +++ b/examples/set_attitude_target/set_attitude_target.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" + +set_attitude_target.py: (Copter Only) + +This example shows how to move/direct Copter and send commands + in GUIDED_NOGPS mode using DroneKit Python. + +Caution: A lot of unexpected behaviors may occur in GUIDED_NOGPS mode. + Always watch the drone movement, and make sure that you are in dangerless environment. + Land the drone as soon as possible when it shows any unexpected behavior. + +Tested in Python 2.7.10 + +""" + +from dronekit import connect, VehicleMode, LocationGlobal, LocationGlobalRelative +from pymavlink import mavutil # Needed for command message definitions +import time +import math + +# Set up option parsing to get connection string +import argparse +parser = argparse.ArgumentParser(description='Control Copter and send commands in GUIDED mode ') +parser.add_argument('--connect', + help="Vehicle connection target string. If not specified, SITL automatically started and used.") +args = parser.parse_args() + +connection_string = args.connect +sitl = None + +# Start SITL if no connection string specified +if not connection_string: + import dronekit_sitl + sitl = dronekit_sitl.start_default() + connection_string = sitl.connection_string() + + +# Connect to the Vehicle +print('Connecting to vehicle on: %s' % connection_string) +vehicle = connect(connection_string, wait_ready=True) + +def arm_and_takeoff_nogps(aTargetAltitude): + """ + Arms vehicle and fly to aTargetAltitude without GPS data. + """ + + ##### CONSTANTS ##### + DEFAULT_TAKEOFF_THRUST = 0.7 + SMOOTH_TAKEOFF_THRUST = 0.6 + + print("Basic pre-arm checks") + # Don't let the user try to arm until autopilot is ready + # If you need to disable the arming check, + # just comment it with your own responsibility. + while not vehicle.is_armable: + print(" Waiting for vehicle to initialise...") + time.sleep(1) + + + print("Arming motors") + # Copter should arm in GUIDED_NOGPS mode + vehicle.mode = VehicleMode("GUIDED_NOGPS") + vehicle.armed = True + + while not vehicle.armed: + print(" Waiting for arming...") + vehicle.armed = True + time.sleep(1) + + print("Taking off!") + + thrust = DEFAULT_TAKEOFF_THRUST + while True: + current_altitude = vehicle.location.global_relative_frame.alt + print(" Altitude: %f Desired: %f" % + (current_altitude, aTargetAltitude)) + if current_altitude >= aTargetAltitude*0.95: # Trigger just below target alt. + print("Reached target altitude") + break + elif current_altitude >= aTargetAltitude*0.6: + thrust = SMOOTH_TAKEOFF_THRUST + set_attitude(thrust = thrust) + time.sleep(0.2) + + +def set_attitude(roll_angle = 0.0, pitch_angle = 0.0, yaw_rate = 0.0, thrust = 0.5, duration = 0): + """ + Note that from AC3.3 the message should be re-sent every second (after about 3 seconds + with no message the velocity will drop back to zero). In AC3.2.1 and earlier the specified + velocity persists until it is canceled. The code below should work on either version + (sending the message multiple times does not cause problems). + """ + + """ + The roll and pitch rate cannot be controllbed with rate in radian in AC3.4.4 or earlier, + so you must use quaternion to control the pitch and roll for those vehicles. + """ + + # Thrust > 0.5: Ascend + # Thrust == 0.5: Hold the altitude + # Thrust < 0.5: Descend + msg = vehicle.message_factory.set_attitude_target_encode( + 0, # time_boot_ms + 1, # Target system + 1, # Target component + 0b00000000, # Type mask: bit 1 is LSB + to_quaternion(roll_angle, pitch_angle), # Quaternion + 0, # Body roll rate in radian + 0, # Body pitch rate in radian + math.radians(yaw_rate), # Body yaw rate in radian + thrust # Thrust + ) + vehicle.send_mavlink(msg) + + start = time.time() + while time.time() - start < duration: + vehicle.send_mavlink(msg) + time.sleep(0.1) + +def to_quaternion(roll = 0.0, pitch = 0.0, yaw = 0.0): + """ + Convert degrees to quaternions + """ + t0 = math.cos(math.radians(yaw * 0.5)) + t1 = math.sin(math.radians(yaw * 0.5)) + t2 = math.cos(math.radians(roll * 0.5)) + t3 = math.sin(math.radians(roll * 0.5)) + t4 = math.cos(math.radians(pitch * 0.5)) + t5 = math.sin(math.radians(pitch * 0.5)) + + w = t0 * t2 * t4 + t1 * t3 * t5 + x = t0 * t3 * t4 - t1 * t2 * t5 + y = t0 * t2 * t5 + t1 * t3 * t4 + z = t1 * t2 * t4 - t0 * t3 * t5 + + return [w, x, y, z] + +# Take off 2.5m in GUIDED_NOGPS mode. +arm_and_takeoff_nogps(2.5) + +# Hold the position for 3 seconds. +print("Hold position for 3 seconds") +set_attitude(duration = 3) + +# Uncomment the lines below for testing roll angle and yaw rate. +# Make sure that there is enough space for testing this. + +# set_attitude(roll_angle = 1, thrust = 0.5, duration = 3) +# set_attitude(yaw_rate = 30, thrust = 0.5, duration = 3) + +# Move the drone forward and backward. +# Note that it will be in front of original position due to inertia. +print("Move forward") +set_attitude(pitch_angle = -5, thrust = 0.5, duration = 3.21) + +print("Move backward") +set_attitude(pitch_angle = 5, thrust = 0.5, duration = 3) + + +print("Setting LAND mode...") +vehicle.mode = VehicleMode("LAND") +time.sleep(1) + +# Close vehicle object before exiting script +print("Close vehicle object") +vehicle.close() + +# Shut down simulator if it was started. +if sitl is not None: + sitl.stop() + +print("Completed") From de31ac6a80c8edb82efbfde7b99e4a3de72fe2b0 Mon Sep 17 00:00:00 2001 From: Lars Kellogg-Stedman Date: Tue, 9 Jan 2018 09:21:34 -0500 Subject: [PATCH 406/475] update connecting_vehicle with a serial example New dronekit users will often encounter timeout errors when attempting to open a serial connection (as in #704 and https://stackoverflow.com/q/48168953/147356). This updates the documentation to include an example for a serial connection and a note about setting the baud rate. --- docs/guide/connecting_vehicle.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/guide/connecting_vehicle.rst b/docs/guide/connecting_vehicle.rst index f4430f501..135e29d38 100644 --- a/docs/guide/connecting_vehicle.rst +++ b/docs/guide/connecting_vehicle.rst @@ -27,6 +27,20 @@ The second parameter (``wait_ready``) is used to determine whether ``connect()`` on connection or if it waits until *some* vehicle parameters and attributes are populated. In most cases you should use ``wait_ready=True`` to wait on the default set of parameters. +Connecting over a serial device will look something like this: + +.. code-block:: python + + from dronekit import connect + + # Connect to the Vehicle (in this case a UDP endpoint) + vehicle = connect('/dev/ttyAMA0', wait_ready=True, baud=57600) + +.. tip:: + + If the baud rate is not set correctly, ``connect`` may fail with a + timeout error. It is best to set the baud rate explicitly. + :py:func:`connect() ` also has arguments for setting the baud rate, the length of the connection timeout, and/or to use a :ref:`custom vehicle class `. From ee6de416a561773388e524ac143ad19326e32dc7 Mon Sep 17 00:00:00 2001 From: pietrodn Date: Mon, 22 Jan 2018 18:27:02 +0100 Subject: [PATCH 407/475] Fixes for intermittent timing failures of tests --- dronekit/test/sitl/test_mavlink.py | 5 +++-- dronekit/test/sitl/test_parameters.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/dronekit/test/sitl/test_mavlink.py b/dronekit/test/sitl/test_mavlink.py index 972c8ac8b..ac9330253 100644 --- a/dronekit/test/sitl/test_mavlink.py +++ b/dronekit/test/sitl/test_mavlink.py @@ -8,12 +8,12 @@ @with_sitl def test_mavlink(connpath): - vehicle = connect(connpath) + vehicle = connect(connpath, wait_ready=True) out = MAVConnection('udpin:localhost:15668') vehicle._handler.pipe(out) out.start() - vehicle2 = connect('udpout:localhost:15668') + vehicle2 = connect('udpout:localhost:15668', wait_ready=True) result = {'success': False} @@ -24,5 +24,6 @@ def callback(*args): i = 20 while not result['success'] and i > 0: time.sleep(1) + i -= 1 assert result['success'] diff --git a/dronekit/test/sitl/test_parameters.py b/dronekit/test/sitl/test_parameters.py index ecd7b75d9..7a5529d8f 100644 --- a/dronekit/test/sitl/test_parameters.py +++ b/dronekit/test/sitl/test_parameters.py @@ -50,7 +50,7 @@ def test_setting(connpath): @vehicle.parameters.on_attribute('THR_MIN') def listener(self, name, value): - result['success'] = name == 'THR_MIN' and value == 3.000 + result['success'] = (name == 'THR_MIN' and value == 3.000) vehicle.parameters['THR_MIN'] = 3.000 From 4528e75444b86b725d5ac17a10a9c432bcfd43ad Mon Sep 17 00:00:00 2001 From: pietrodn Date: Mon, 22 Jan 2018 18:35:50 +0100 Subject: [PATCH 408/475] Fixes to make the test suite run under Python 3 also --- dronekit/__init__.py | 18 +++++++++++------- dronekit/test/sitl/test_channels.py | 4 ++-- dronekit/test/sitl/test_parameters.py | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 10e04a213..b8450196d 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -342,7 +342,7 @@ def release_type(self): if self.release is None: return None types = [ "dev", "alpha", "beta", "rc" ] - return types[self.release/64] + return types[self.release >> 6] def __str__(self): prefix="" @@ -751,7 +751,7 @@ def __len__(self): def _send(self): if self._active: overrides = [0] * 8 - for k, v in self.iteritems(): + for k, v in self.items(): overrides[int(k) - 1] = v self._vehicle._master.mav.rc_channels_override_send(0, 0, *overrides) @@ -846,7 +846,7 @@ def overrides(self): def overrides(self, newch): self._overrides._active = False self._overrides.clear() - for k, v in newch.iteritems(): + for k, v in newch.items(): if v: self._overrides[str(k)] = v else: @@ -1290,7 +1290,7 @@ def listener(_): c = 0 for i, v in enumerate(self._params_set): if v == None: - self._master.mav.param_request_read_send(0, 0, '', i) + self._master.mav.param_request_read_send(0, 0, b'', i) c += 1 if c > 50: break @@ -1316,8 +1316,12 @@ def listener(self, name, msg): self._params_last = monotonic.monotonic() self._params_duration = start_duration self._params_set[msg.param_index] = msg - self._params_map[msg.param_id] = msg.param_value - self._parameters.notify_attribute_listeners(msg.param_id, msg.param_value, + + # Normalize parameter name (remove trailing null bytes and convert to string) + param_name = msg.param_id.rstrip(b'\x00').decode('utf8') + + self._params_map[param_name] = msg.param_value + self._parameters.notify_attribute_listeners(param_name, msg.param_value, cache=True) except: import traceback @@ -2996,7 +3000,7 @@ def connect(ip, @vehicle.on_message('STATUSTEXT') def listener(self, name, m): - status_printer(re.sub(r'(^|\n)', '>>> ', m.text.decode('utf-8').rstrip())) + status_printer(re.sub(r'(^|\n)', '>>> ', m.text.rstrip(b'\x00').decode('utf-8').rstrip())) if _initialize: vehicle.initialize(rate=rate, heartbeat_timeout=heartbeat_timeout) diff --git a/dronekit/test/sitl/test_channels.py b/dronekit/test/sitl/test_channels.py index 44c484353..f3f02b1fa 100644 --- a/dronekit/test/sitl/test_channels.py +++ b/dronekit/test/sitl/test_channels.py @@ -10,7 +10,7 @@ def assert_readback(vehicle, values): while i > 0: time.sleep(.1) i -= .1 - for k, v in values.iteritems(): + for k, v in values.items(): if vehicle.channels[k] != v: continue break @@ -135,7 +135,7 @@ def test_timeout(connpath): # Set Ch2 to 33, clear channel 6 vehicle.channels.overrides = {'2': 33, '6': None} assert_readback(vehicle, {'2': 33, '6': 1500}) - assert_equals(vehicle.channels.overrides.keys(), ['2']) + assert_equals(list(vehicle.channels.overrides.keys()), ['2']) # Callbacks result = {'success': False} diff --git a/dronekit/test/sitl/test_parameters.py b/dronekit/test/sitl/test_parameters.py index 7a5529d8f..cb7d2f4bb 100644 --- a/dronekit/test/sitl/test_parameters.py +++ b/dronekit/test/sitl/test_parameters.py @@ -32,7 +32,7 @@ def test_iterating(connpath): vehicle = connect(connpath, wait_ready=True) # Iterate over parameters. - for k, v in vehicle.parameters.iteritems(): + for k, v in vehicle.parameters.items(): break for key in vehicle.parameters: break From 328977a89c6047152e10f56d49b3a94198e9fbec Mon Sep 17 00:00:00 2001 From: Pietro De Nicolao Date: Tue, 23 Jan 2018 07:50:45 +0100 Subject: [PATCH 409/475] =?UTF-8?q?Take=20out=20the=20.rstrip(b=E2=80=99\x?= =?UTF-8?q?00=E2=80=99)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dronekit/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index b8450196d..5c189fe54 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1317,8 +1317,8 @@ def listener(self, name, msg): self._params_duration = start_duration self._params_set[msg.param_index] = msg - # Normalize parameter name (remove trailing null bytes and convert to string) - param_name = msg.param_id.rstrip(b'\x00').decode('utf8') + # Normalize parameter name (convert to string) + param_name = msg.param_id.decode('utf8') self._params_map[param_name] = msg.param_value self._parameters.notify_attribute_listeners(param_name, msg.param_value, @@ -3000,7 +3000,7 @@ def connect(ip, @vehicle.on_message('STATUSTEXT') def listener(self, name, m): - status_printer(re.sub(r'(^|\n)', '>>> ', m.text.rstrip(b'\x00').decode('utf-8').rstrip())) + status_printer(re.sub(r'(^|\n)', '>>> ', m.text.decode('utf-8').rstrip())) if _initialize: vehicle.initialize(rate=rate, heartbeat_timeout=heartbeat_timeout) From 20ad0cd1d8a54b5fc25fbded8f3b0de12ed76628 Mon Sep 17 00:00:00 2001 From: pietrodn Date: Tue, 23 Jan 2018 19:37:43 +0100 Subject: [PATCH 410/475] String encoding to bytes should be done in pymavlink, not here --- dronekit/__init__.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 5c189fe54..3c1c854a8 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1290,7 +1290,7 @@ def listener(_): c = 0 for i, v in enumerate(self._params_set): if v == None: - self._master.mav.param_request_read_send(0, 0, b'', i) + self._master.mav.param_request_read_send(0, 0, '', i) c += 1 if c > 50: break @@ -1317,11 +1317,8 @@ def listener(self, name, msg): self._params_duration = start_duration self._params_set[msg.param_index] = msg - # Normalize parameter name (convert to string) - param_name = msg.param_id.decode('utf8') - - self._params_map[param_name] = msg.param_value - self._parameters.notify_attribute_listeners(param_name, msg.param_value, + self._params_map[msg.param_id] = msg.param_value + self._parameters.notify_attribute_listeners(msg.param_id, msg.param_value, cache=True) except: import traceback @@ -3000,7 +2997,7 @@ def connect(ip, @vehicle.on_message('STATUSTEXT') def listener(self, name, m): - status_printer(re.sub(r'(^|\n)', '>>> ', m.text.decode('utf-8').rstrip())) + status_printer(re.sub(r'(^|\n)', '>>> ', m.text.rstrip())) if _initialize: vehicle.initialize(rate=rate, heartbeat_timeout=heartbeat_timeout) From 1861b047c450a6acd0f38e36c17d6c217121dccf Mon Sep 17 00:00:00 2001 From: Pietro De Nicolao Date: Sun, 25 Mar 2018 20:57:44 +0200 Subject: [PATCH 411/475] circle.yml: use latest available Python versions https://circleci.com/docs/1.0/build-image-trusty/#python --- circle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index 2e9e6a804..89573040a 100644 --- a/circle.yml +++ b/circle.yml @@ -1,6 +1,6 @@ machine: post: - - pyenv global 2.7.13 3.6.0 + - pyenv global 2.7.12 3.6.2 environment: SITL_SPEEDUP: 10 SITL_RATE: 200 From b238edb36db9c5d248370ddde0092b7ed82d9df5 Mon Sep 17 00:00:00 2001 From: Pietro De Nicolao Date: Mon, 26 Mar 2018 07:24:41 +0200 Subject: [PATCH 412/475] circle.yml: these versions surely work https://github.com/dronekit/dronekit-python/commit/fb004baddbedc510e17726474e8c40af88ccb208 --- circle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index 89573040a..5ee47fc59 100644 --- a/circle.yml +++ b/circle.yml @@ -1,6 +1,6 @@ machine: post: - - pyenv global 2.7.12 3.6.2 + - pyenv global 2.7.10 3.5.0 environment: SITL_SPEEDUP: 10 SITL_RATE: 200 From 87abf28c4e5a08dabee35c36565e6cc6162b28d6 Mon Sep 17 00:00:00 2001 From: Pietro De Nicolao Date: Mon, 26 Mar 2018 19:25:46 +0200 Subject: [PATCH 413/475] circle.yml: fix the build - Install future beforehand as workaround to pymavlink bug: https://github.com/ArduPilot/pymavlink/issues/25 - Install dependencies before dronekit, not after --- circle.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index 5ee47fc59..f4208dfce 100644 --- a/circle.yml +++ b/circle.yml @@ -7,8 +7,9 @@ machine: dependencies: override: - - 'pip install . -UI' + - 'pip install -UI future' - 'pip install -r requirements.txt -UI' + - 'pip install . -UI' test: override: From 689aa2240b86d8c5903768c47553869632ed2415 Mon Sep 17 00:00:00 2001 From: pietrodn Date: Sat, 31 Mar 2018 11:39:56 +0200 Subject: [PATCH 414/475] Implement autopilot reboot + test --- dronekit/__init__.py | 15 +++++++++++++++ dronekit/test/sitl/test_reboot.py | 27 +++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 dronekit/test/sitl/test_reboot.py diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 3c1c854a8..85d101514 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -2360,6 +2360,21 @@ def wait_ready(self, *types, **kwargs): return True + def reboot(self): + """Requests an autopilot reboot by sending a ``MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN`` command.""" + + reboot_msg = self.message_factory.command_long_encode( + 0, 0, # target_system, target_component + mavutil.mavlink.MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN, # command + 0, # confirmation + 1, # param 1, autopilot (reboot) + 0, # param 2, onboard computer (do nothing) + 0, # param 3, camera (do nothing) + 0, # param 4, mount (do nothing) + 0, 0, 0) # param 5 ~ 7 not used + + self.send_mavlink(reboot_msg) + class Gimbal(object): """ diff --git a/dronekit/test/sitl/test_reboot.py b/dronekit/test/sitl/test_reboot.py new file mode 100644 index 000000000..3a7252fdc --- /dev/null +++ b/dronekit/test/sitl/test_reboot.py @@ -0,0 +1,27 @@ +from nose.tools import assert_equal + +from dronekit import connect +from dronekit.test import with_sitl +import time + + +@with_sitl +def test_reboot(connpath): + """Tries to reboot the vehicle, and checks that the autopilot ACKs the command.""" + + vehicle = connect(connpath, wait_ready=True) + + reboot_acks = [] + + def on_ack(self, name, message): + if message.command == 246: # reboot/shutdown + reboot_acks.append(message) + + vehicle.add_message_listener('COMMAND_ACK', on_ack) + vehicle.reboot() + time.sleep(0.5) + vehicle.remove_message_listener('COMMAND_ACK', on_ack) + + assert_equal(1, len(reboot_acks)) # one and only one ACK + assert_equal(246, reboot_acks[0].command) # for the correct command + assert_equal(0, reboot_acks[0].result) # the result must be successful From 9f6572a9ea20cdeaeba93c4029b5409966d25535 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 31 Mar 2018 23:50:14 +1100 Subject: [PATCH 415/475] examples: add a reboot example --- examples/reboot/reboot.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100755 examples/reboot/reboot.py diff --git a/examples/reboot/reboot.py b/examples/reboot/reboot.py new file mode 100755 index 000000000..698d10142 --- /dev/null +++ b/examples/reboot/reboot.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from __future__ import print_function + +from dronekit import connect +import time + +# Set up option parsing to get connection string +import argparse +parser = argparse.ArgumentParser(description='Reboots vehicle') +parser.add_argument('--connect', + help="Vehicle connection target string. If not specified, SITL automatically started and used.") +args = parser.parse_args() + +connection_string = args.connect +sitl = None + + +# Start SITL if no connection string specified +if not connection_string: + import dronekit_sitl + sitl = dronekit_sitl.start_default() + connection_string = sitl.connection_string() + + +# Connect to the Vehicle +print('Connecting to vehicle on: %s' % connection_string) +vehicle = connect(connection_string, wait_ready=True) + +vehicle.reboot() +time.sleep(1) + +# Shut down simulator if it was started. +if sitl: + sitl.stop() From ac6d4aeaad50ca56a5d54af0268c316de8ef76ba Mon Sep 17 00:00:00 2001 From: Pietro De Nicolao Date: Wed, 11 Apr 2018 21:14:29 +0200 Subject: [PATCH 416/475] Upgrade CircleCI configuration to version 2.0 (#810) * Upgrade CircleCI config to version 2.0 - Parallel Python 2, Python 3 builds - Well-defined environments using Docker - CircleCI 1.0 will be deprecated soon * config.yml: disable Python 3 testing Comment out Python 3 testing until support is ready. Otherwise, the "deploy" step will fail. --- .circleci/config.yml | 87 ++++++++++++++++++++++++++++++++++++++++++++ circle.yml | 34 ----------------- 2 files changed, 87 insertions(+), 34 deletions(-) create mode 100644 .circleci/config.yml delete mode 100644 circle.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 000000000..f386bc9e0 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,87 @@ +# CircleCI 2.0 configuration file for dronekit-python + +# Steps common to both Python 2 and Python 3 +common: &commonsteps + steps: + - checkout + + - run: + name: Install global tools + command: | + pip install -U virtualenv + + - run: + name: Install dronekit with dependencies + command: | + virtualenv venv + source venv/bin/activate + pip install -UI future + pip install -r requirements.txt -UI + pip install . -UI + + - run: + name: Run dronekit tests + environment: + SITL_SPEEDUP: 10 + SITL_RATE: 200 + command: | + source venv/bin/activate + nosetests -svx dronekit.test.unit + nosetests -svx dronekit.test.sitl + + - run: + name: Build documentation + command: | + source venv/bin/activate + cd docs; make clean; make html + + - store_artifacts: + path: test-reports + destination: test-reports + +# Jobs definition +version: 2 +jobs: + python2: + docker: + - image: circleci/python:2.7-stretch + working_directory: ~/dronekit-python2 + <<: *commonsteps + +# python3: +# docker: +# - image: circleci/python:3.6-stretch +# working_directory: ~/dronekit-python3 +# <<: *commonsteps + + deploy: + name: Deploy to dronekit.io + working_directory: ~/deploy + machine: true + steps: + - checkout + - run: + name: update docs + command: ./scripts/update-docs.sh + +# Send a notification on Gitter +notify: + webhooks: + - url: https://webhooks.gitter.im/e/27b0e1a9fede99dbbe6c + +# Workflow definition +# Run Python 2 and Python 3 testing in parallel +# and deploy if the Python 2 build succeeds +workflows: + version: 2 + build_test_deploy: + jobs: + - python2 +# - python3 + - deploy: + requires: + - python2 + filters: + branches: + only: + - master diff --git a/circle.yml b/circle.yml deleted file mode 100644 index f4208dfce..000000000 --- a/circle.yml +++ /dev/null @@ -1,34 +0,0 @@ -machine: - post: - - pyenv global 2.7.10 3.5.0 - environment: - SITL_SPEEDUP: 10 - SITL_RATE: 200 - -dependencies: - override: - - 'pip install -UI future' - - 'pip install -r requirements.txt -UI' - - 'pip install . -UI' - -test: - override: - # docs - - 'cd docs; make clean; make html' - - # code - - 'nosetests -svx dronekit.test.unit' - - 'nosetests -svx dronekit.test.sitl' - -general: - build_dir: . - -deployment: - production: - branch: master - commands: - - ./scripts/update-docs.sh - -notify: - webhooks: - - url: https://webhooks.gitter.im/e/27b0e1a9fede99dbbe6c From 0d4a368dde1cbd2c2741739cba6efe2cd91d4b1a Mon Sep 17 00:00:00 2001 From: Ramon Roche Date: Wed, 11 Apr 2018 12:31:39 -0700 Subject: [PATCH 417/475] disable docs deploy from circleci (#814) we are migrating service providers and need to disable deployments of docs --- .circleci/config.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f386bc9e0..21c28075f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -78,10 +78,11 @@ workflows: jobs: - python2 # - python3 - - deploy: - requires: - - python2 - filters: - branches: - only: - - master +# disabling until we find a new docs server +# - deploy: +# requires: +# - python2 +# filters: +# branches: +# only: +# - master From 8f5fa48e675dac3a270517f5c093fd5785f98f5c Mon Sep 17 00:00:00 2001 From: Ramon Roche Date: Wed, 11 Apr 2018 12:52:54 -0700 Subject: [PATCH 418/475] travisci: disable python3 environment tests (#815) TODO: re enable tests once we fix pymavlink --- .travis.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9fc8157b9..a230b369c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,11 +7,11 @@ env: python: - 2.7 - - 3.6 + #- 3.6 before_install: - pip install --upgrade pip - + install: - pip install -r requirements.txt - pip install flake8 @@ -38,9 +38,9 @@ notifications: on_failure: always on_start: never -matrix: - allow_failures: - - python: 3.6 +#matrix: + #allow_failures: + #- python: 3.6 branches: only: From 32b6ba10713b35f8cd61492bab5e5235c5e149cc Mon Sep 17 00:00:00 2001 From: michael-hart Date: Tue, 15 May 2018 15:27:52 +0100 Subject: [PATCH 419/475] Home location set command corrected param1 should have value 0 rather than 2 --- dronekit/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 85d101514..44d70e2d7 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1969,7 +1969,7 @@ def home_location(self, pos): 0, 0, # target system, target component mavutil.mavlink.MAV_CMD_DO_SET_HOME, # command 0, # confirmation - 2, # param 1: 1 to use current position, 2 to use the entered values. + 0, # param 1: 1 to use current position, 0 to use the entered values. 0, 0, 0, # params 2-4 pos.lat, pos.lon, pos.alt)) From a20eadf92b5d30940a7533a8a57a39273cdf3938 Mon Sep 17 00:00:00 2001 From: Pietro De Nicolao Date: Thu, 2 Aug 2018 14:15:21 +0200 Subject: [PATCH 420/475] __init__.py: rename variable "await" As of Python 3.7, "await" is a reserved word (PEP 492). --- dronekit/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 85d101514..8f11fe69a 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -2347,9 +2347,9 @@ def wait_ready(self, *types, **kwargs): raise ValueError('wait_ready expects one or more string arguments.') # Wait for these attributes to have been set. - await = set(types) + await_attributes = set(types) start = monotonic.monotonic() - while not await.issubset(self._ready_attrs): + while not await_attributes.issubset(self._ready_attrs): time.sleep(0.1) if monotonic.monotonic() - start > timeout: if raise_exception: From 7000397ad04441eb1531ca7e546fa7dbdfd88986 Mon Sep 17 00:00:00 2001 From: pietrodn Date: Sat, 20 Oct 2018 10:43:39 +0200 Subject: [PATCH 421/475] Properly close Vehicle instances after SITL tests If Vehicle instances are left unclosed, the latest pymavlink (2.2.20) will spam a lot of "EOF on TCP socket" warning messages: https://github.com/ArduPilot/pymavlink/issues/230 --- dronekit/test/sitl/test_capability_and_version.py | 2 ++ dronekit/test/sitl/test_locations.py | 2 ++ dronekit/test/sitl/test_mavlink.py | 3 +++ dronekit/test/sitl/test_mode_settings.py | 2 ++ dronekit/test/sitl/test_reboot.py | 2 ++ dronekit/test/sitl/test_state.py | 2 ++ dronekit/test/sitl/test_timeout.py | 2 ++ dronekit/test/sitl/test_waypoints.py | 4 ++++ 8 files changed, 19 insertions(+) diff --git a/dronekit/test/sitl/test_capability_and_version.py b/dronekit/test/sitl/test_capability_and_version.py index ed466cdd3..1aa1cd531 100644 --- a/dronekit/test/sitl/test_capability_and_version.py +++ b/dronekit/test/sitl/test_capability_and_version.py @@ -34,3 +34,5 @@ def test_115(connpath): assert_true(v.version.major is not None) assert_true(len(v.version.release_type()) >= 2) assert_true(v.version.release_version() is not None) + + v.close() diff --git a/dronekit/test/sitl/test_locations.py b/dronekit/test/sitl/test_locations.py index c1e5ef2b7..326b62b8b 100644 --- a/dronekit/test/sitl/test_locations.py +++ b/dronekit/test/sitl/test_locations.py @@ -83,3 +83,5 @@ def callback(*args): wait_for(lambda : ret['success'], 30) assert ret['success'], 'Expected location object to emit notifications.' + + vehicle.close() diff --git a/dronekit/test/sitl/test_mavlink.py b/dronekit/test/sitl/test_mavlink.py index ac9330253..6ddf2d442 100644 --- a/dronekit/test/sitl/test_mavlink.py +++ b/dronekit/test/sitl/test_mavlink.py @@ -27,3 +27,6 @@ def callback(*args): i -= 1 assert result['success'] + + vehicle2.close() + vehicle.close() diff --git a/dronekit/test/sitl/test_mode_settings.py b/dronekit/test/sitl/test_mode_settings.py index da7ec794c..95392c36e 100644 --- a/dronekit/test/sitl/test_mode_settings.py +++ b/dronekit/test/sitl/test_mode_settings.py @@ -13,3 +13,5 @@ def listener(self, name, m): assert_equals('STABILIZE', self._flightmode) vehicle.add_message_listener('HEARTBEAT', listener) + + vehicle.close() diff --git a/dronekit/test/sitl/test_reboot.py b/dronekit/test/sitl/test_reboot.py index 3a7252fdc..bf9236c8e 100644 --- a/dronekit/test/sitl/test_reboot.py +++ b/dronekit/test/sitl/test_reboot.py @@ -25,3 +25,5 @@ def on_ack(self, name, message): assert_equal(1, len(reboot_acks)) # one and only one ACK assert_equal(246, reboot_acks[0].command) # for the correct command assert_equal(0, reboot_acks[0].result) # the result must be successful + + vehicle.close() diff --git a/dronekit/test/sitl/test_state.py b/dronekit/test/sitl/test_state.py index 8f6502856..850f9da58 100644 --- a/dronekit/test/sitl/test_state.py +++ b/dronekit/test/sitl/test_state.py @@ -13,3 +13,5 @@ def test_state(connpath): assert_equals(type(vehicle.system_status), SystemStatus) assert_equals(type(vehicle.system_status.state), str) + + vehicle.close() diff --git a/dronekit/test/sitl/test_timeout.py b/dronekit/test/sitl/test_timeout.py index b6d539682..d36b78ca1 100644 --- a/dronekit/test/sitl/test_timeout.py +++ b/dronekit/test/sitl/test_timeout.py @@ -35,6 +35,8 @@ def test_timeout_empty(): # Connect with timeout of 10s. vehicle = connect('tcp:127.0.0.1:5760', wait_ready=True, heartbeat_timeout=20) + vehicle.close() + # Should not pass assert False except: diff --git a/dronekit/test/sitl/test_waypoints.py b/dronekit/test/sitl/test_waypoints.py index 61976fbbd..288509b98 100644 --- a/dronekit/test/sitl/test_waypoints.py +++ b/dronekit/test/sitl/test_waypoints.py @@ -41,6 +41,8 @@ def test_set_home(connpath): assert_equals(vehicle.home_location.lon, 149) assert_equals(vehicle.home_location.alt, 600) + vehicle.close() + @with_sitl def test_parameter(connpath): @@ -139,3 +141,5 @@ def assert_commands(count): vehicle.flush() # Send commands assert_commands(1) + + vehicle.close() From d52ebda3e991b88c154f81f1e24bfb4d6951c4ad Mon Sep 17 00:00:00 2001 From: pietrodn Date: Sat, 20 Oct 2018 11:03:45 +0200 Subject: [PATCH 422/475] Update pymavlink for Python 3 support --- .circleci/config.yml | 12 ++++++------ requirements.txt | 2 +- setup.py | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 21c28075f..31203edc5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -48,11 +48,11 @@ jobs: working_directory: ~/dronekit-python2 <<: *commonsteps -# python3: -# docker: -# - image: circleci/python:3.6-stretch -# working_directory: ~/dronekit-python3 -# <<: *commonsteps + python3: + docker: + - image: circleci/python:3.6-stretch + working_directory: ~/dronekit-python3 + <<: *commonsteps deploy: name: Deploy to dronekit.io @@ -77,7 +77,7 @@ workflows: build_test_deploy: jobs: - python2 -# - python3 + - python3 # disabling until we find a new docs server # - deploy: # requires: diff --git a/requirements.txt b/requirements.txt index b621f67c5..7b67b3550 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -pymavlink>=2.2.3 +pymavlink>=2.2.20 monotonic>=1.3 future>=0.15.2 nose==1.3.7 diff --git a/setup.py b/setup.py index 3824ee523..8b4805b32 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ url='https://github.com/dronekit/dronekit-python', author='3D Robotics', install_requires=[ - 'pymavlink>=2.2.3', + 'pymavlink>=2.2.20', 'monotonic==1.2', 'future==0.15.2' ], From d33778858d42b5d263933c7ce0754ab7f57d0fb7 Mon Sep 17 00:00:00 2001 From: pietrodn Date: Sun, 28 Oct 2018 08:35:27 +0100 Subject: [PATCH 423/475] mavlink.py: efficient I/O waiting with select() pymavlink uses non-blocking sockets and serial ports: polling for data in a while loop with a sleep(0.05) is inefficient and leads to increased latency for incoming MAVLink messages (issue #863). --- dronekit/mavlink.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dronekit/mavlink.py b/dronekit/mavlink.py index 7cff501df..b27ec83bf 100644 --- a/dronekit/mavlink.py +++ b/dronekit/mavlink.py @@ -203,13 +203,13 @@ def mavlink_thread_in(): # Huge try catch in case we see http://bugs.python.org/issue1856 try: while self._alive: - # Downtime - time.sleep(0.05) - # Loop listeners. for fn in self.loop_listeners: fn(self) + # Sleep + self.master.select(0.05) + while self._accept_input: try: msg = self.master.recv_msg() From 883fadc88af181296a9e437bfef124180ec0c92d Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Mon, 29 Oct 2018 14:24:26 +1100 Subject: [PATCH 424/475] Correct comment on play_tune --- dronekit/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index b2e0cf36b..3bbc0927d 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -2300,7 +2300,7 @@ def send_capabilities_request(self, vehicle, name, m): vehicle.send_mavlink(capability_msg) def play_tune(self, tune): - '''Request an AUTOPILOT_VERSION packet''' + '''Play a tune on the vehicle''' msg = self.message_factory.play_tune_encode(0, 0, tune) self.send_mavlink(msg) From a8f3907a562ad714d1f21b16c971cb236f72884f Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Thu, 9 Nov 2017 14:37:49 +1100 Subject: [PATCH 425/475] Add still-waiting interval and callback to wait_ready --- dronekit/__init__.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 3bbc0927d..b66ec9ad8 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -2349,14 +2349,24 @@ def wait_ready(self, *types, **kwargs): # Wait for these attributes to have been set. await_attributes = set(types) start = monotonic.monotonic() + still_waiting_last_message_sent = start + still_waiting_callback = kwargs.get('still_waiting_callback') + still_waiting_message_interval = kwargs.get('still_waiting_interval', 1) + while not await_attributes.issubset(self._ready_attrs): time.sleep(0.1) - if monotonic.monotonic() - start > timeout: + now = monotonic.monotonic() + if now - start > timeout: if raise_exception: raise TimeoutError('wait_ready experienced a timeout after %s seconds.' % timeout) else: return False + if (still_waiting_callback and + now - still_waiting_last_message_sent > still_waiting_message_interval): + still_waiting_last_message_sent = now + if still_waiting_callback: + still_waiting_callback(await-self._ready_attrs) return True @@ -2941,9 +2951,15 @@ def __setitem__(self, index, value): from dronekit.mavlink import MAVConnection +def default_still_waiting_callback(atts): + print("Still waiting for data from vehicle: %s" % ','.join(atts), + file=sys.stderr) + def connect(ip, _initialize=True, wait_ready=None, + still_waiting_callback=default_still_waiting_callback, + still_waiting_interval=1, status_printer=errprinter, vehicle_class=None, rate=4, @@ -3019,7 +3035,8 @@ def listener(self, name, m): if wait_ready: if wait_ready == True: - vehicle.wait_ready(True) + vehicle.wait_ready(still_waiting_interval=still_waiting_interval, + still_waiting_callback=still_waiting_callback) else: vehicle.wait_ready(*wait_ready) From e7e5ab1ea43b9b99249623cb6ed160a834170a02 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Thu, 9 Nov 2017 16:59:50 +1100 Subject: [PATCH 426/475] Add timeout to kwargs in connect, pass to wait_ready --- dronekit/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index b66ec9ad8..8aa66431e 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -2958,6 +2958,7 @@ def default_still_waiting_callback(atts): def connect(ip, _initialize=True, wait_ready=None, + timeout=30, still_waiting_callback=default_still_waiting_callback, still_waiting_interval=1, status_printer=errprinter, @@ -3036,7 +3037,8 @@ def listener(self, name, m): if wait_ready: if wait_ready == True: vehicle.wait_ready(still_waiting_interval=still_waiting_interval, - still_waiting_callback=still_waiting_callback) + still_waiting_callback=still_waiting_callback, + timeout=timeout) else: vehicle.wait_ready(*wait_ready) From 63e913b1b5bddfb8e771641d883934789a93d5db Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Thu, 9 Nov 2017 17:00:31 +1100 Subject: [PATCH 427/475] examples/follow_me: set timeout on connect to 300 --- examples/follow_me/follow_me.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/follow_me/follow_me.py b/examples/follow_me/follow_me.py index aa489d26b..ef1227bce 100644 --- a/examples/follow_me/follow_me.py +++ b/examples/follow_me/follow_me.py @@ -40,7 +40,7 @@ # Connect to the Vehicle print('Connecting to vehicle on: %s' % connection_string) -vehicle = connect(connection_string, wait_ready=True) +vehicle = connect(connection_string, wait_ready=True, timeout=300) From 513ab4ef68bd5b578ea08ed481b471091db1e44b Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Thu, 1 Nov 2018 08:23:34 +1100 Subject: [PATCH 428/475] fixup! Add still-waiting interval and callback to wait_ready --- dronekit/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 8aa66431e..dcba106a9 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -2366,7 +2366,7 @@ def wait_ready(self, *types, **kwargs): now - still_waiting_last_message_sent > still_waiting_message_interval): still_waiting_last_message_sent = now if still_waiting_callback: - still_waiting_callback(await-self._ready_attrs) + still_waiting_callback(await_attributes-self._ready_attrs) return True From 6eaa942e9015df7f1bb0861d0809ff238ebbebbb Mon Sep 17 00:00:00 2001 From: pietrodn Date: Tue, 30 Oct 2018 22:45:42 +0100 Subject: [PATCH 429/475] Faster comparisons with None/True/False, various performance fixes --- dronekit/__init__.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index dcba106a9..51fdf2d9c 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -304,7 +304,7 @@ def __init__(self, raw_version, autopilot_type, vehicle_type): self.autopilot_type = autopilot_type self.vehicle_type = vehicle_type self.raw_version = raw_version - if(raw_version == None): + if raw_version is None: self.major = None self.minor = None self.patch = None @@ -640,7 +640,7 @@ def notify_attribute_listeners(self, attr_name, value, cache=False): """ # Cached values are not re-sent if they are unchanged. if cache: - if attr_name in self._attribute_cache and self._attribute_cache[attr_name] == value: + if self._attribute_cache.get(attr_name) == value: return self._attribute_cache[attr_name] = value @@ -885,7 +885,7 @@ def listener(vehicle, name, m): vehicle.notify_attribute_listeners('location.global_relative_frame', vehicle.location.global_relative_frame) - if self._alt != None or m.alt != 0: + if self._alt is not None or m.alt != 0: # Require first alt value to be non-0 # TODO is this the proper check to do? self._alt = m.alt / 1000.0 @@ -1197,7 +1197,7 @@ def listener(self, name, m): self.notify_attribute_listeners('armed', self.armed, cache=True) self._autopilot_type = m.autopilot self._vehicle_type = m.type - if self._is_mode_available(m.custom_mode, m.base_mode) == False: + if self._is_mode_available(m.custom_mode, m.base_mode) is False: raise APIException("mode (%s, %s) not available on mavlink definition" % (m.custom_mode, m.base_mode)) if self._autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_PX4: self._flightmode = mavutil.interpret_px4_mode(m.base_mode, m.custom_mode) @@ -1254,7 +1254,7 @@ def listener(self, name, msg): # Waypoint send to master @self.on_message(['WAYPOINT_REQUEST', 'MISSION_REQUEST']) def listener(self, name, msg): - if self._wp_uploaded != None: + if self._wp_uploaded is not None: wp = self._wploader.wp(msg.seq) handler.fix_targets(wp) self._master.mav.send(wp) @@ -1282,7 +1282,7 @@ def listener(_): if not self._params_start: return - if None not in self._params_set and not self._params_loaded: + if not self._params_loaded and all(x is not None for x in self._params_set): self._params_loaded = True self.notify_attribute_listeners('parameters', self.parameters) @@ -1312,7 +1312,7 @@ def listener(self, name, msg): # we lack a param_id. try: if msg.param_index < msg.param_count and msg: - if self._params_set[msg.param_index] == None: + if self._params_set[msg.param_index] is None: self._params_last = monotonic.monotonic() self._params_duration = start_duration self._params_set[msg.param_index] = msg @@ -1350,7 +1350,7 @@ def listener(_): raise APIException('No heartbeat in %s seconds, aborting.' % self._heartbeat_error) elif monotonic.monotonic() - self._heartbeat_lastreceived > self._heartbeat_warning: - if self._heartbeat_timeout == False: + if self._heartbeat_timeout is False: errprinter('>>> Link timeout, no heartbeat in last %s seconds' % self._heartbeat_warning) self._heartbeat_timeout = True @@ -1673,7 +1673,7 @@ def battery(self): """ Current system batter status (:py:class:`Battery`). """ - if self._voltage == None or self._current == None or self._level == None: + if self._voltage is None or self._current is None or self._level is None: return None return Battery(self._voltage, self._current, self._level) @@ -2180,9 +2180,9 @@ def simple_goto(self, location, airspeed=None, groundspeed=None): 0, 0, 0, location.lat, location.lon, alt) - if airspeed != None: + if airspeed is not None: self.airspeed = airspeed - if groundspeed != None: + if groundspeed is not None: self.groundspeed = groundspeed def send_mavlink(self, message): @@ -2271,7 +2271,7 @@ def initialize(self, rate=4, heartbeat_timeout=30): time.sleep(0.1) # Initialize data stream. - if rate != None: + if rate is not None: self._master.mav.request_data_stream_send(0, 0, mavutil.mavlink.MAV_DATA_STREAM_ALL, rate, 1) @@ -3035,7 +3035,7 @@ def listener(self, name, m): vehicle.initialize(rate=rate, heartbeat_timeout=heartbeat_timeout) if wait_ready: - if wait_ready == True: + if wait_ready is True: vehicle.wait_ready(still_waiting_interval=still_waiting_interval, still_waiting_callback=still_waiting_callback, timeout=timeout) From 3f89410a1f29c65029206010e82516865e406387 Mon Sep 17 00:00:00 2001 From: pietrodn Date: Thu, 1 Nov 2018 00:14:04 +0100 Subject: [PATCH 430/475] Fix virtualenv installation for CircleCI --- .circleci/config.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 31203edc5..825f26624 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,11 +5,6 @@ common: &commonsteps steps: - checkout - - run: - name: Install global tools - command: | - pip install -U virtualenv - - run: name: Install dronekit with dependencies command: | From b559bf1f4ce2eeefe7b6898d6e6de84eb6a8113d Mon Sep 17 00:00:00 2001 From: pietrodn Date: Thu, 1 Nov 2018 01:04:06 +0100 Subject: [PATCH 431/475] Travis: build for Python 3; resolve #816 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a230b369c..16dfd6d8b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ env: python: - 2.7 - #- 3.6 + - 3.6 before_install: - pip install --upgrade pip From 16d6a793e5132e24263754d4af68b3d81e58b014 Mon Sep 17 00:00:00 2001 From: pietrodn Date: Thu, 1 Nov 2018 10:17:56 +0100 Subject: [PATCH 432/475] mavlink.py: specific exception handling for MAVError --- dronekit/mavlink.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/dronekit/mavlink.py b/dronekit/mavlink.py index b27ec83bf..f19d1a5ae 100644 --- a/dronekit/mavlink.py +++ b/dronekit/mavlink.py @@ -218,11 +218,15 @@ def mavlink_thread_in(): if error.errno == ECONNABORTED: raise APIException('Connection aborting during send') raise - except Exception as e: - # TODO this should be more rigorous. How to avoid + except mavutil.mavlink.MAVError as e: + # Avoid # invalid MAVLink prefix '73' # invalid MAVLink prefix '13' - # errprinter('mav recv error:', e) + #errprinter('mav recv error:', e) + msg = None + except Exception as e: + # Log any other unexpected exception + errprinter('>>> Exception while receiving message: ', e) msg = None if not msg: break From 945b2f8ed67330a3decffde8ace906d098f7f4fd Mon Sep 17 00:00:00 2001 From: pietrodn Date: Thu, 1 Nov 2018 13:10:50 +0100 Subject: [PATCH 433/475] PEP8 and style improvements --- dronekit/__init__.py | 193 ++++++++---------- dronekit/mavlink.py | 15 +- dronekit/test/__init__.py | 7 +- dronekit/test/sitl/__init__.py | 1 - dronekit/test/sitl/test_110.py | 6 +- dronekit/test/sitl/test_115.py | 2 - dronekit/test/sitl/test_12.py | 4 +- .../test/sitl/test_capability_and_version.py | 4 +- dronekit/test/sitl/test_channels.py | 7 +- dronekit/test/sitl/test_earlyattrs.py | 6 +- dronekit/test/sitl/test_locations.py | 10 +- dronekit/test/sitl/test_mavlink.py | 2 - dronekit/test/sitl/test_mode_settings.py | 2 - dronekit/test/sitl/test_modeavailable.py | 11 +- dronekit/test/sitl/test_parameters.py | 4 +- dronekit/test/sitl/test_simpledemo.py | 3 - dronekit/test/sitl/test_state.py | 6 +- dronekit/test/sitl/test_timeout.py | 4 +- dronekit/test/sitl/test_vehicleclass.py | 1 - dronekit/test/sitl/test_waypoints.py | 3 +- dronekit/test/unit/__init__.py | 1 - dronekit/test/unit/test_api.py | 2 - dronekit/util.py | 1 + 23 files changed, 123 insertions(+), 172 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 51fdf2d9c..17dbf2090 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -34,17 +34,10 @@ import collections import copy import math -import os import struct -import platform -from queue import Queue, Empty import re -import socket import sys -import threading -from threading import Thread import time -import types import monotonic from past.builtins import basestring @@ -197,7 +190,7 @@ def distance_home(self): if self.north is not None and self.east is not None: if self.down is not None: - return math.sqrt(self.north**2 + self.east**2 + self.down**2) + return math.sqrt(self.north**2 + self.east**2 + self.down**2) else: return math.sqrt(self.north**2 + self.east**2) @@ -270,6 +263,7 @@ def __init__(self, distance, voltage): def __str__(self): return "Rangefinder: distance={}, voltage={}".format(self.distance, self.voltage) + class Version(object): """ Autopilot version and type. @@ -322,7 +316,6 @@ def is_stable(self): """ return self.release == 255 - def release_version(self): """ Returns the version within the release type (an integer). @@ -330,38 +323,37 @@ def release_version(self): """ if self.release is None: return None - if(self.release == 255): + if self.release == 255: return 0 return self.release % 64 - def release_type(self): """ Returns text describing the release type e.g. "alpha", "stable" etc. """ if self.release is None: return None - types = [ "dev", "alpha", "beta", "rc" ] + types = ["dev", "alpha", "beta", "rc"] return types[self.release >> 6] def __str__(self): - prefix="" + prefix = "" - if(self.autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_ARDUPILOTMEGA): + if self.autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_ARDUPILOTMEGA: prefix += "APM:" - elif(self.autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_PX4): + elif self.autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_PX4: prefix += "PX4" else: prefix += "UnknownAutoPilot" - if(self.vehicle_type == mavutil.mavlink.MAV_TYPE_QUADROTOR): + if self.vehicle_type == mavutil.mavlink.MAV_TYPE_QUADROTOR: prefix += "Copter-" - elif(self.vehicle_type == mavutil.mavlink.MAV_TYPE_FIXED_WING): + elif self.vehicle_type == mavutil.mavlink.MAV_TYPE_FIXED_WING: prefix += "Plane-" - elif(self.vehicle_type == mavutil.mavlink.MAV_TYPE_GROUND_ROVER): + elif self.vehicle_type == mavutil.mavlink.MAV_TYPE_GROUND_ROVER: prefix += "Rover-" else: - prefix += "UnknownVehicleType%d-" % (self.vehicle_type) + prefix += "UnknownVehicleType%d-" % self.vehicle_type if self.release_type() is None: release_type = "UnknownReleaseType" @@ -373,6 +365,7 @@ def __str__(self): return prefix + "%s.%s.%s" % (self.major, self.minor, self.patch) + release_type + class Capabilities: """ Autopilot capabilities (supported message types and functionality). @@ -542,8 +535,6 @@ def __init__(self): self._attribute_listeners = {} self._attribute_cache = {} - - def add_attribute_listener(self, attr_name, observer): """ Add an attribute listener callback. @@ -587,12 +578,12 @@ def location_callback(self, attr_name, msg): :param observer: The callback to invoke when a change in the attribute is detected. """ - l = self._attribute_listeners.get(attr_name) - if l is None: - l = [] - self._attribute_listeners[attr_name] = l - if not observer in l: - l.append(observer) + listeners_for_attr = self._attribute_listeners.get(attr_name) + if listeners_for_attr is None: + listeners_for_attr = [] + self._attribute_listeners[attr_name] = listeners_for_attr + if observer not in listeners_for_attr: + listeners_for_attr.append(observer) def remove_attribute_listener(self, attr_name, observer): """ @@ -611,10 +602,10 @@ def remove_attribute_listener(self, attr_name, observer): :param observer: The callback function to remove. """ - l = self._attribute_listeners.get(attr_name) - if l is not None: - l.remove(observer) - if len(l) == 0: + listeners_for_attr = self._attribute_listeners.get(attr_name) + if listeners_for_attr is not None: + listeners_for_attr.remove(observer) + if len(listeners_for_attr) == 0: del self._attribute_listeners[attr_name] def notify_attribute_listeners(self, attr_name, value, cache=False): @@ -695,7 +686,7 @@ def attitude_listener(self, name, msg): See :ref:`vehicle_state_observe_attributes` for more information. - :param String attr_name: The name of the attribute to watch (or '*' to watch all attributes). + :param String name: The name of the attribute to watch (or '*' to watch all attributes). :param observer: The callback to invoke when a change in the attribute is detected. """ @@ -730,7 +721,7 @@ def __getitem__(self, key): return dict.__getitem__(self, str(key)) def __setitem__(self, key, value): - if not (int(key) > 0 and int(key) <= self._count): + if not (0 < int(key) <= self._count): raise KeyError('Invalid channel index %s' % key) if not value: try: @@ -1022,7 +1013,7 @@ def __init__(self, handler): # Cache all updated attributes for wait_ready. # By default, we presume all "commands" are loaded. - self._ready_attrs = set(['commands']) + self._ready_attrs = {'commands'} # Default parameters when calling wait_ready() or wait_ready(True). self._default_ready_attrs = ['parameters', 'gps_0', 'armed', 'mode', 'attitude'] @@ -1099,7 +1090,7 @@ def listener(self, name, m): self.notify_attribute_listeners('mount', self.mount_status) self._capabilities = None - self._raw_version =None + self._raw_version = None self._autopilot_version_msg_count = 0 @self.on_message('AUTOPILOT_VERSION') @@ -1185,8 +1176,8 @@ def listener(self, name, m): self._flightmode = 'AUTO' self._armed = False self._system_status = None - self._autopilot_type = None#PX4, ArduPilot, etc. - self._vehicle_type = None#quadcopter, plane, etc. + self._autopilot_type = None # PX4, ArduPilot, etc. + self._vehicle_type = None # quadcopter, plane, etc. @self.on_message('HEARTBEAT') def listener(self, name, m): @@ -1223,10 +1214,9 @@ def listener(self, name, msg): self._wploader.expected_count = msg.count self._master.waypoint_request_send(0) - @self.on_message(['HOME_POSITION']) def listener(self, name, msg): - self._home_location = LocationGlobal(msg.latitude/1.0e7, msg.longitude/1.0e7, msg.altitude/1000.0); + self._home_location = LocationGlobal(msg.latitude / 1.0e7, msg.longitude / 1.0e7, msg.altitude / 1000.0) self.notify_attribute_listeners('home_location', self.home_location, cache=True) @self.on_message(['WAYPOINT', 'MISSION_ITEM']) @@ -1289,7 +1279,7 @@ def listener(_): if not self._params_loaded and monotonic.monotonic() - self._params_last > self._params_duration: c = 0 for i, v in enumerate(self._params_set): - if v == None: + if v is None: self._master.mav.param_request_read_send(0, 0, '', i) c += 1 if c > 50: @@ -1345,8 +1335,7 @@ def listener(_): # Timeouts. if self._heartbeat_started: - if self._heartbeat_error and self._heartbeat_error > 0 and monotonic.monotonic( - ) - self._heartbeat_lastreceived > self._heartbeat_error: + if self._heartbeat_error and monotonic.monotonic() - self._heartbeat_lastreceived > self._heartbeat_error > 0: raise APIException('No heartbeat in %s seconds, aborting.' % self._heartbeat_error) elif monotonic.monotonic() - self._heartbeat_lastreceived > self._heartbeat_warning: @@ -1523,7 +1512,6 @@ def notify_message_listeners(self, name, msg): msg.get_type()) errprinter('>>> ' + str(e)) - def close(self): return self._handler.close() @@ -1812,20 +1800,19 @@ def groundspeed(self): @groundspeed.setter def groundspeed(self, speed): - speed_type = 1 # ground speed + speed_type = 1 # ground speed msg = self.message_factory.command_long_encode( 0, 0, # target system, target component - mavutil.mavlink.MAV_CMD_DO_CHANGE_SPEED, #command - 0, #confirmation - speed_type, #param 1 - speed, # speed in metres/second - -1, 0, 0, 0, 0 #param 3 - 7 - ) + mavutil.mavlink.MAV_CMD_DO_CHANGE_SPEED, # command + 0, # confirmation + speed_type, # param 1 + speed, # speed in metres/second + -1, 0, 0, 0, 0 # param 3 - 7 + ) # send command to vehicle self.send_mavlink(msg) - @property def airspeed(self): """ @@ -1839,15 +1826,15 @@ def airspeed(self): @airspeed.setter def airspeed(self, speed): - speed_type = 0 # air speed + speed_type = 0 # air speed msg = self.message_factory.command_long_encode( 0, 0, # target system, target component - mavutil.mavlink.MAV_CMD_DO_CHANGE_SPEED, #command - 0, #confirmation - speed_type, #param 1 - speed, # speed in metres/second - -1, 0, 0, 0, 0 #param 3 - 7 - ) + mavutil.mavlink.MAV_CMD_DO_CHANGE_SPEED, # command + 0, # confirmation + speed_type, # param 1 + speed, # speed in metres/second + -1, 0, 0, 0, 0 # param 3 - 7 + ) # send command to vehicle self.send_mavlink(msg) @@ -2084,12 +2071,12 @@ def get_alt(): def check_alt(): cur = get_alt() - delta = abs(alt-cur) + delta = abs(alt - cur) return ( (delta < epsilon) or - (start < alt and cur > alt) or - (start > alt and cur < alt) + (cur > alt > start) or + (cur < alt < start) ) start = get_alt() @@ -2131,7 +2118,7 @@ def simple_takeoff(self, alt=None): if math.isnan(altitude) or math.isinf(altitude): raise ValueError("Altitude was NaN or Infinity. Please provide a real number") self._master.mav.command_long_send(0, 0, mavutil.mavlink.MAV_CMD_NAV_TAKEOFF, - 0, 0, 0, 0, 0, 0, 0, altitude) + 0, 0, 0, 0, 0, 0, 0, altitude) def simple_goto(self, location, airspeed=None, groundspeed=None): ''' @@ -2363,10 +2350,10 @@ def wait_ready(self, *types, **kwargs): else: return False if (still_waiting_callback and - now - still_waiting_last_message_sent > still_waiting_message_interval): + now - still_waiting_last_message_sent > still_waiting_message_interval): still_waiting_last_message_sent = now if still_waiting_callback: - still_waiting_callback(await_attributes-self._ready_attrs) + still_waiting_callback(await_attributes - self._ready_attrs) return True @@ -2476,22 +2463,23 @@ def rotate(self, pitch, roll, yaw): :param yaw: Gimbal yaw in degrees relative to *global frame* (0 is North, 90 is West, 180 is South etc.) """ msg = self._vehicle.message_factory.mount_configure_encode( - 0, 1, # target system, target component - mavutil.mavlink.MAV_MOUNT_MODE_MAVLINK_TARGETING, #mount_mode - 1, # stabilize roll - 1, # stabilize pitch - 1, # stabilize yaw - ) + 0, 1, # target system, target component + mavutil.mavlink.MAV_MOUNT_MODE_MAVLINK_TARGETING, #mount_mode + 1, # stabilize roll + 1, # stabilize pitch + 1, # stabilize yaw + ) self._vehicle.send_mavlink(msg) msg = self._vehicle.message_factory.mount_control_encode( - 0, 1, # target system, target component - pitch * 100, # pitch is in centidegrees - roll * 100, # roll - yaw * 100, # yaw is in centidegrees - 0) # save position + 0, 1, # target system, target component + pitch * 100, # pitch is in centidegrees + roll * 100, # roll + yaw * 100, # yaw is in centidegrees + 0 # save position + ) self._vehicle.send_mavlink(msg) - def target_location(self,roi): + def target_location(self, roi): """ Point the gimbal at a specific region of interest (ROI). @@ -2508,17 +2496,17 @@ def target_location(self,roi): :param roi: Target location in global relative frame. """ - #set gimbal to targeting mode + # set gimbal to targeting mode msg = self._vehicle.message_factory.mount_configure_encode( - 0, 1, # target system, target component - mavutil.mavlink.MAV_MOUNT_MODE_GPS_POINT, #mount_mode - 1, # stabilize roll - 1, # stabilize pitch - 1, # stabilize yaw - ) + 0, 1, # target system, target component + mavutil.mavlink.MAV_MOUNT_MODE_GPS_POINT, # mount_mode + 1, # stabilize roll + 1, # stabilize pitch + 1, # stabilize yaw + ) self._vehicle.send_mavlink(msg) - #Get altitude relative to home irrespective of Location object passed in. + # Get altitude relative to home irrespective of Location object passed in. if isinstance(roi, LocationGlobalRelative): alt = roi.alt elif isinstance(roi, LocationGlobal): @@ -2529,16 +2517,16 @@ def target_location(self,roi): else: raise ValueError('Expecting location to be LocationGlobal or LocationGlobalRelative.') - #set the ROI + # set the ROI msg = self._vehicle.message_factory.command_long_encode( - 0, 1, # target system, target component - mavutil.mavlink.MAV_CMD_DO_SET_ROI, #command - 0, #confirmation - 0, 0, 0, 0, #params 1-4 - roi.lat, - roi.lon, - alt - ) + 0, 1, # target system, target component + mavutil.mavlink.MAV_CMD_DO_SET_ROI, # command + 0, # confirmation + 0, 0, 0, 0, # params 1-4 + roi.lat, + roi.lon, + alt + ) self._vehicle.send_mavlink(msg) def release(self): @@ -2549,12 +2537,12 @@ def release(self): or :py:func:`target_location`. Control will automatically be released if you change vehicle mode. """ msg = self._vehicle.message_factory.mount_configure_encode( - 0, 1, # target system, target component - mavutil.mavlink.MAV_MOUNT_MODE_RC_TARGETING, #mount_mode - 1, # stabilize roll - 1, # stabilize pitch - 1, # stabilize yaw - ) + 0, 1, # target system, target component + mavutil.mavlink.MAV_MOUNT_MODE_RC_TARGETING, # mount_mode + 1, # stabilize roll + 1, # stabilize pitch + 1, # stabilize yaw + ) self._vehicle.send_mavlink(msg) def __str__(self): @@ -2623,7 +2611,6 @@ def set(self, name, value, retries=3, wait_ready=False): name = name.upper() # convert to single precision floating point number (the type used by low level mavlink messages) value = float(struct.unpack('f', struct.pack('f', value))[0]) - success = False remaining = retries while True: self._vehicle._master.param_set_send(name, value) @@ -2948,13 +2935,11 @@ def __setitem__(self, index, value): self._vehicle._wpts_dirty = True -from dronekit.mavlink import MAVConnection - - def default_still_waiting_callback(atts): print("Still waiting for data from vehicle: %s" % ','.join(atts), file=sys.stderr) + def connect(ip, _initialize=True, wait_ready=None, @@ -3019,6 +3004,8 @@ def connect(ip, :returns: A connected vehicle of the type defined in ``vehicle_class`` (a superclass of :py:class:`Vehicle`). """ + from dronekit.mavlink import MAVConnection + if not vehicle_class: vehicle_class = Vehicle diff --git a/dronekit/mavlink.py b/dronekit/mavlink.py index f19d1a5ae..a38bde1c5 100644 --- a/dronekit/mavlink.py +++ b/dronekit/mavlink.py @@ -5,15 +5,12 @@ import sys import os import platform -import re import copy -import dronekit from dronekit import APIException from dronekit.util import errprinter -from pymavlink import mavutil, mavwp +from pymavlink import mavutil from queue import Queue, Empty from threading import Thread -import types if platform.system() == 'Windows': from errno import WSAECONNRESET as ECONNABORTED @@ -58,23 +55,23 @@ def __init__(self, device, baud=None, input=True, broadcast=False, source_system self.port.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) self.broadcast = True mavutil.set_close_on_exec(self.port.fileno()) - self.port.setblocking(0) + self.port.setblocking(False) mavutil.mavfile.__init__(self, self.port.fileno(), device, source_system=source_system, input=input, use_native=use_native) def close(self): self.port.close() - def recv(self,n=None): + def recv(self, n=None): try: try: data, new_addr = self.port.recvfrom(65535) except socket.error as e: - if e.errno in [ errno.EAGAIN, errno.EWOULDBLOCK, errno.ECONNREFUSED ]: + if e.errno in [errno.EAGAIN, errno.EWOULDBLOCK, errno.ECONNREFUSED]: return "" if self.udp_server: self.addresses.add(new_addr) elif self.broadcast: - self.addresses = set([new_addr]) + self.addresses = {new_addr} return data except Exception as e: print(e) @@ -222,7 +219,7 @@ def mavlink_thread_in(): # Avoid # invalid MAVLink prefix '73' # invalid MAVLink prefix '13' - #errprinter('mav recv error:', e) + # errprinter('mav recv error:', e) msg = None except Exception as e: # Log any other unexpected exception diff --git a/dronekit/test/__init__.py b/dronekit/test/__init__.py index fa1442c74..04ad5353a 100644 --- a/dronekit/test/__init__.py +++ b/dronekit/test/__init__.py @@ -1,8 +1,7 @@ from __future__ import print_function import os -import sys from dronekit_sitl import SITL -from nose.tools import assert_equals, with_setup +from nose.tools import with_setup import time sitl = None @@ -13,21 +12,25 @@ if 'SITL_RATE' in os.environ: sitl_args += ['-r', str(os.environ['SITL_RATE'])] + def setup_sitl(): global sitl sitl = SITL() sitl.download('copter', '3.3') sitl.launch(sitl_args, await_ready=True, restart=True) + def teardown_sitl(): sitl.stop() + def with_sitl(fn): @with_setup(setup_sitl, teardown_sitl) def test(*args, **kargs): return fn('tcp:127.0.0.1:5760', *args, **kargs) return test + def wait_for(condition, time_max): time_start = time.time() while not condition(): diff --git a/dronekit/test/sitl/__init__.py b/dronekit/test/sitl/__init__.py index 8b1378917..e69de29bb 100644 --- a/dronekit/test/sitl/__init__.py +++ b/dronekit/test/sitl/__init__.py @@ -1 +0,0 @@ - diff --git a/dronekit/test/sitl/test_110.py b/dronekit/test/sitl/test_110.py index 9ab32c6c0..43ed92135 100644 --- a/dronekit/test/sitl/test_110.py +++ b/dronekit/test/sitl/test_110.py @@ -1,6 +1,4 @@ import time -import sys -import os from dronekit import connect, VehicleMode from dronekit.test import with_sitl, wait_for from nose.tools import assert_equals @@ -17,7 +15,7 @@ def test_110(connpath): vehicle.parameters['FS_EKF_THRESH'] = 100 # Await armability. - wait_for(lambda : vehicle.is_armable, 60) + wait_for(lambda: vehicle.is_armable, 60) # Change the vehicle into STABILIZE mode vehicle.mode = VehicleMode("GUIDED") @@ -44,7 +42,7 @@ def armed_callback(vehicle, attribute, value): # Wait for ACK. time_max = 10 - wait_for(lambda : armed_callback.called, time_max) + wait_for(lambda: armed_callback.called, time_max) # Ensure the callback was called. assert armed_callback.called > 0, "Callback should have been called within %d seconds" % (time_max,) diff --git a/dronekit/test/sitl/test_115.py b/dronekit/test/sitl/test_115.py index 28f4a3f11..ae17d4a11 100644 --- a/dronekit/test/sitl/test_115.py +++ b/dronekit/test/sitl/test_115.py @@ -1,6 +1,4 @@ import time -import sys -import os from dronekit import connect, VehicleMode from dronekit.test import with_sitl from nose.tools import assert_equals diff --git a/dronekit/test/sitl/test_12.py b/dronekit/test/sitl/test_12.py index d2c55a15c..c30e30b0b 100644 --- a/dronekit/test/sitl/test_12.py +++ b/dronekit/test/sitl/test_12.py @@ -1,7 +1,5 @@ import time -import sys -import os -from dronekit import connect, VehicleMode +from dronekit import connect from dronekit.test import with_sitl from nose.tools import assert_equals diff --git a/dronekit/test/sitl/test_capability_and_version.py b/dronekit/test/sitl/test_capability_and_version.py index 1aa1cd531..cae0a0c45 100644 --- a/dronekit/test/sitl/test_capability_and_version.py +++ b/dronekit/test/sitl/test_capability_and_version.py @@ -1,6 +1,6 @@ import time -from dronekit import VehicleMode, connect +from dronekit import connect from dronekit.test import with_sitl from nose.tools import assert_false, assert_true @@ -15,11 +15,9 @@ def test_115(connpath): # flags before they are initialised. Vehicle attempts to refetch # until capabilities are non-zero, but we may need to wait: start_time = time.time() - nonzero_capabilities = True slept = False while v.capabilities.mission_float == 0: if time.time() > start_time + 30: - nonzero_capabilities = False break time.sleep(0.1) slept = True diff --git a/dronekit/test/sitl/test_channels.py b/dronekit/test/sitl/test_channels.py index f3f02b1fa..a23d536a2 100644 --- a/dronekit/test/sitl/test_channels.py +++ b/dronekit/test/sitl/test_channels.py @@ -1,8 +1,7 @@ -from pymavlink import mavutil import time -from dronekit import connect, VehicleMode, LocationGlobal +from dronekit import connect from dronekit.test import with_sitl -from nose.tools import assert_equals, assert_not_equals +from nose.tools import assert_equals def assert_readback(vehicle, values): @@ -63,7 +62,7 @@ def test_timeout(connpath): vehicle.channels.overrides['1'] = None assert_readback(vehicle, {'1': 1500, '2': 1500}) - #test + # test try: vehicle.channels['9'] assert False, "Can read over end of channels" diff --git a/dronekit/test/sitl/test_earlyattrs.py b/dronekit/test/sitl/test_earlyattrs.py index 91ec2c97b..3d48a1140 100644 --- a/dronekit/test/sitl/test_earlyattrs.py +++ b/dronekit/test/sitl/test_earlyattrs.py @@ -1,8 +1,4 @@ -import time -import sys -import os -import socket -from dronekit import connect, VehicleMode +from dronekit import connect from dronekit.test import with_sitl from nose.tools import assert_equals, assert_not_equals diff --git a/dronekit/test/sitl/test_locations.py b/dronekit/test/sitl/test_locations.py index 326b62b8b..be48cc7a6 100644 --- a/dronekit/test/sitl/test_locations.py +++ b/dronekit/test/sitl/test_locations.py @@ -1,5 +1,5 @@ import time -from dronekit import connect, VehicleMode, LocationGlobal +from dronekit import connect, VehicleMode from dronekit.test import with_sitl, wait_for from nose.tools import assert_equals, assert_not_equals @@ -20,17 +20,17 @@ def arm_and_takeoff(aTargetAltitude): """ # Don't let the user try to fly autopilot is booting - wait_for(lambda : vehicle.is_armable, 60) + wait_for(lambda: vehicle.is_armable, 60) assert_equals(vehicle.is_armable, True) # Copter should arm in GUIDED mode vehicle.mode = VehicleMode("GUIDED") - wait_for(lambda : vehicle.mode.name == 'GUIDED', 60) + wait_for(lambda: vehicle.mode.name == 'GUIDED', 60) assert_equals(vehicle.mode.name, 'GUIDED') # Arm copter. vehicle.armed = True - wait_for(lambda : vehicle.armed, 60) + wait_for(lambda: vehicle.armed, 60) assert_equals(vehicle.armed, True) # Take off to target altitude @@ -80,7 +80,7 @@ def callback(*args): assert_not_equals(args[2].alt, 0) ret['success'] = True - wait_for(lambda : ret['success'], 30) + wait_for(lambda: ret['success'], 30) assert ret['success'], 'Expected location object to emit notifications.' diff --git a/dronekit/test/sitl/test_mavlink.py b/dronekit/test/sitl/test_mavlink.py index 6ddf2d442..006240981 100644 --- a/dronekit/test/sitl/test_mavlink.py +++ b/dronekit/test/sitl/test_mavlink.py @@ -1,9 +1,7 @@ import time -import math from dronekit import connect from dronekit.mavlink import MAVConnection from dronekit.test import with_sitl -from nose.tools import assert_not_equals, assert_equals @with_sitl diff --git a/dronekit/test/sitl/test_mode_settings.py b/dronekit/test/sitl/test_mode_settings.py index 95392c36e..7c777f7ac 100644 --- a/dronekit/test/sitl/test_mode_settings.py +++ b/dronekit/test/sitl/test_mode_settings.py @@ -1,5 +1,3 @@ -import time -import math from dronekit import connect from dronekit.test import with_sitl from nose.tools import assert_equals diff --git a/dronekit/test/sitl/test_modeavailable.py b/dronekit/test/sitl/test_modeavailable.py index 2796f7ad3..f95298f69 100644 --- a/dronekit/test/sitl/test_modeavailable.py +++ b/dronekit/test/sitl/test_modeavailable.py @@ -2,22 +2,19 @@ Simple test to trigger a bug in Vehicle class: issue #610 fixed in PR #611 """ -import time -import sys -import os -from dronekit import connect, VehicleMode +from dronekit import connect from dronekit.test import with_sitl -from nose.tools import assert_equals + @with_sitl def test_timeout(connpath): v = connect(connpath) - + # Set the vehicle and autopilot type to 'unsupported' types that MissionPlanner uses as of 17.Apr.2016 v._vehicle_type = 6 v._autopilot_type = 8 # The above types trigger 'TypeError: argument of type 'NoneType' is not iterable' which is addressed in issue #610 - is_available = v._is_mode_available(0) + v._is_mode_available(0) v.close() diff --git a/dronekit/test/sitl/test_parameters.py b/dronekit/test/sitl/test_parameters.py index cb7d2f4bb..bdfc5c3b8 100644 --- a/dronekit/test/sitl/test_parameters.py +++ b/dronekit/test/sitl/test_parameters.py @@ -1,7 +1,5 @@ import time -import sys -import os -from dronekit import connect, VehicleMode +from dronekit import connect from dronekit.test import with_sitl from nose.tools import assert_equals, assert_not_equals diff --git a/dronekit/test/sitl/test_simpledemo.py b/dronekit/test/sitl/test_simpledemo.py index 0f8319d12..d79dda11b 100644 --- a/dronekit/test/sitl/test_simpledemo.py +++ b/dronekit/test/sitl/test_simpledemo.py @@ -3,9 +3,6 @@ Feel free to copy and modify at your leisure. """ -import time -import sys -import os from dronekit import connect, VehicleMode from dronekit.test import with_sitl from nose.tools import assert_equals diff --git a/dronekit/test/sitl/test_state.py b/dronekit/test/sitl/test_state.py index 850f9da58..b53889548 100644 --- a/dronekit/test/sitl/test_state.py +++ b/dronekit/test/sitl/test_state.py @@ -1,8 +1,4 @@ -import time -import sys -import os -import socket -from dronekit import connect, VehicleMode, SystemStatus +from dronekit import connect, SystemStatus from dronekit.test import with_sitl from nose.tools import assert_equals diff --git a/dronekit/test/sitl/test_timeout.py b/dronekit/test/sitl/test_timeout.py index d36b78ca1..11b99baf1 100644 --- a/dronekit/test/sitl/test_timeout.py +++ b/dronekit/test/sitl/test_timeout.py @@ -1,8 +1,6 @@ import time -import sys -import os import socket -from dronekit import connect, VehicleMode +from dronekit import connect from dronekit.test import with_sitl from nose.tools import assert_equals diff --git a/dronekit/test/sitl/test_vehicleclass.py b/dronekit/test/sitl/test_vehicleclass.py index b7d386eed..ddc1054be 100644 --- a/dronekit/test/sitl/test_vehicleclass.py +++ b/dronekit/test/sitl/test_vehicleclass.py @@ -1,7 +1,6 @@ import time from dronekit import connect, Vehicle from dronekit.test import with_sitl -from nose.tools import assert_equals class DummyVehicle(Vehicle): diff --git a/dronekit/test/sitl/test_waypoints.py b/dronekit/test/sitl/test_waypoints.py index 288509b98..af594ca1b 100644 --- a/dronekit/test/sitl/test_waypoints.py +++ b/dronekit/test/sitl/test_waypoints.py @@ -1,6 +1,5 @@ import time -import math -from dronekit import connect, VehicleMode, LocationGlobal, Command +from dronekit import connect, LocationGlobal, Command from pymavlink import mavutil from dronekit.test import with_sitl from nose.tools import assert_not_equals, assert_equals diff --git a/dronekit/test/unit/__init__.py b/dronekit/test/unit/__init__.py index 8b1378917..e69de29bb 100644 --- a/dronekit/test/unit/__init__.py +++ b/dronekit/test/unit/__init__.py @@ -1 +0,0 @@ - diff --git a/dronekit/test/unit/test_api.py b/dronekit/test/unit/test_api.py index a7224e4a8..1ce8190dd 100644 --- a/dronekit/test/unit/test_api.py +++ b/dronekit/test/unit/test_api.py @@ -1,5 +1,3 @@ -import mock -from mock import MagicMock from dronekit import VehicleMode from nose.tools import assert_equals, assert_not_equals diff --git a/dronekit/util.py b/dronekit/util.py index 081ffd2be..f72166b67 100644 --- a/dronekit/util.py +++ b/dronekit/util.py @@ -5,6 +5,7 @@ def errprinter(*args): logger(*args) + def logger(*args): print(*args, file=sys.stderr) sys.stderr.flush() From cede8e090a7f444ba3ae43667298cdcdc3d42680 Mon Sep 17 00:00:00 2001 From: pietrodn Date: Mon, 5 Nov 2018 19:01:40 +0100 Subject: [PATCH 434/475] Avoid pinning requirements to specific version (#872) --- requirements.txt | 4 ++-- setup.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements.txt b/requirements.txt index 7b67b3550..18f64c791 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ pymavlink>=2.2.20 monotonic>=1.3 future>=0.15.2 -nose==1.3.7 -mock==2.0.0 +nose>=1.3.7 +mock>=2.0.0 dronekit-sitl==3.2.0 sphinx-3dr-theme>=0.4.3 diff --git a/setup.py b/setup.py index 8b4805b32..a31072480 100644 --- a/setup.py +++ b/setup.py @@ -12,8 +12,8 @@ author='3D Robotics', install_requires=[ 'pymavlink>=2.2.20', - 'monotonic==1.2', - 'future==0.15.2' + 'monotonic>=1.2', + 'future>=0.15.2' ], author_email='tim@3drobotics.com, kevinh@geeksville.com', classifiers=[ From 8f97dd99a5db8d430c87dd9939d7db67437fee32 Mon Sep 17 00:00:00 2001 From: pietrodn Date: Sun, 4 Nov 2018 09:50:33 +0100 Subject: [PATCH 435/475] Logging: use builting logging module, not print() Deprecate status_printer and log STATUSTEXT messages on a separate logger with the correct severity. Improved exception logging with stack traces in the log where necessary. --- dronekit/__init__.py | 86 ++++++++++++++++++++++++++------------------ dronekit/mavlink.py | 44 +++++++++++++---------- 2 files changed, 76 insertions(+), 54 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 17dbf2090..3b5bf80f5 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -25,6 +25,8 @@ It is also possible to work with vehicle "missions" using the :py:attr:`Vehicle.commands` attribute, and run them in AUTO mode. +All the logging is handled through the builtin Python `logging` module. + A number of other useful classes and methods are listed below. ---- @@ -33,15 +35,13 @@ from __future__ import print_function import collections import copy +import logging import math import struct -import re -import sys import time import monotonic from past.builtins import basestring -from dronekit.util import errprinter from pymavlink import mavutil, mavwp from pymavlink.dialects.v10 import ardupilotmega @@ -531,6 +531,8 @@ def __ne__(self, other): class HasObservers(object): def __init__(self): + self._logger = logging.getLogger(__name__) + # A mapping from attr_name to a list of observers self._attribute_listeners = {} self._attribute_cache = {} @@ -639,18 +641,14 @@ def notify_attribute_listeners(self, attr_name, value, cache=False): for fn in self._attribute_listeners.get(attr_name, []): try: fn(self, attr_name, value) - except Exception as e: - errprinter('>>> Exception in attribute handler for %s' % - attr_name) - errprinter('>>> ' + str(e)) + except Exception: + self._logger.exception('Exception in attribute handler for %s' % attr_name, exc_info=True) for fn in self._attribute_listeners.get('*', []): try: fn(self, attr_name, value) - except Exception as e: - errprinter('>>> Exception in attribute handler for %s' % - attr_name) - errprinter('>>> ' + str(e)) + except Exception: + self._logger.exception('Exception in attribute handler for %s' % attr_name, exc_info=True) def on_attribute(self, name): """ @@ -987,6 +985,15 @@ class Vehicle(HasObservers): It is also possible to work with vehicle "missions" using the :py:attr:`commands` attribute, and run them in AUTO mode. + STATUSTEXT log messages from the autopilot are handled through a separate logger. + It is possible to configure the log level, the formatting, etc. by accessing the logger, e.g.: + + .. code-block:: python + + import logging + autopilot_logger = logging.getLogger('autopilot') + autopilot_logger.setLevel(logging.DEBUG) + The guide contains more detailed information on the different ways you can use the ``Vehicle`` class: @@ -1008,6 +1015,20 @@ class Vehicle(HasObservers): def __init__(self, handler): super(Vehicle, self).__init__() + self._logger = logging.getLogger(__name__) # Logger for DroneKit + self._autopilot_logger = logging.getLogger('autopilot') # Logger for the autopilot messages + # MAVLink-to-logging-module log severity mappings + self._mavlink_statustext_severity = { + 0: logging.CRITICAL, + 1: logging.CRITICAL, + 2: logging.CRITICAL, + 3: logging.ERROR, + 4: logging.WARNING, + 5: logging.INFO, + 6: logging.INFO, + 7: logging.DEBUG + } + self._handler = handler self._master = handler.master @@ -1034,6 +1055,14 @@ def listener(_, msg): self._vy = None self._vz = None + @self.on_message('STATUSTEXT') + def statustext_listener(self, name, m): + # Log the STATUSTEXT on the autopilot logger, with the correct severity + self._autopilot_logger.log( + msg=m.text.strip(), + level=self._mavlink_statustext_severity[m.severity] + ) + @self.on_message('GLOBAL_POSITION_INT') def listener(self, name, m): (self._vx, self._vy, self._vz) = (m.vx / 100.0, m.vy / 100.0, m.vz / 100.0) @@ -1340,8 +1369,7 @@ def listener(_): self._heartbeat_error) elif monotonic.monotonic() - self._heartbeat_lastreceived > self._heartbeat_warning: if self._heartbeat_timeout is False: - errprinter('>>> Link timeout, no heartbeat in last %s seconds' % - self._heartbeat_warning) + self._logger.warning('Link timeout, no heartbeat in last %s seconds' % self._heartbeat_warning) self._heartbeat_timeout = True @self.on_message(['HEARTBEAT']) @@ -1352,7 +1380,7 @@ def listener(self, name, msg): self._heartbeat_system = msg.get_srcSystem() self._heartbeat_lastreceived = monotonic.monotonic() if self._heartbeat_timeout: - errprinter('>>> ...link restored.') + self._logger.info('...link restored.') self._heartbeat_timeout = False self._last_heartbeat = None @@ -1499,18 +1527,14 @@ def notify_message_listeners(self, name, msg): for fn in self._message_listeners.get(name, []): try: fn(self, name, msg) - except Exception as e: - errprinter('>>> Exception in message handler for %s' % - msg.get_type()) - errprinter('>>> ' + str(e)) + except Exception: + self._logger.exception('Exception in message handler for %s' % msg.get_type(), exc_info=True) for fn in self._message_listeners.get('*', []): try: fn(self, name, msg) - except Exception as e: - errprinter('>>> Exception in message handler for %s' % - msg.get_type()) - errprinter('>>> ' + str(e)) + except Exception: + self._logger.exception('Exception in message handler for %s' % msg.get_type(), exc_info=True) def close(self): return self._handler.close() @@ -2572,6 +2596,7 @@ class Parameters(collections.MutableMapping, HasObservers): def __init__(self, vehicle): super(Parameters, self).__init__() + self._logger = logging.getLogger(__name__) self._vehicle = vehicle def __getitem__(self, name): @@ -2624,7 +2649,7 @@ def set(self, name, value, retries=3, wait_ready=False): time.sleep(0.1) if retries > 0: - errprinter("timeout setting parameter %s to %f" % (name, value)) + self._logger.error("timeout setting parameter %s to %f" % (name, value)) return False def wait_ready(self, **kwargs): @@ -2936,8 +2961,7 @@ def __setitem__(self, index, value): def default_still_waiting_callback(atts): - print("Still waiting for data from vehicle: %s" % ','.join(atts), - file=sys.stderr) + logging.getLogger(__name__).debug("Still waiting for data from vehicle: %s" % ','.join(atts)) def connect(ip, @@ -2946,7 +2970,7 @@ def connect(ip, timeout=30, still_waiting_callback=default_still_waiting_callback, still_waiting_interval=1, - status_printer=errprinter, + status_printer=None, vehicle_class=None, rate=4, baud=115200, @@ -2978,9 +3002,7 @@ def connect(ip, For more information see :py:func:`Vehicle.wait_ready `. - :param status_printer: Method of signature ``def status_printer(txt)`` that prints - STATUS_TEXT messages from the Vehicle and other diagnostic information. - By default the status information is printed to the command prompt in which the script is running. + :param status_printer: deprecated and unused (STATUSTEXT messages are directed to their own logger) :param Vehicle vehicle_class: The class that will be instantiated by the ``connect()`` method. This can be any sub-class of ``Vehicle`` (and defaults to ``Vehicle``). :param int rate: Data stream refresh rate. The default is 4Hz (4 updates per second). @@ -3012,12 +3034,6 @@ def connect(ip, handler = MAVConnection(ip, baud=baud, source_system=source_system, use_native=use_native) vehicle = vehicle_class(handler) - if status_printer: - - @vehicle.on_message('STATUSTEXT') - def listener(self, name, m): - status_printer(re.sub(r'(^|\n)', '>>> ', m.text.rstrip())) - if _initialize: vehicle.initialize(rate=rate, heartbeat_timeout=heartbeat_timeout) diff --git a/dronekit/mavlink.py b/dronekit/mavlink.py index a38bde1c5..514f7f7a1 100644 --- a/dronekit/mavlink.py +++ b/dronekit/mavlink.py @@ -1,4 +1,6 @@ from __future__ import print_function + +import logging import time import socket import errno @@ -7,7 +9,6 @@ import platform import copy from dronekit import APIException -from dronekit.util import errprinter from pymavlink import mavutil from queue import Queue, Empty from threading import Thread @@ -25,22 +26,24 @@ class MAVWriter(object): """ def __init__(self, queue): + self._logger = logging.getLogger(__name__) self.queue = queue def write(self, pkt): self.queue.put(pkt) def read(self): - errprinter('writer should not have had a read request') + self._logger.critical('writer should not have had a read request') os._exit(43) class mavudpin_multi(mavutil.mavfile): '''a UDP mavlink socket''' def __init__(self, device, baud=None, input=True, broadcast=False, source_system=255, use_native=mavutil.default_native): + self._logger = logging.getLogger(__name__) a = device.split(':') if len(a) != 2: - print("UDP ports must be specified as host:port") + self._logger.critical("UDP ports must be specified as host:port") sys.exit(1) self.port = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.udp_server = input @@ -73,8 +76,8 @@ def recv(self, n=None): elif self.broadcast: self.addresses = {new_addr} return data - except Exception as e: - print(e) + except Exception: + self._logger.exception("Exception while reading data", exc_info=True) def write(self, buf): try: @@ -90,8 +93,8 @@ def write(self, buf): self.port.sendto(buf, self.destination_addr) except socket.error: pass - except Exception as e: - print(e) + except Exception: + self._logger.exception("Exception while writing data", exc_info=True) def recv_msg(self): '''message receive routine for UDP link''' @@ -119,6 +122,8 @@ def stop_threads(self): self.mavlink_thread_out = None def __init__(self, ip, baud=115200, target_system=0, source_system=255, use_native=False): + self._logger = logging.getLogger(__name__) + if ip.startswith("udpin:"): self.master = mavudpin_multi(ip[6:], input=True, baud=baud, source_system=source_system) else: @@ -176,10 +181,10 @@ def mavlink_thread_out(): raise APIException('Connection aborting during read') raise except Exception as e: - errprinter('>>> mav send error:', e) + self._logger.exception('mav send error: %s' % str(e)) break except APIException as e: - errprinter('>>> ' + str(e)) + self._logger.exception("Exception in MAVLink write loop", exc_info=True) self._alive = False self.master.close() self._death_error = e @@ -219,11 +224,11 @@ def mavlink_thread_in(): # Avoid # invalid MAVLink prefix '73' # invalid MAVLink prefix '13' - # errprinter('mav recv error:', e) + self._logger.debug('mav recv error: %s' % str(e)) msg = None - except Exception as e: + except Exception: # Log any other unexpected exception - errprinter('>>> Exception while receiving message: ', e) + self._logger.exception('Exception while receiving message: ', exc_info=True) msg = None if not msg: break @@ -232,13 +237,14 @@ def mavlink_thread_in(): for fn in self.message_listeners: try: fn(self, msg) - except Exception as e: - errprinter('>>> Exception in message handler for %s' % - msg.get_type()) - errprinter('>>> ' + str(e)) + except Exception: + self._logger.exception( + 'Exception in message handler for %s' % msg.get_type(), + exc_info=True + ) except APIException as e: - errprinter('>>> ' + str(e)) + self._logger.exception('Exception in MAVLink input loop') self._alive = False self.master.close() self._death_error = e @@ -316,7 +322,7 @@ def callback(_, msg): assert len(msg.get_msgbuf()) > 0 target.out_queue.put(msg.get_msgbuf()) except: - errprinter('>>> Could not pack this object on receive: %s' % type(msg)) + self._logger.exception('Could not pack this object on receive: %s' % type(msg), exc_info=True) # target -> self -> vehicle @target.forward_message @@ -330,6 +336,6 @@ def callback(_, msg): assert len(msg.get_msgbuf()) > 0 self.out_queue.put(msg.get_msgbuf()) except: - errprinter('>>> Could not pack this object on forward: %s' % type(msg)) + self._logger.exception('Could not pack this object on forward: %s' % type(msg), exc_info=True) return target From f786a6323191ab1fe0cf252111262287ff511adb Mon Sep 17 00:00:00 2001 From: pietrodn Date: Sat, 10 Nov 2018 11:21:54 +0100 Subject: [PATCH 436/475] Backwards compatibility for status_printer Add test for status_printer support --- dronekit/__init__.py | 13 ++++++++-- dronekit/test/sitl/test_errprinter.py | 34 +++++++++++++++++++++++++++ dronekit/util.py | 14 +++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 dronekit/test/sitl/test_errprinter.py diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 3b5bf80f5..6c207297b 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -32,7 +32,6 @@ ---- """ -from __future__ import print_function import collections import copy import logging @@ -46,6 +45,8 @@ from pymavlink import mavutil, mavwp from pymavlink.dialects.v10 import ardupilotmega +from dronekit.util import ErrprinterHandler + class APIException(Exception): """ @@ -3002,7 +3003,9 @@ def connect(ip, For more information see :py:func:`Vehicle.wait_ready `. - :param status_printer: deprecated and unused (STATUSTEXT messages are directed to their own logger) + :param status_printer: (deprecated) method of signature ``def status_printer(txt)`` that prints + STATUS_TEXT messages from the Vehicle and other diagnostic information. + By default the status information is handled by the ``autopilot`` logger. :param Vehicle vehicle_class: The class that will be instantiated by the ``connect()`` method. This can be any sub-class of ``Vehicle`` (and defaults to ``Vehicle``). :param int rate: Data stream refresh rate. The default is 4Hz (4 updates per second). @@ -3022,6 +3025,9 @@ def connect(ip, It is *good practice* to assign a unique id for every system on the MAVLink network. It is possible to configure the autopilot to only respond to guided-mode commands from a specified GCS ID. + The ``status_printer`` argument is deprecated. To redirect the logging from the library and from the + autopilot, configure the ``dronekit`` and ``autopilot`` loggers using the Python ``logging`` module. + :returns: A connected vehicle of the type defined in ``vehicle_class`` (a superclass of :py:class:`Vehicle`). """ @@ -3034,6 +3040,9 @@ def connect(ip, handler = MAVConnection(ip, baud=baud, source_system=source_system, use_native=use_native) vehicle = vehicle_class(handler) + if status_printer: + vehicle._autopilot_logger.addHandler(ErrprinterHandler(status_printer)) + if _initialize: vehicle.initialize(rate=rate, heartbeat_timeout=heartbeat_timeout) diff --git a/dronekit/test/sitl/test_errprinter.py b/dronekit/test/sitl/test_errprinter.py new file mode 100644 index 000000000..ce14c0af2 --- /dev/null +++ b/dronekit/test/sitl/test_errprinter.py @@ -0,0 +1,34 @@ +import logging +import time + +from nose.tools import assert_true + +from dronekit import connect +from dronekit.test import with_sitl + + +@with_sitl +def test_115(connpath): + """Provide a custom status_printer function to the Vehicle and check that + the autopilot messages are correctly logged. + """ + + logging_check = {'ok': False} + + def errprinter_fn(msg): + if isinstance(msg, str) and "APM:Copter" in msg: + logging_check['ok'] = True + + vehicle = connect(connpath, wait_ready=False, status_printer=errprinter_fn) + + i = 5 + while not logging_check['ok'] and i > 0: + time.sleep(1) + i -= 1 + + assert_true(logging_check['ok']) + vehicle.close() + + # Cleanup the logger + autopilotLogger = logging.getLogger('autopilot') + autopilotLogger.removeHandler(autopilotLogger.handlers[0]) diff --git a/dronekit/util.py b/dronekit/util.py index f72166b67..4b7bd43a6 100644 --- a/dronekit/util.py +++ b/dronekit/util.py @@ -1,4 +1,6 @@ from __future__ import print_function + +import logging import sys @@ -9,3 +11,15 @@ def errprinter(*args): def logger(*args): print(*args, file=sys.stderr) sys.stderr.flush() + + +class ErrprinterHandler(logging.Handler): + """Logging handler to support the deprecated `errprinter` argument to connect()""" + + def __init__(self, errprinter): + logging.Handler.__init__(self) + self.errprinter = errprinter + + def emit(self, record): + msg = self.format(record) + self.errprinter(msg) From c89175ac941d29f7e0f0b5d42f97f96ec268fd6d Mon Sep 17 00:00:00 2001 From: pietrodn Date: Wed, 14 Nov 2018 18:44:44 +0100 Subject: [PATCH 437/475] param_request_read_send wants bytes, not str --- dronekit/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 6c207297b..99e5c5c94 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1310,7 +1310,7 @@ def listener(_): c = 0 for i, v in enumerate(self._params_set): if v is None: - self._master.mav.param_request_read_send(0, 0, '', i) + self._master.mav.param_request_read_send(0, 0, b'', i) c += 1 if c > 50: break From 28d4fd336f1987f8db318239137f78b7b5e9ce4d Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 15 Nov 2018 17:37:58 +1100 Subject: [PATCH 438/475] Explain using native SITL with dk-sitl --- docs/develop/sitl_setup.rst | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/develop/sitl_setup.rst b/docs/develop/sitl_setup.rst index d9131a284..8da0c3871 100644 --- a/docs/develop/sitl_setup.rst +++ b/docs/develop/sitl_setup.rst @@ -29,7 +29,8 @@ the `project on Github `_. .. note:: - DroneKit-SITL is still relatively experimental and there are only a few pre-built vehicles. + DroneKit-SITL is still relatively experimental and there are only a few pre-built vehicles + (some of which are quite old and/or unstable). The binaries are built and tested on Windows 10, Ubuntu Linux, and Mac OS X "El Capitan". Binaries are only available for x86 architectures. ARM builds @@ -74,7 +75,13 @@ There are a number of other useful arguments: dronekit-sitl --reset #Delete all downloaded vehicle binaries. dronekit-sitl ./path [args...] #Start SITL instance at target file location. - + +.. note:: + + You can also use *dronekit-sitl* to start a SITL executable that you have built locally from source. + To do this, put the file path of the target executable in the `SITL_BINARY` environment variable, + or as the first argument when calling the tool. + .. _connecting_dronekit_sitl: From 8a44656737915a851e149f8592e12d5393a29ee5 Mon Sep 17 00:00:00 2001 From: Yuuya Fujiwara Date: Thu, 15 Nov 2018 16:39:08 +0900 Subject: [PATCH 439/475] mission import / export example : Displayed message changed, file names get from argument. --- examples/mission_import_export/mission_import_export.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/mission_import_export/mission_import_export.py b/examples/mission_import_export/mission_import_export.py index d0c77e04c..fc36e7f91 100644 --- a/examples/mission_import_export/mission_import_export.py +++ b/examples/mission_import_export/mission_import_export.py @@ -89,7 +89,7 @@ def upload_mission(aFileName): #Read mission from file missionlist = readmission(aFileName) - print("\nUpload mission from a file: %s" % import_mission_filename) + print("\nUpload mission from a file: %s" % aFileName) #Clear existing mission from vehicle print(' Clear mission') cmds = vehicle.commands @@ -120,7 +120,7 @@ def save_mission(aFileName): Save a mission in the Waypoint file format (http://qgroundcontrol.org/mavlink/waypoint_protocol#waypoint_file_format). """ - print("\nSave mission from Vehicle to file: %s" % export_mission_filename) + print("\nSave mission from Vehicle to file: %s" % aFileName) #Download mission from vehicle missionlist = download_mission() #Add file-format information From a80a9bdbcfd7b80ba60a9fa860478cb748a4de16 Mon Sep 17 00:00:00 2001 From: pietrodn Date: Sun, 18 Nov 2018 16:52:19 +0100 Subject: [PATCH 440/475] AppVeyor: test on multiple Python versions --- appveyor.yml | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 63fab30ca..b1996b573 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,10 +1,20 @@ environment: SITL_SPEEDUP: 10 SITL_RATE: 200 + PYTHONUNBUFFERED: 1 + + matrix: + - PYTHON: "C:\\Python27" + PYTHON_VERSION: "2.7" + - PYTHON: "C:\\Python37" + PYTHON_VERSION: "3.7" cache: - "c:\\Users\\appveyor\\.pip-wheelhouse" +init: + - cmd: "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" + install: - ps: | New-Item -ItemType Directory -Force -Path c:\Users\appveyor\pip\ @@ -15,17 +25,14 @@ install: [wheel] wheel-dir = c:/Users/appveyor/.pip-wheelhouse '@ | out-file -Encoding ascii -FilePath c:\Users\appveyor\pip\pip.ini - - - cmd: 'SET PATH=%PYTHON%;c:\\Python27\\Scripts;%PATH%' - - cmd: 'SET PYTHONUNBUFFERED=1' - - cmd: 'python -m pip install pip wheel -U' - cmd: 'pip install . -UI' - cmd: 'pip install -r requirements.txt -UI' -build_script: +build: off + +test_script: - cmd: 'nosetests -svx dronekit.test.unit' - cmd: 'nosetests -svx dronekit.test.sitl' clone_depth: 10 -test: 'off' From e412e95d24169c606edcd87fa1dc309af305eb0e Mon Sep 17 00:00:00 2001 From: Huibean Date: Thu, 20 Dec 2018 20:42:30 +0800 Subject: [PATCH 441/475] incase None > int in python3 --- dronekit/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 99e5c5c94..42d1a3991 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1775,7 +1775,7 @@ def is_armable(self): # check that mode is not INITIALSING # check that we have a GPS fix # check that EKF pre-arm is complete - return self.mode != 'INITIALISING' and self.gps_0.fix_type > 1 and self._ekf_predposhorizabs + return self.mode != 'INITIALISING' and (self.gps_0.fix_type is not None and self.gps_0.fix_type > 1) and self._ekf_predposhorizabs @property def system_status(self): From b448fd9c5a3aae58d5cc7c240288e2c226796d7d Mon Sep 17 00:00:00 2001 From: Huibean Date: Tue, 25 Dec 2018 13:00:51 +0800 Subject: [PATCH 442/475] add logging basic config --- dronekit/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 42d1a3991..01536e10c 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -532,6 +532,7 @@ def __ne__(self, other): class HasObservers(object): def __init__(self): + logging.basicConfig() self._logger = logging.getLogger(__name__) # A mapping from attr_name to a list of observers From e07328b2ec41c1864eb0e437ed97f74063956427 Mon Sep 17 00:00:00 2001 From: pietrodn Date: Sun, 18 Nov 2018 16:19:16 +0100 Subject: [PATCH 443/475] Add commands and tests for sensor calibration --- dronekit/__init__.py | 119 ++++++++++++++++++ dronekit/test/sitl/__init__.py | 47 +++++++ dronekit/test/sitl/test_sensor_calibration.py | 95 ++++++++++++++ 3 files changed, 261 insertions(+) create mode 100644 dronekit/test/sitl/test_sensor_calibration.py diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 01536e10c..74a8a6302 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -2398,6 +2398,125 @@ def reboot(self): self.send_mavlink(reboot_msg) + def calibrate_gyro(self): + """Request gyroscope calibration.""" + + calibration_command = self.message_factory.command_long_encode( + 0, 0, # target_system, target_component + mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, # command + 0, # confirmation + 1, # param 1, 1: gyro calibration, 3: gyro temperature calibration + 0, # param 2, 1: magnetometer calibration + 0, # param 3, 1: ground pressure calibration + 0, # param 4, 1: radio RC calibration, 2: RC trim calibration + 0, # param 5, 1: accelerometer calibration, 2: board level calibration, 3: accelerometer temperature calibration, 4: simple accelerometer calibration + 0, # param 6, 2: airspeed calibration + 0, # param 7, 1: ESC calibration, 3: barometer temperature calibration + ) + self.send_mavlink(calibration_command) + + def calibrate_magnetometer(self): + """Request magnetometer calibration.""" + + # APM requires the MAV_CMD_DO_START_MAG_CAL command, only present in the APM MAVLink dialect + if self._autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_ARDUPILOTMEGA: + calibration_command = self.message_factory.command_long_encode( + 0, 0, # target_system, target_component + mavutil.mavlink.MAV_CMD_DO_START_MAG_CAL, # command + 0, # confirmation + 0, # param 1, uint8_t bitmask of magnetometers (0 means all). + 1, # param 2, Automatically retry on failure (0=no retry, 1=retry). + 1, # param 3, Save without user input (0=require input, 1=autosave). + 0, # param 4, Delay (seconds). + 1, # param 5, Autoreboot (0=user reboot, 1=autoreboot). + 0, # param 6, Empty. + 0, # param 7, Empty. + ) + else: + calibration_command = self.message_factory.command_long_encode( + 0, 0, # target_system, target_component + mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, # command + 0, # confirmation + 0, # param 1, 1: gyro calibration, 3: gyro temperature calibration + 1, # param 2, 1: magnetometer calibration + 0, # param 3, 1: ground pressure calibration + 0, # param 4, 1: radio RC calibration, 2: RC trim calibration + 0, # param 5, 1: accelerometer calibration, 2: board level calibration, 3: accelerometer temperature calibration, 4: simple accelerometer calibration + 0, # param 6, 2: airspeed calibration + 0, # param 7, 1: ESC calibration, 3: barometer temperature calibration + ) + + self._logger.critical(calibration_command) + self.send_mavlink(calibration_command) + + def calibrate_accelerometer(self): + """Request accelerometer calibration.""" + + calibration_command = self.message_factory.command_long_encode( + 0, 0, # target_system, target_component + mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, # command + 0, # confirmation + 0, # param 1, 1: gyro calibration, 3: gyro temperature calibration + 0, # param 2, 1: magnetometer calibration + 0, # param 3, 1: ground pressure calibration + 0, # param 4, 1: radio RC calibration, 2: RC trim calibration + 1, # param 5, 1: accelerometer calibration, 2: board level calibration, 3: accelerometer temperature calibration, 4: simple accelerometer calibration + 0, # param 6, 2: airspeed calibration + 0, # param 7, 1: ESC calibration, 3: barometer temperature calibration + ) + self.send_mavlink(calibration_command) + + def calibrate_accelerometer_simple(self): + """Request simple accelerometer calibration.""" + + calibration_command = self.message_factory.command_long_encode( + 0, 0, # target_system, target_component + mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, # command + 0, # confirmation + 0, # param 1, 1: gyro calibration, 3: gyro temperature calibration + 0, # param 2, 1: magnetometer calibration + 0, # param 3, 1: ground pressure calibration + 0, # param 4, 1: radio RC calibration, 2: RC trim calibration + 4, # param 5, 1: accelerometer calibration, 2: board level calibration, 3: accelerometer temperature calibration, 4: simple accelerometer calibration + 0, # param 6, 2: airspeed calibration + 0, # param 7, 1: ESC calibration, 3: barometer temperature calibration + ) + self.send_mavlink(calibration_command) + + def calibrate_board_level(self): + """Request board level calibration.""" + + calibration_command = self.message_factory.command_long_encode( + 0, 0, # target_system, target_component + mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, # command + 0, # confirmation + 0, # param 1, 1: gyro calibration, 3: gyro temperature calibration + 0, # param 2, 1: magnetometer calibration + 0, # param 3, 1: ground pressure calibration + 0, # param 4, 1: radio RC calibration, 2: RC trim calibration + 2, # param 5, 1: accelerometer calibration, 2: board level calibration, 3: accelerometer temperature calibration, 4: simple accelerometer calibration + 0, # param 6, 2: airspeed calibration + 0, # param 7, 1: ESC calibration, 3: barometer temperature calibration + ) + self.send_mavlink(calibration_command) + + def calibrate_barometer(self): + """Request barometer calibration.""" + + calibration_command = self.message_factory.command_long_encode( + 0, 0, # target_system, target_component + mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, # command + 0, # confirmation + 0, # param 1, 1: gyro calibration, 3: gyro temperature calibration + 0, # param 2, 1: magnetometer calibration + 1, # param 3, 1: ground pressure calibration + 0, # param 4, 1: radio RC calibration, 2: RC trim calibration + 0, # param 5, 1: accelerometer calibration, 2: board level calibration, 3: accelerometer temperature calibration, 4: simple accelerometer calibration + 0, # param 6, 2: airspeed calibration + 0, # param 7, 1: ESC calibration, 3: barometer temperature calibration + ) + self.send_mavlink(calibration_command) + class Gimbal(object): """ diff --git a/dronekit/test/sitl/__init__.py b/dronekit/test/sitl/__init__.py index e69de29bb..51b3be828 100644 --- a/dronekit/test/sitl/__init__.py +++ b/dronekit/test/sitl/__init__.py @@ -0,0 +1,47 @@ +import time +from contextlib import contextmanager +from nose.tools import assert_equal +from pymavlink import mavutil + + +@contextmanager +def assert_command_ack( + vehicle, + command_type, + ack_result=mavutil.mavlink.MAV_RESULT_ACCEPTED, + timeout=10 +): + """Context manager to assert that: + + 1) exactly one COMMAND_ACK is received from a Vehicle; + 2) for a specific command type; + 3) with the given result; + 4) within a timeout (in seconds). + + For example: + + .. code-block:: python + + with assert_command_ack(vehicle, mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, timeout=30): + vehicle.calibrate_gyro() + + """ + + acks = [] + + def on_ack(self, name, message): + if message.command == command_type: + acks.append(message) + + vehicle.add_message_listener('COMMAND_ACK', on_ack) + + yield + + start_time = time.time() + while not acks and time.time() - start_time < timeout: + time.sleep(0.1) + vehicle.remove_message_listener('COMMAND_ACK', on_ack) + + assert_equal(1, len(acks)) # one and only one ACK + assert_equal(command_type, acks[0].command) # for the correct command + assert_equal(ack_result, acks[0].result) # the result must be successful diff --git a/dronekit/test/sitl/test_sensor_calibration.py b/dronekit/test/sitl/test_sensor_calibration.py new file mode 100644 index 000000000..76d51f2e9 --- /dev/null +++ b/dronekit/test/sitl/test_sensor_calibration.py @@ -0,0 +1,95 @@ +from pymavlink import mavutil + +from dronekit import connect +from dronekit.test import with_sitl + +from dronekit.test.sitl import assert_command_ack + + +@with_sitl +def test_gyro_calibration(connpath): + """Request gyroscope calibration, and check for the COMMAND_ACK.""" + + vehicle = connect(connpath, wait_ready=True) + + with assert_command_ack(vehicle, mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, timeout=30): + vehicle.calibrate_gyro() + + vehicle.close() + + +@with_sitl +def test_magnetometer_calibration(connpath): + """Request magnetometer calibration, and check for the COMMAND_ACK.""" + + vehicle = connect(connpath, wait_ready=True) + + with assert_command_ack( + vehicle, + mavutil.mavlink.MAV_CMD_DO_START_MAG_CAL, + timeout=30, + ack_result=mavutil.mavlink.MAV_RESULT_UNSUPPORTED, # TODO: change when APM is upgraded + ): + vehicle.calibrate_magnetometer() + + vehicle.close() + + +@with_sitl +def test_simple_accelerometer_calibration(connpath): + """Request simple accelerometer calibration, and check for the COMMAND_ACK.""" + + vehicle = connect(connpath, wait_ready=True) + + with assert_command_ack( + vehicle, + mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, + timeout=30, + ack_result=mavutil.mavlink.MAV_RESULT_FAILED, # TODO: change when APM is upgraded + ): + vehicle.calibrate_accelerometer_simple() + + vehicle.close() + + +@with_sitl +def test_accelerometer_calibration(connpath): + """Request accelerometer calibration, and check for the COMMAND_ACK.""" + + vehicle = connect(connpath, wait_ready=True) + + # The calibration is expected to fail because in the SITL we don't tilt the Vehicle. + # We just check that the command isn't denied or unsupported. + with assert_command_ack( + vehicle, + mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, + timeout=30, + ack_result=mavutil.mavlink.MAV_RESULT_FAILED, + ): + vehicle.calibrate_accelerometer() + + vehicle.close() + + +@with_sitl +def test_board_level_calibration(connpath): + """Request board level calibration, and check for the COMMAND_ACK.""" + + vehicle = connect(connpath, wait_ready=True) + + with assert_command_ack(vehicle, mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, timeout=30): + vehicle.calibrate_board_level() + + vehicle.close() + + +@with_sitl +def test_barometer_calibration(connpath): + """Request barometer calibration, and check for the COMMAND_ACK.""" + + vehicle = connect(connpath, wait_ready=True) + + with assert_command_ack(vehicle, mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, timeout=30): + vehicle.calibrate_barometer() + + vehicle.close() From 70822a52c39e440e3870b8c93c3291b0519c2139 Mon Sep 17 00:00:00 2001 From: pietrodn Date: Mon, 19 Nov 2018 08:34:34 +0100 Subject: [PATCH 444/475] Corrections --- dronekit/__init__.py | 38 ++++++------------- dronekit/test/sitl/test_sensor_calibration.py | 6 +-- 2 files changed, 15 insertions(+), 29 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 74a8a6302..57c732685 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -2402,7 +2402,7 @@ def calibrate_gyro(self): """Request gyroscope calibration.""" calibration_command = self.message_factory.command_long_encode( - 0, 0, # target_system, target_component + self._handler.target_system, 0, # target_system, target_component mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, # command 0, # confirmation 1, # param 1, 1: gyro calibration, 3: gyro temperature calibration @@ -2418,10 +2418,10 @@ def calibrate_gyro(self): def calibrate_magnetometer(self): """Request magnetometer calibration.""" - # APM requires the MAV_CMD_DO_START_MAG_CAL command, only present in the APM MAVLink dialect + # ArduPilot requires the MAV_CMD_DO_START_MAG_CAL command, only present in the ardupilotmega.xml definition if self._autopilot_type == mavutil.mavlink.MAV_AUTOPILOT_ARDUPILOTMEGA: calibration_command = self.message_factory.command_long_encode( - 0, 0, # target_system, target_component + self._handler.target_system, 0, # target_system, target_component mavutil.mavlink.MAV_CMD_DO_START_MAG_CAL, # command 0, # confirmation 0, # param 1, uint8_t bitmask of magnetometers (0 means all). @@ -2434,7 +2434,7 @@ def calibrate_magnetometer(self): ) else: calibration_command = self.message_factory.command_long_encode( - 0, 0, # target_system, target_component + self._handler.target_system, 0, # target_system, target_component mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, # command 0, # confirmation 0, # param 1, 1: gyro calibration, 3: gyro temperature calibration @@ -2449,35 +2449,21 @@ def calibrate_magnetometer(self): self._logger.critical(calibration_command) self.send_mavlink(calibration_command) - def calibrate_accelerometer(self): - """Request accelerometer calibration.""" - - calibration_command = self.message_factory.command_long_encode( - 0, 0, # target_system, target_component - mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, # command - 0, # confirmation - 0, # param 1, 1: gyro calibration, 3: gyro temperature calibration - 0, # param 2, 1: magnetometer calibration - 0, # param 3, 1: ground pressure calibration - 0, # param 4, 1: radio RC calibration, 2: RC trim calibration - 1, # param 5, 1: accelerometer calibration, 2: board level calibration, 3: accelerometer temperature calibration, 4: simple accelerometer calibration - 0, # param 6, 2: airspeed calibration - 0, # param 7, 1: ESC calibration, 3: barometer temperature calibration - ) - self.send_mavlink(calibration_command) + def calibrate_accelerometer(self, simple=False): + """Request accelerometer calibration. - def calibrate_accelerometer_simple(self): - """Request simple accelerometer calibration.""" + :param simple: if True, perform simple accelerometer calibration + """ calibration_command = self.message_factory.command_long_encode( - 0, 0, # target_system, target_component + self._handler.target_system, 0, # target_system, target_component mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, # command 0, # confirmation 0, # param 1, 1: gyro calibration, 3: gyro temperature calibration 0, # param 2, 1: magnetometer calibration 0, # param 3, 1: ground pressure calibration 0, # param 4, 1: radio RC calibration, 2: RC trim calibration - 4, # param 5, 1: accelerometer calibration, 2: board level calibration, 3: accelerometer temperature calibration, 4: simple accelerometer calibration + 4 if simple else 1, # param 5, 1: accelerometer calibration, 2: board level calibration, 3: accelerometer temperature calibration, 4: simple accelerometer calibration 0, # param 6, 2: airspeed calibration 0, # param 7, 1: ESC calibration, 3: barometer temperature calibration ) @@ -2487,7 +2473,7 @@ def calibrate_board_level(self): """Request board level calibration.""" calibration_command = self.message_factory.command_long_encode( - 0, 0, # target_system, target_component + self._handler.target_system, 0, # target_system, target_component mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, # command 0, # confirmation 0, # param 1, 1: gyro calibration, 3: gyro temperature calibration @@ -2504,7 +2490,7 @@ def calibrate_barometer(self): """Request barometer calibration.""" calibration_command = self.message_factory.command_long_encode( - 0, 0, # target_system, target_component + self._handler.target_system, 0, # target_system, target_component mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, # command 0, # confirmation 0, # param 1, 1: gyro calibration, 3: gyro temperature calibration diff --git a/dronekit/test/sitl/test_sensor_calibration.py b/dronekit/test/sitl/test_sensor_calibration.py index 76d51f2e9..de1a9c90e 100644 --- a/dronekit/test/sitl/test_sensor_calibration.py +++ b/dronekit/test/sitl/test_sensor_calibration.py @@ -45,9 +45,9 @@ def test_simple_accelerometer_calibration(connpath): vehicle, mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, timeout=30, - ack_result=mavutil.mavlink.MAV_RESULT_FAILED, # TODO: change when APM is upgraded + ack_result=mavutil.mavlink.MAV_RESULT_FAILED, ): - vehicle.calibrate_accelerometer_simple() + vehicle.calibrate_accelerometer(simple=True) vehicle.close() @@ -66,7 +66,7 @@ def test_accelerometer_calibration(connpath): timeout=30, ack_result=mavutil.mavlink.MAV_RESULT_FAILED, ): - vehicle.calibrate_accelerometer() + vehicle.calibrate_accelerometer(simple=False) vehicle.close() From 1ee6e4853cb2aba6f155b4ba0553520b5bd09a44 Mon Sep 17 00:00:00 2001 From: pietrodn Date: Sat, 24 Nov 2018 11:59:03 +0100 Subject: [PATCH 445/475] Rename calibrate_board_level -> calibrate_vehicle level; don't auto-reboot on mag calibration. --- dronekit/__init__.py | 6 +++--- dronekit/test/sitl/test_sensor_calibration.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 57c732685..92f70cfbe 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -2428,7 +2428,7 @@ def calibrate_magnetometer(self): 1, # param 2, Automatically retry on failure (0=no retry, 1=retry). 1, # param 3, Save without user input (0=require input, 1=autosave). 0, # param 4, Delay (seconds). - 1, # param 5, Autoreboot (0=user reboot, 1=autoreboot). + 0, # param 5, Autoreboot (0=user reboot, 1=autoreboot). 0, # param 6, Empty. 0, # param 7, Empty. ) @@ -2469,8 +2469,8 @@ def calibrate_accelerometer(self, simple=False): ) self.send_mavlink(calibration_command) - def calibrate_board_level(self): - """Request board level calibration.""" + def calibrate_vehicle_level(self): + """Request vehicle level (accelerometer trim) calibration.""" calibration_command = self.message_factory.command_long_encode( self._handler.target_system, 0, # target_system, target_component diff --git a/dronekit/test/sitl/test_sensor_calibration.py b/dronekit/test/sitl/test_sensor_calibration.py index de1a9c90e..a9bcf13fb 100644 --- a/dronekit/test/sitl/test_sensor_calibration.py +++ b/dronekit/test/sitl/test_sensor_calibration.py @@ -78,7 +78,7 @@ def test_board_level_calibration(connpath): vehicle = connect(connpath, wait_ready=True) with assert_command_ack(vehicle, mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, timeout=30): - vehicle.calibrate_board_level() + vehicle.calibrate_vehicle_level() vehicle.close() From e4314dedb81a84d5b2b1df13ffefa856c97b5aa7 Mon Sep 17 00:00:00 2001 From: pietrodn Date: Sat, 24 Nov 2018 12:27:48 +0100 Subject: [PATCH 446/475] Remove extraneous logging line --- dronekit/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 92f70cfbe..e381baff2 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -2446,7 +2446,6 @@ def calibrate_magnetometer(self): 0, # param 7, 1: ESC calibration, 3: barometer temperature calibration ) - self._logger.critical(calibration_command) self.send_mavlink(calibration_command) def calibrate_accelerometer(self, simple=False): From c3cfa7fab0b78273d9af88bc4f8c6a9f80001b8d Mon Sep 17 00:00:00 2001 From: pietrodn Date: Mon, 31 Dec 2018 09:21:51 +0100 Subject: [PATCH 447/475] Rename "calibrate_*" to "send_calibrate_*" (non-blocking methods) --- dronekit/__init__.py | 10 +++++----- dronekit/test/sitl/test_sensor_calibration.py | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index e381baff2..99b91f42d 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -2398,7 +2398,7 @@ def reboot(self): self.send_mavlink(reboot_msg) - def calibrate_gyro(self): + def send_calibrate_gyro(self): """Request gyroscope calibration.""" calibration_command = self.message_factory.command_long_encode( @@ -2415,7 +2415,7 @@ def calibrate_gyro(self): ) self.send_mavlink(calibration_command) - def calibrate_magnetometer(self): + def send_calibrate_magnetometer(self): """Request magnetometer calibration.""" # ArduPilot requires the MAV_CMD_DO_START_MAG_CAL command, only present in the ardupilotmega.xml definition @@ -2448,7 +2448,7 @@ def calibrate_magnetometer(self): self.send_mavlink(calibration_command) - def calibrate_accelerometer(self, simple=False): + def send_calibrate_accelerometer(self, simple=False): """Request accelerometer calibration. :param simple: if True, perform simple accelerometer calibration @@ -2468,7 +2468,7 @@ def calibrate_accelerometer(self, simple=False): ) self.send_mavlink(calibration_command) - def calibrate_vehicle_level(self): + def send_calibrate_vehicle_level(self): """Request vehicle level (accelerometer trim) calibration.""" calibration_command = self.message_factory.command_long_encode( @@ -2485,7 +2485,7 @@ def calibrate_vehicle_level(self): ) self.send_mavlink(calibration_command) - def calibrate_barometer(self): + def send_calibrate_barometer(self): """Request barometer calibration.""" calibration_command = self.message_factory.command_long_encode( diff --git a/dronekit/test/sitl/test_sensor_calibration.py b/dronekit/test/sitl/test_sensor_calibration.py index a9bcf13fb..d80aa2343 100644 --- a/dronekit/test/sitl/test_sensor_calibration.py +++ b/dronekit/test/sitl/test_sensor_calibration.py @@ -13,7 +13,7 @@ def test_gyro_calibration(connpath): vehicle = connect(connpath, wait_ready=True) with assert_command_ack(vehicle, mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, timeout=30): - vehicle.calibrate_gyro() + vehicle.send_calibrate_gyro() vehicle.close() @@ -30,7 +30,7 @@ def test_magnetometer_calibration(connpath): timeout=30, ack_result=mavutil.mavlink.MAV_RESULT_UNSUPPORTED, # TODO: change when APM is upgraded ): - vehicle.calibrate_magnetometer() + vehicle.send_calibrate_magnetometer() vehicle.close() @@ -47,7 +47,7 @@ def test_simple_accelerometer_calibration(connpath): timeout=30, ack_result=mavutil.mavlink.MAV_RESULT_FAILED, ): - vehicle.calibrate_accelerometer(simple=True) + vehicle.send_calibrate_accelerometer(simple=True) vehicle.close() @@ -66,7 +66,7 @@ def test_accelerometer_calibration(connpath): timeout=30, ack_result=mavutil.mavlink.MAV_RESULT_FAILED, ): - vehicle.calibrate_accelerometer(simple=False) + vehicle.send_calibrate_accelerometer(simple=False) vehicle.close() @@ -78,7 +78,7 @@ def test_board_level_calibration(connpath): vehicle = connect(connpath, wait_ready=True) with assert_command_ack(vehicle, mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, timeout=30): - vehicle.calibrate_vehicle_level() + vehicle.send_calibrate_vehicle_level() vehicle.close() @@ -90,6 +90,6 @@ def test_barometer_calibration(connpath): vehicle = connect(connpath, wait_ready=True) with assert_command_ack(vehicle, mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION, timeout=30): - vehicle.calibrate_barometer() + vehicle.send_calibrate_barometer() vehicle.close() From e51de971f67d4f154aefb671d8233f095bbed36f Mon Sep 17 00:00:00 2001 From: huibean Date: Wed, 9 Jan 2019 12:49:10 +0800 Subject: [PATCH 448/475] add MOUNT_ORIENTATION support --- dronekit/__init__.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 99b91f42d..b9bfbe015 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -2542,6 +2542,13 @@ def listener(vehicle, name, m): self._yaw = m.pointing_c / 100.0 vehicle.notify_attribute_listeners('gimbal', vehicle.gimbal) + @vehicle.on_message('MOUNT_ORIENTATION') + def listener(vehicle, name, m): + self._pitch = m.pitch + self._roll = m.roll + self._yaw = m.yaw + vehicle.notify_attribute_listeners('gimbal', vehicle.gimbal) + @property def pitch(self): """ From ed132cce3588b5a9b0fa93e50f255a284fb8a0f7 Mon Sep 17 00:00:00 2001 From: Yuuya Fujiwara Date: Fri, 25 Jan 2019 08:44:09 +0900 Subject: [PATCH 449/475] revise URL in comment. --- examples/create_attribute/my_vehicle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/create_attribute/my_vehicle.py b/examples/create_attribute/my_vehicle.py index 01f12cea1..9b129f937 100644 --- a/examples/create_attribute/my_vehicle.py +++ b/examples/create_attribute/my_vehicle.py @@ -17,7 +17,7 @@ class RawIMU(object): The RAW IMU readings for the usual 9DOF sensor setup. This contains the true raw values without any scaling to allow data capture and system debugging. - The message definition is here: https://pixhawk.ethz.ch/mavlink/#RAW_IMU + The message definition is here: https://mavlink.io/en/messages/common.html#RAW_IMU :param time_boot_us: Timestamp (microseconds since system boot). #Note, not milliseconds as per spec :param xacc: X acceleration (mg) From 22ae381f188167d45157b574993bdaaf80778658 Mon Sep 17 00:00:00 2001 From: Afsoon Afzal Date: Thu, 31 Jan 2019 15:42:23 -0500 Subject: [PATCH 450/475] Set a timeout for uploading missions --- dronekit/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index b9bfbe015..0de761bb4 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -3009,7 +3009,7 @@ def add(self, cmd): self._vehicle._wploader.add(cmd, comment='Added by DroneKit') self._vehicle._wpts_dirty = True - def upload(self): + def upload(self, timeout=None): """ Call ``upload()`` after :py:func:`adding ` or :py:func:`clearing ` mission commands. @@ -3018,10 +3018,13 @@ def upload(self): """ if self._vehicle._wpts_dirty: self._vehicle._master.waypoint_clear_all_send() + start_time = time.time() if self._vehicle._wploader.count() > 0: self._vehicle._wp_uploaded = [False] * self._vehicle._wploader.count() self._vehicle._master.waypoint_count_send(self._vehicle._wploader.count()) while False in self._vehicle._wp_uploaded: + if timeout and time.time() - start_time > timeout: + raise TimeoutError time.sleep(0.1) self._vehicle._wp_uploaded = None self._vehicle._wpts_dirty = False From 0eb7715bd9392c36e8ab6901a4546ae20c424918 Mon Sep 17 00:00:00 2001 From: Afsoon Afzal Date: Thu, 31 Jan 2019 15:43:54 -0500 Subject: [PATCH 451/475] updating the comment --- dronekit/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 0de761bb4..37c66de0d 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -3015,6 +3015,8 @@ def upload(self, timeout=None): After the return from ``upload()`` any writes are guaranteed to have completed (or thrown an exception) and future reads will see their effects. + + :param int timeout: The timeout for uploading the mission. No timeout if not provided or set to None. """ if self._vehicle._wpts_dirty: self._vehicle._master.waypoint_clear_all_send() From 4ea3b9f274ac3cf99b6ca91f6a8ae62a8ea01f7b Mon Sep 17 00:00:00 2001 From: Jaime Machuca Date: Fri, 8 Feb 2019 16:20:19 -0700 Subject: [PATCH 452/475] Add Source Component ID parameter to connect function to allow setting a different comp ID than 0. Default to 0 to make it backwards compatible. --- dronekit/__init__.py | 4 +++- dronekit/mavlink.py | 11 ++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 37c66de0d..b6ff96227 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -3094,6 +3094,7 @@ def connect(ip, baud=115200, heartbeat_timeout=30, source_system=255, + source_component=0, use_native=False): """ Returns a :py:class:`Vehicle` object connected to the address specified by string parameter ``ip``. @@ -3130,6 +3131,7 @@ def connect(ip, :param int heartbeat_timeout: Connection timeout value in seconds (default is 30s). If a heartbeat is not detected within this time an exception will be raised. :param int source_system: The MAVLink ID of the :py:class:`Vehicle` object returned by this method (by default 255). + :param int source_component: The MAVLink Component ID fo the :py:class:`Vehicle` object returned by this method (by default 0). :param bool use_native: Use precompiled MAVLink parser. .. note:: @@ -3154,7 +3156,7 @@ def connect(ip, if not vehicle_class: vehicle_class = Vehicle - handler = MAVConnection(ip, baud=baud, source_system=source_system, use_native=use_native) + handler = MAVConnection(ip, baud=baud, source_system=source_system, source_component=source_component, use_native=use_native) vehicle = vehicle_class(handler) if status_printer: diff --git a/dronekit/mavlink.py b/dronekit/mavlink.py index 514f7f7a1..d87f93ae5 100644 --- a/dronekit/mavlink.py +++ b/dronekit/mavlink.py @@ -39,7 +39,7 @@ def read(self): class mavudpin_multi(mavutil.mavfile): '''a UDP mavlink socket''' - def __init__(self, device, baud=None, input=True, broadcast=False, source_system=255, use_native=mavutil.default_native): + def __init__(self, device, baud=None, input=True, broadcast=False, source_system=255, source_component=0, use_native=mavutil.default_native): self._logger = logging.getLogger(__name__) a = device.split(':') if len(a) != 2: @@ -59,7 +59,7 @@ def __init__(self, device, baud=None, input=True, broadcast=False, source_system self.broadcast = True mavutil.set_close_on_exec(self.port.fileno()) self.port.setblocking(False) - mavutil.mavfile.__init__(self, self.port.fileno(), device, source_system=source_system, input=input, use_native=use_native) + mavutil.mavfile.__init__(self, self.port.fileno(), device, source_system=source_system, source_component=source_component, input=input, use_native=use_native) def close(self): self.port.close() @@ -121,13 +121,13 @@ def stop_threads(self): self.mavlink_thread_out.join() self.mavlink_thread_out = None - def __init__(self, ip, baud=115200, target_system=0, source_system=255, use_native=False): + def __init__(self, ip, baud=115200, target_system=0, source_system=255, source_component=0, use_native=False): self._logger = logging.getLogger(__name__) if ip.startswith("udpin:"): - self.master = mavudpin_multi(ip[6:], input=True, baud=baud, source_system=source_system) + self.master = mavudpin_multi(ip[6:], input=True, baud=baud, source_system=source_system, source_component=source_component) else: - self.master = mavutil.mavlink_connection(ip, baud=baud, source_system=source_system) + self.master = mavutil.mavlink_connection(ip, baud=baud, source_system=source_system, source_component=source_component) # TODO get rid of "master" object as exposed, # keep it private, expose something smaller for dronekit @@ -135,6 +135,7 @@ def __init__(self, ip, baud=115200, target_system=0, source_system=255, use_nati self.master.mav = mavutil.mavlink.MAVLink( MAVWriter(self.out_queue), srcSystem=self.master.source_system, + srcComponent=self.master.source_component, use_native=use_native) # Monkey-patch MAVLink object for fix_targets. From 4a70a08a40600e41af2caeba2f9a9cfe698a9c87 Mon Sep 17 00:00:00 2001 From: pietrodn Date: Sun, 30 Dec 2018 12:56:23 +0100 Subject: [PATCH 453/475] setup.py, requirements.txt, README.md improvements - future is not a direct dependency of dronekit: remove it - README.md: Python 3-compatible "Hello World" - PyPI badge: link to the package page on PyPI - setup.py: add classifier for Python 3 - setup.py: install monotonic only for Python<3.3 - setup.py: automatically discover packages with setuptools --- README.md | 6 +++--- requirements.txt | 1 - setup.py | 56 +++++++++++++++++++++++------------------------- 3 files changed, 30 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 057eef556..014fc2dbb 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![dronekit_python_logo](https://cloud.githubusercontent.com/assets/5368500/10805537/90dd4b14-7e22-11e5-9592-5925348a7df9.png) -![PyPi published version](https://img.shields.io/pypi/v/dronekit.svg) +[![PyPi published version](https://img.shields.io/pypi/v/dronekit.svg)](https://pypi.org/project/dronekit/) [![Windows Build status](https://img.shields.io/appveyor/ci/3drobotics/dronekit-python/master.svg?label=windows)](https://ci.appveyor.com/project/3drobotics/dronekit-python/branch/master) [![OS X Build Status](https://img.shields.io/travis/dronekit/dronekit-python/master.svg?label=os%20x)](https://travis-ci.org/dronekit/dronekit-python) [![Linux Build Status](https://img.shields.io/circleci/project/dronekit/dronekit-python/master.svg?label=linux)](https://circleci.com/gh/dronekit/dronekit-python) @@ -25,12 +25,12 @@ The [Quick Start](http://python.dronekit.io/guide/quick_start.html) guide explai A basic script looks like this: ```python -from dronekit import connect, VehicleMode +from dronekit import connect # Connect to UDP endpoint. vehicle = connect('127.0.0.1:14550', wait_ready=True) # Use returned Vehicle object to query device state - e.g. to get the mode: -print " Mode: %s" % vehicle.mode.name +print("Mode: %s" % vehicle.mode.name) ``` Once you've got DroneKit set up, the [guide](http://python.dronekit.io/guide/index.html) explains how to perform operations like taking off and flying the vehicle. You can also try out most of the tasks by running the [examples](http://python.dronekit.io/examples/index.html). diff --git a/requirements.txt b/requirements.txt index 18f64c791..9e70c79bb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,5 @@ pymavlink>=2.2.20 monotonic>=1.3 -future>=0.15.2 nose>=1.3.7 mock>=2.0.0 dronekit-sitl==3.2.0 diff --git a/setup.py b/setup.py index a31072480..235d2cfb2 100644 --- a/setup.py +++ b/setup.py @@ -1,32 +1,30 @@ -from setuptools import setup, Extension -import platform +import setuptools version = '2.9.1' -setup(name='dronekit', - zip_safe=True, - version=version, - description='Developer Tools for Drones.', - long_description='Python API for communication and control of drones over MAVLink.', - url='https://github.com/dronekit/dronekit-python', - author='3D Robotics', - install_requires=[ - 'pymavlink>=2.2.20', - 'monotonic>=1.2', - 'future>=0.15.2' - ], - author_email='tim@3drobotics.com, kevinh@geeksville.com', - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Environment :: Console', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: Apache Software License', - 'Operating System :: OS Independent', - 'Programming Language :: Python :: 2.7', - 'Topic :: Scientific/Engineering', - ], - license='apache', - packages=[ - 'dronekit', 'dronekit.test' - ], - ext_modules=[]) +setuptools.setup( + name='dronekit', + zip_safe=True, + version=version, + description='Developer Tools for Drones.', + long_description='Python API for communication and control of drones over MAVLink.', + url='https://github.com/dronekit/dronekit-python', + author='3D Robotics', + install_requires=[ + 'pymavlink>=2.2.20', + 'monotonic>=1.3 ; python_version<"3.3"', + ], + author_email='tim@3drobotics.com, kevinh@geeksville.com', + classifiers=[ + 'Development Status :: 5 - Production/Stable', + 'Environment :: Console', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: Apache Software License', + 'Operating System :: OS Independent', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Topic :: Scientific/Engineering', + ], + license='apache', + packages=setuptools.find_packages() +) From fa5530c172a6cb3ef9b63b8ea539f7947a8aef29 Mon Sep 17 00:00:00 2001 From: pietrodn Date: Sun, 30 Dec 2018 13:34:27 +0100 Subject: [PATCH 454/475] monotonic is actually needed --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 235d2cfb2..cc24953f8 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ author='3D Robotics', install_requires=[ 'pymavlink>=2.2.20', - 'monotonic>=1.3 ; python_version<"3.3"', + 'monotonic>=1.3', ], author_email='tim@3drobotics.com, kevinh@geeksville.com', classifiers=[ From f85f9cb64a1cf34c02c6d1a16fbf1cee62d9f368 Mon Sep 17 00:00:00 2001 From: Dr Nic Williams Date: Wed, 13 Feb 2019 12:01:32 +1000 Subject: [PATCH 455/475] fix URL to mavproxy documentation New MAVProxy docs are at http://ardupilot.github.io/MAVProxy/html/getting_started/starting.html Signed-off-by: Dr Nic Williams --- docs/guide/connecting_vehicle.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/connecting_vehicle.rst b/docs/guide/connecting_vehicle.rst index 135e29d38..62faa7df1 100644 --- a/docs/guide/connecting_vehicle.rst +++ b/docs/guide/connecting_vehicle.rst @@ -80,7 +80,7 @@ The table below shows *connection strings* you can use for some of the more comm .. tip:: The strings above are the same as are used when connecting the MAVProxy GCS. For other options see the - `MAVProxy documentation `_. + `MAVProxy documentation `_. .. note:: From 10d79fa22ddaed701521d27df19794586b188aa7 Mon Sep 17 00:00:00 2001 From: deb0ch Date: Mon, 8 Jan 2018 10:29:22 +0100 Subject: [PATCH 456/475] improve set_attitude_target example --- .../set_attitude_target.py | 50 ++++++++++++------- 1 file changed, 33 insertions(+), 17 deletions(-) mode change 100644 => 100755 examples/set_attitude_target/set_attitude_target.py diff --git a/examples/set_attitude_target/set_attitude_target.py b/examples/set_attitude_target/set_attitude_target.py old mode 100644 new mode 100755 index c6ebd0ed3..c3f676f0e --- a/examples/set_attitude_target/set_attitude_target.py +++ b/examples/set_attitude_target/set_attitude_target.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- """ @@ -85,20 +84,18 @@ def arm_and_takeoff_nogps(aTargetAltitude): set_attitude(thrust = thrust) time.sleep(0.2) - -def set_attitude(roll_angle = 0.0, pitch_angle = 0.0, yaw_rate = 0.0, thrust = 0.5, duration = 0): - """ - Note that from AC3.3 the message should be re-sent every second (after about 3 seconds - with no message the velocity will drop back to zero). In AC3.2.1 and earlier the specified - velocity persists until it is canceled. The code below should work on either version - (sending the message multiple times does not cause problems). - """ - +def send_attitude_target(roll_angle = 0.0, pitch_angle = 0.0, + yaw_angle = None, yaw_rate = 0.0, use_yaw_rate = False, + thrust = 0.5): """ - The roll and pitch rate cannot be controllbed with rate in radian in AC3.4.4 or earlier, - so you must use quaternion to control the pitch and roll for those vehicles. + use_yaw_rate: the yaw can be controlled using yaw_angle OR yaw_rate. + When one is used, the other is ignored by Ardupilot. + thrust: 0 <= thrust <= 1, as a fraction of maximum vertical thrust. + Note that as of Copter 3.5, thrust = 0.5 triggers a special case in + the code for maintaining current altitude. """ - + if not use_yaw_rate and yaw_angle is None: + yaw_angle = vehicle.attitude.yaw # Thrust > 0.5: Ascend # Thrust == 0.5: Hold the altitude # Thrust < 0.5: Descend @@ -106,19 +103,38 @@ def set_attitude(roll_angle = 0.0, pitch_angle = 0.0, yaw_rate = 0.0, thrust = 0 0, # time_boot_ms 1, # Target system 1, # Target component - 0b00000000, # Type mask: bit 1 is LSB - to_quaternion(roll_angle, pitch_angle), # Quaternion + 0b00000000 if use_yaw_rate else 0b00000100, + to_quaternion(roll_angle, pitch_angle, yaw_angle), # Quaternion 0, # Body roll rate in radian 0, # Body pitch rate in radian - math.radians(yaw_rate), # Body yaw rate in radian + math.radians(yaw_rate), # Body yaw rate in radian/second thrust # Thrust ) vehicle.send_mavlink(msg) +def set_attitude(roll_angle = 0.0, pitch_angle = 0.0, + yaw_angle = None, yaw_rate = 0.0, use_yaw_rate = False, + thrust = 0.5, duration = 0): + """ + Note that from AC3.3 the message should be re-sent more often than every + second, as an ATTITUDE_TARGET order has a timeout of 1s. + In AC3.2.1 and earlier the specified attitude persists until it is canceled. + The code below should work on either version. + Sending the message multiple times is the recommended way. + """ + send_attitude_target(roll_angle, pitch_angle, + yaw_angle, yaw_rate, False, + thrust) start = time.time() while time.time() - start < duration: - vehicle.send_mavlink(msg) + send_attitude_target(roll_angle, pitch_angle, + yaw_angle, yaw_rate, False, + thrust) time.sleep(0.1) + # Reset attitude, or it will persist for 1s more due to the timeout + send_attitude_target(0, 0, + 0, 0, True, + thrust) def to_quaternion(roll = 0.0, pitch = 0.0, yaw = 0.0): """ From 119689e29cb7cc6d98796a19f0e8548db63c0e97 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Thu, 14 Mar 2019 16:28:00 +1100 Subject: [PATCH 457/475] examples: set_attitude_target: avoid use of None in to_quaternion --- examples/set_attitude_target/set_attitude_target.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/set_attitude_target/set_attitude_target.py b/examples/set_attitude_target/set_attitude_target.py index c3f676f0e..d182637b1 100755 --- a/examples/set_attitude_target/set_attitude_target.py +++ b/examples/set_attitude_target/set_attitude_target.py @@ -94,7 +94,8 @@ def send_attitude_target(roll_angle = 0.0, pitch_angle = 0.0, Note that as of Copter 3.5, thrust = 0.5 triggers a special case in the code for maintaining current altitude. """ - if not use_yaw_rate and yaw_angle is None: + if yaw_angle is None: + # this value may be unused by the vehicle, depending on use_yaw_rate yaw_angle = vehicle.attitude.yaw # Thrust > 0.5: Ascend # Thrust == 0.5: Hold the altitude From 3cd8bdebd53ef90ec1062e561b4dae91b92b9886 Mon Sep 17 00:00:00 2001 From: mohamed ali rashad Date: Tue, 5 Mar 2019 15:11:07 +0200 Subject: [PATCH 458/475] Adding README to PyPi & minimizing imports Adding the README as a long description in PyPi and minimizing the setuptools import to only setup and find_packages --- setup.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index cc24953f8..5b3e90e78 100644 --- a/setup.py +++ b/setup.py @@ -1,13 +1,17 @@ import setuptools +import os version = '2.9.1' +with open(os.path.join(os.path.dirname(__file__), 'README.md')) as f: + LongDescription = f.read() + setuptools.setup( name='dronekit', zip_safe=True, version=version, description='Developer Tools for Drones.', - long_description='Python API for communication and control of drones over MAVLink.', + long_description=LongDescription, url='https://github.com/dronekit/dronekit-python', author='3D Robotics', install_requires=[ From 8d4495ad134fd3ee88c0e4f9f9bc42577d76ed58 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Thu, 14 Mar 2019 16:58:50 +1100 Subject: [PATCH 459/475] Release 2.9.2 notes and version bump --- CHANGELOG.md | 26 ++++++++++++++++++++++++++ setup.py | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21331ab2e..ca542f26a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,31 @@ # Changelog + +## Version 2.9.2 (2019-03-18) + +### Improvements +* CI integration improvements +* Python3 compatability +* use logging module +* log statustexts +* documentation improvements +* convenience functions added: wait_for, wait_for_armable, arm, disarm, wait_for_mode, wait_for_alt, wait_simple_takeoff +* play_tune method added +* reboot method added +* send_calibrate_gyro, send_calibrate_magnetometer, send_calibrate_magnetometer, send_calibrate_vehicle_level, send_calibrate_barometer all added +* update gimbal orientation from MOUNT_ORIENTATION +* add a still-waiting callback for connect() to provide debug on where the connection is up to +* several new tests added (including, play_tune, reboot and set_attitude_target) + +### Cleanup +* flake8 compliance improvements +* test includes pruned +* examples cleaned up + +### Bug Fixes +* ignore GCS heartbeats for the purposes of link up +* many! + ## Version 2.9.1 (2017-04-21) ### Improvements diff --git a/setup.py b/setup.py index 5b3e90e78..7bcb37b50 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ import setuptools import os -version = '2.9.1' +version = '2.9.2' with open(os.path.join(os.path.dirname(__file__), 'README.md')) as f: LongDescription = f.read() From 91c147fa61f521f5fff5d0cee06d07ed93614af8 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Tue, 19 Mar 2019 09:54:36 +1100 Subject: [PATCH 460/475] setup.py: add long_description_content_type --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 7bcb37b50..49d7477e2 100644 --- a/setup.py +++ b/setup.py @@ -11,6 +11,7 @@ zip_safe=True, version=version, description='Developer Tools for Drones.', + long_description_content_type="text/markdown", long_description=LongDescription, url='https://github.com/dronekit/dronekit-python', author='3D Robotics', From f54efe20df0f5ac015b4ec3ef88584d859726a7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Dvo=C5=99=C3=A1k?= Date: Tue, 25 Jun 2019 22:37:27 +0200 Subject: [PATCH 461/475] change of mavlink message name. --- dronekit/__init__.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index b6ff96227..76b1dadd3 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1142,12 +1142,12 @@ def listener(vehicle, name, m): # All keys are strings. self._channels = Channels(self, 8) - @self.on_message('RC_CHANNELS_RAW') + @self.on_message('RC_CHANNELS') def listener(self, name, m): def set_rc(chnum, v): '''Private utility for handling rc channel messages''' # use port to allow ch nums greater than 8 - self._channels._update_channel(str(m.port * 8 + chnum), v) + self._channels._update_channel(str(0 * 8 + chnum), v) set_rc(1, m.chan1_raw) set_rc(2, m.chan2_raw) @@ -1157,6 +1157,16 @@ def set_rc(chnum, v): set_rc(6, m.chan6_raw) set_rc(7, m.chan7_raw) set_rc(8, m.chan8_raw) + set_rc(9, m.chan9_raw) + set_rc(10, m.chan10_raw) + set_rc(11, m.chan11_raw) + set_rc(12, m.chan12_raw) + set_rc(13, m.chan13_raw) + set_rc(14, m.chan14_raw) + set_rc(15, m.chan15_raw) + set_rc(16, m.chan16_raw) + set_rc(17, m.chan17_raw) + set_rc(18, m.chan18_raw) self.notify_attribute_listeners('channels', self.channels) self._voltage = None @@ -2544,7 +2554,7 @@ def listener(vehicle, name, m): @vehicle.on_message('MOUNT_ORIENTATION') def listener(vehicle, name, m): - self._pitch = m.pitch + self._pitch = m.pitch self._roll = m.roll self._yaw = m.yaw vehicle.notify_attribute_listeners('gimbal', vehicle.gimbal) From bf5004aaa06e3456d442adcccd69a5a2a7d7d5ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Dvo=C5=99=C3=A1k?= Date: Wed, 26 Jun 2019 07:28:08 +0200 Subject: [PATCH 462/475] support for booth messages - RC_CHANNELS ad RC_CHANNELS_RAW., clean code. --- dronekit/__init__.py | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 76b1dadd3..200f15272 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1142,31 +1142,18 @@ def listener(vehicle, name, m): # All keys are strings. self._channels = Channels(self, 8) + @self.on_message('RC_CHANNELS_RAW') @self.on_message('RC_CHANNELS') def listener(self, name, m): def set_rc(chnum, v): '''Private utility for handling rc channel messages''' # use port to allow ch nums greater than 8 - self._channels._update_channel(str(0 * 8 + chnum), v) - - set_rc(1, m.chan1_raw) - set_rc(2, m.chan2_raw) - set_rc(3, m.chan3_raw) - set_rc(4, m.chan4_raw) - set_rc(5, m.chan5_raw) - set_rc(6, m.chan6_raw) - set_rc(7, m.chan7_raw) - set_rc(8, m.chan8_raw) - set_rc(9, m.chan9_raw) - set_rc(10, m.chan10_raw) - set_rc(11, m.chan11_raw) - set_rc(12, m.chan12_raw) - set_rc(13, m.chan13_raw) - set_rc(14, m.chan14_raw) - set_rc(15, m.chan15_raw) - set_rc(16, m.chan16_raw) - set_rc(17, m.chan17_raw) - set_rc(18, m.chan18_raw) + port = 0 if name == "RC_CHANNELS" else m.port + self._channels._update_channel(str(port * 8 + chnum), v) + + for i in range(1, (18 if name == "RC_CHANNELS" else 8)+1): + set_rc(i, getattr(m, "chan{}_raw".format(i))) + self.notify_attribute_listeners('channels', self.channels) self._voltage = None From cfb0a9d38e2ef13a5715faea0150f4d2f5b94de1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Dvo=C5=99=C3=A1k?= Date: Wed, 26 Jun 2019 08:56:56 +0200 Subject: [PATCH 463/475] message names in list --- dronekit/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 200f15272..4f3613906 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1142,8 +1142,7 @@ def listener(vehicle, name, m): # All keys are strings. self._channels = Channels(self, 8) - @self.on_message('RC_CHANNELS_RAW') - @self.on_message('RC_CHANNELS') + @self.on_message(['RC_CHANNELS_RAW', 'RC_CHANNELS']) def listener(self, name, m): def set_rc(chnum, v): '''Private utility for handling rc channel messages''' From 86d1af472709f2a204cbbb9ec143f5f2a29d43c4 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 5 Jul 2019 10:33:08 +1000 Subject: [PATCH 464/475] Fix up links to point to readthedos --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 014fc2dbb..616ac31f7 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ The API is primarily intended for use in onboard companion computers (to support ## Getting Started -The [Quick Start](http://python.dronekit.io/guide/quick_start.html) guide explains how to set up DroneKit on each of the supported platforms (Linux, Mac OSX, Windows) and how to write a script to connect to a vehicle (real or simulated). +The [Quick Start](https://dronekit-python.readthedocs.io/en/latest/guide/quick_start.html) guide explains how to set up DroneKit on each of the supported platforms (Linux, Mac OSX, Windows) and how to write a script to connect to a vehicle (real or simulated). A basic script looks like this: @@ -33,19 +33,19 @@ vehicle = connect('127.0.0.1:14550', wait_ready=True) print("Mode: %s" % vehicle.mode.name) ``` -Once you've got DroneKit set up, the [guide](http://python.dronekit.io/guide/index.html) explains how to perform operations like taking off and flying the vehicle. You can also try out most of the tasks by running the [examples](http://python.dronekit.io/examples/index.html). +Once you've got DroneKit set up, the [guide](https://dronekit-python.readthedocs.io/en/latest/guide/index.html) explains how to perform operations like taking off and flying the vehicle. You can also try out most of the tasks by running the [examples](https://dronekit-python.readthedocs.io/en/latest/examples/index.html). ## Resources -The project documentation is available at [python.dronekit.io](http://python.dronekit.io/). This includes [guide](http://python.dronekit.io/guide/index.html), [example](http://python.dronekit.io/examples/index.html) and [API Reference](http://python.dronekit.io/automodule.html) material. +The project documentation is available at [https://readthedocs.org/projects/dronekit-python/](https://readthedocs.org/projects/dronekit-python/). This includes [guide](https://dronekit-python.readthedocs.io/en/latest/guide/index.html), [example](https://dronekit-python.readthedocs.io/en/latest/examples/index.html) and [API Reference](https://dronekit-python.readthedocs.io/en/latest/automodule.html) material. The example source code is hosted here on Github as sub-folders of [/dronekit-python/examples](https://github.com/dronekit/dronekit-python/tree/master/examples). The [DroneKit Forums](http://discuss.dronekit.io) are the best place to ask for technical support on how to use the library. You can also check out our [Gitter channel](https://gitter.im/dronekit/dronekit-python?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) though we prefer posts on the forums where possible. -* **Documentation:** [http://python.dronekit.io/](http://python.dronekit.io/) -* **Guides:** [http://python.dronekit.io/guide/index.html](http://python.dronekit.io/guide/index.html) -* **API Reference:** [http://python.dronekit.io/automodule.html](http://python.dronekit.io/automodule.html) +* **Documentation:** [https://dronekit-python.readthedocs.io/en/latest/about/index.html](https://dronekit-python.readthedocs.io/en/latest/about/index.html) +* **Guides:** [https://dronekit-python.readthedocs.io/en/latest/guide/index.html) +* **API Reference:** [https://dronekit-python.readthedocs.io/en/latest/automodule.html) * **Examples:** [/dronekit-python/examples](https://github.com/dronekit/dronekit-python/tree/master/examples) * **Forums:** [http://discuss.dronekit.io/](http://discuss.dronekit.io) * **Gitter:** [https://gitter.im/dronekit/dronekit-python](https://gitter.im/dronekit/dronekit-python?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) though we prefer posts on the forums where possible. @@ -57,7 +57,7 @@ We'd love your [feedback and suggestions](https://github.com/dronekit/dronekit-p If you've created some awesome software that uses this project, [let us know on the forums here](https://discuss.dronekit.io/t/notable-projects-using-dronekit/230)! -If you want to contribute, see our [Contributing](http://python.dronekit.io/contributing/index.html) guidelines, we welcome all types of contributions but mostly contributions that would help us shrink our [issues list](https://github.com/dronekit/dronekit-python/issues). +If you want to contribute, see our [Contributing](https://dronekit-python.readthedocs.io/en/latest/contributing/index.html) guidelines, we welcome all types of contributions but mostly contributions that would help us shrink our [issues list](https://github.com/dronekit/dronekit-python/issues). ## Licence From fe6c62313831c7d4847ae8009af3f6400aea8c5e Mon Sep 17 00:00:00 2001 From: Ross Higa Date: Tue, 12 Nov 2019 12:00:50 -1000 Subject: [PATCH 465/475] Fixed error in code comments The serial example code said it was for a UDP endpoint --- docs/guide/connecting_vehicle.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/connecting_vehicle.rst b/docs/guide/connecting_vehicle.rst index 62faa7df1..af2d68fc2 100644 --- a/docs/guide/connecting_vehicle.rst +++ b/docs/guide/connecting_vehicle.rst @@ -33,7 +33,7 @@ Connecting over a serial device will look something like this: from dronekit import connect - # Connect to the Vehicle (in this case a UDP endpoint) + # Connect to the Vehicle (in this case a serial endpoint) vehicle = connect('/dev/ttyAMA0', wait_ready=True, baud=57600) .. tip:: From bdb20fb028862dc268a8b870917c80c97d93545a Mon Sep 17 00:00:00 2001 From: Pietro De Nicolao Date: Thu, 2 Jul 2020 19:28:56 +0200 Subject: [PATCH 466/475] docs: Python 3 is supported Using `sudo` is actually a bad idea --- docs/develop/installation.rst | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/develop/installation.rst b/docs/develop/installation.rst index 97b0229a8..f063bf069 100644 --- a/docs/develop/installation.rst +++ b/docs/develop/installation.rst @@ -5,7 +5,7 @@ Installing DroneKit =================== DroneKit-Python can be installed on a Linux, Mac OSX, or Windows computer that -has *Python 2.7* and can install Python packages from the Internet. +has Python 2.7 or Python 3 installed and can install Python packages from the Internet. It is installed from **pip** on all platforms: @@ -16,11 +16,13 @@ It is installed from **pip** on all platforms: **Installation notes:** -* Mac and Linux require you prefix the command with ``sudo``. +* Install `dronekit` with `pip` inside a virtualenv: .. code-block:: bash - sudo pip install dronekit + python3 -m venv .venv + . .venv/bin/activate + pip install dronekit * On Linux you may need to first install **pip** and **python-dev**: @@ -28,11 +30,11 @@ It is installed from **pip** on all platforms: sudo apt-get install python-pip python-dev - Alternatively, the *easy_install* tool provides another way to install pip: + Alternatively, you can use the `ensurepip` module to install or upgrade Pip on Python 3: .. code-block:: bash - sudo easy_install pip + python -m ensurepip --upgrade * :doc:`companion-computers` are likely to run on stripped down versions of Linux. Ensure you use a variant that supports Python 2.7 and can install Python packages from the Internet. @@ -43,4 +45,4 @@ It is installed from **pip** on all platforms: * `WinPython 2.7 64bit `_ (see `these instructions for installation and registration `_). This is the most tested version. * `ActiveState ActivePython 2.7 `_. -* Python 3 is not supported. +* Python 3 is fully supported. From 27b292b8eb32e465a3682e84bab3a56fb83bba0c Mon Sep 17 00:00:00 2001 From: Pietro De Nicolao Date: Fri, 3 Jul 2020 10:49:13 +0200 Subject: [PATCH 467/475] docs: ensurepip also works for Python 2.7 --- docs/develop/installation.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/develop/installation.rst b/docs/develop/installation.rst index f063bf069..bcfe09f64 100644 --- a/docs/develop/installation.rst +++ b/docs/develop/installation.rst @@ -30,7 +30,8 @@ It is installed from **pip** on all platforms: sudo apt-get install python-pip python-dev - Alternatively, you can use the `ensurepip` module to install or upgrade Pip on Python 3: + Alternatively, you can use the `ensurepip` module to install or upgrade Pip on your system: + .. code-block:: bash From 253eb45ca28519f2d9864bed90489bd1c821ec9d Mon Sep 17 00:00:00 2001 From: ogent Date: Mon, 15 Feb 2021 23:59:03 +0000 Subject: [PATCH 468/475] wind stats --- dronekit/__init__.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 4f3613906..0c5fc16e3 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -220,6 +220,25 @@ def __str__(self): return "GPSInfo:fix=%s,num_sat=%s" % (self.fix_type, self.satellites_visible) +class Wind(object): + """ + Wind information + + An object of this type is returned by :py:attr: `Vehicle.wind`. + + :param wind_direction: Wind direction in degrees + :param wind_speed: Wind speed in m/s + :param wind_speed_z: vertical wind speed in m/s + """ + def __init__(self, wind_direction, wind_speed, wind_speed_z): + self.wind_direction = wind_direction + self.wind_speed = wind_speed + self.wind_speed_z = wind_speed_z + + def __str__(self): + return "Wind: wind direction: {}, wind speed: {}, wind speed z: {}".format(self.wind_direction, self.wind_speed, self.wind_speed_z) + + class Battery(object): """ System battery information. @@ -1057,6 +1076,19 @@ def listener(_, msg): self._vy = None self._vz = None + + self._wind_direction = None + self._wind_speed = None + self._wind_speed_z = None + + @self.on_message('WIND') + def listener(self,name, m): + """ WIND {direction : -180.0, speed : 0.0, speed_z : 0.0} """ + self._wind_direction = m.direction + self._wind_speed = m.speed + self._wind_speed_z = m.speed_z + + @self.on_message('STATUSTEXT') def statustext_listener(self, name, m): # Log the STATUSTEXT on the autopilot logger, with the correct severity @@ -1678,6 +1710,13 @@ def listener(self, attr_name, value): """ return self._location + @property + def wind(self): + """ + Current wind status (:pu:class: `Wind`) + """ + return Wind(self._wind_direction, self._wind_speed, self._wind_speed_z) + @property def battery(self): """ From c7143e0ba94d414416fd36679fd3306ce31a7e69 Mon Sep 17 00:00:00 2001 From: ogent Date: Fri, 19 Feb 2021 00:38:56 +0000 Subject: [PATCH 469/475] wind property, return none if attributes are none --- dronekit/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index 0c5fc16e3..e4a45bd40 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1715,6 +1715,8 @@ def wind(self): """ Current wind status (:pu:class: `Wind`) """ + if self._wind_direction is None or self._wind_speed is None or self._wind_speed_z is None: + return None return Wind(self._wind_direction, self._wind_speed, self._wind_speed_z) @property From 1d89e82807ce543bae5e36426641b717e187c589 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 16 Dec 2021 02:07:10 +0000 Subject: [PATCH 470/475] Correct import of MutableMapping for Python 3.10 --- dronekit/__init__.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index e4a45bd40..db5e1f3d4 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -32,7 +32,15 @@ ---- """ +import sys import collections + +# Python3.10 removed MutableMapping from collections: +if sys.version_info.major == 3 and sys.version_info.minor >= 10: + from collections.abc import MutableMapping +else: + from collections import MutableMapping + import copy import logging import math @@ -2723,7 +2731,7 @@ def __str__(self): return "Gimbal: pitch={0}, roll={1}, yaw={2}".format(self.pitch, self.roll, self.yaw) -class Parameters(collections.MutableMapping, HasObservers): +class Parameters(MutableMapping, HasObservers): """ This object is used to get and set the values of named parameters for a vehicle. See the following links for information about the supported parameters for each platform: `Copter Parameters `_, From b92a9b049fb9b66b9da93778871e050f05df57d3 Mon Sep 17 00:00:00 2001 From: "Samuel S. Hernandez" <54045450+SamuelSHernandez@users.noreply.github.com> Date: Wed, 15 Jun 2022 17:26:51 -0500 Subject: [PATCH 471/475] Update mission_basic.py outdated documentation links --- examples/mission_basic/mission_basic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/mission_basic/mission_basic.py b/examples/mission_basic/mission_basic.py index 8e394e4db..226d327dd 100644 --- a/examples/mission_basic/mission_basic.py +++ b/examples/mission_basic/mission_basic.py @@ -5,7 +5,7 @@ © Copyright 2015-2016, 3D Robotics. mission_basic.py: Example demonstrating basic mission operations including creating, clearing and monitoring missions. -Full documentation is provided at http://python.dronekit.io/examples/mission_basic.html +Full documentation is provided at https://dronekit-python.readthedocs.io/en/latest/examples/mission_basic.html """ from __future__ import print_function From c7e1b8ef534170db38289da46d6c2d89a3db2dd9 Mon Sep 17 00:00:00 2001 From: Ramon Roche Date: Wed, 7 Jun 2023 21:45:27 -0700 Subject: [PATCH 472/475] Maintainers Needed Hey @hamishwillee, your feedback would be appreciated. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 616ac31f7..f024a0b6f 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ DroneKit-Python helps you create powerful apps for UAVs. +# ⚠️ ATTENTION: MAINTAINERS NEEDED ⚠️ + +Hey it's true this project is not very active, but it could be with your help. We are looking for maintainers interested in keeping the project alive by keep up with CI and PRs. If you are interested in helping please apply by [creating an issue]([url](https://github.com/dronekit/dronekit-python/issues/new)) and listing the reasons why you would like to help, in return we will be granting committer access to folks who are truly interested in helping. + ## Overview From 3ee89b7d83ba1fe676f0b2980a7774b052c29c2f Mon Sep 17 00:00:00 2001 From: John Kesler Date: Fri, 14 Apr 2023 08:10:11 -0500 Subject: [PATCH 473/475] Make HEARTBEAT handler ignore non-vehicle HEARTBEATs --- dronekit/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dronekit/__init__.py b/dronekit/__init__.py index db5e1f3d4..bc05a7098 100644 --- a/dronekit/__init__.py +++ b/dronekit/__init__.py @@ -1249,7 +1249,7 @@ def listener(self, name, m): @self.on_message('HEARTBEAT') def listener(self, name, m): # ignore groundstations - if m.type == mavutil.mavlink.MAV_TYPE_GCS: + if m.type == mavutil.mavlink.MAV_TYPE_GCS or (not self._handler.master.probably_vehicle_heartbeat(m)): return self._armed = (m.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED) != 0 self.notify_attribute_listeners('armed', self.armed, cache=True) @@ -1413,7 +1413,7 @@ def listener(_): @self.on_message(['HEARTBEAT']) def listener(self, name, msg): # ignore groundstations - if msg.type == mavutil.mavlink.MAV_TYPE_GCS: + if msg.type == mavutil.mavlink.MAV_TYPE_GCS or (not self._handler.master.probably_vehicle_heartbeat(msg)): return self._heartbeat_system = msg.get_srcSystem() self._heartbeat_lastreceived = monotonic.monotonic() From 53ca517bcb4ed1dd2dffad26528a25bf77f9c34b Mon Sep 17 00:00:00 2001 From: muramura Date: Mon, 20 May 2024 06:48:19 +0900 Subject: [PATCH 474/475] examples: Change the reference URL --- docs/examples/guided-set-speed-yaw-demo.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/examples/guided-set-speed-yaw-demo.rst b/docs/examples/guided-set-speed-yaw-demo.rst index 49cefdf23..22554157f 100644 --- a/docs/examples/guided-set-speed-yaw-demo.rst +++ b/docs/examples/guided-set-speed-yaw-demo.rst @@ -189,16 +189,16 @@ The functions for controlling vehicle movement are: DroneKit position controller method. It is called from :ref:`goto ` to fly a triangular path. * :ref:`goto_position_target_global_int() ` is a position controller that uses the - `SET_POSITION_TARGET_GLOBAL_INT `_ command. + `SET_POSITION_TARGET_GLOBAL_INT `_ command. * :ref:`goto_position_target_local_ned() ` - is a position controller that uses `SET_POSITION_TARGET_LOCAL_NED `_ + is a position controller that uses `SET_POSITION_TARGET_LOCAL_NED `_ command (taking values in NED frame, relative to the home position). This is used to fly a square path. The script is put to sleep for a certain time in order to allow the vehicle to reach the specified position. * :ref:`send_ned_velocity() ` is a velocity controller. - It uses `SET_POSITION_TARGET_LOCAL_NED `_ + It uses `SET_POSITION_TARGET_LOCAL_NED `_ to fly a square path using velocity vectors to define the speed in each direction. * :ref:`send_global_velocity() ` is a velocity controller. - It uses `SET_POSITION_TARGET_GLOBAL_INT `_ + It uses `SET_POSITION_TARGET_GLOBAL_INT `_ to fly a diamond-shaped path. The behaviour is essentially the same as for ``send_ned_velocity()`` because the velocity components in both commands are in the NED frame. * :ref:`goto ` is a convenience function for specifying a target location @@ -262,7 +262,7 @@ send_global_velocity() ---------------------- The function ``send_global_velocity()`` generates a -`SET_POSITION_TARGET_GLOBAL_INT `_ +`SET_POSITION_TARGET_GLOBAL_INT `_ MAVLink message which is used to directly specify the speed components of the vehicle in the NED frame. @@ -359,7 +359,7 @@ The ``type_mask`` enables the position parameters (the last three bits of of the .. note:: - The `MAVLink protocol documentation `_ + The `MAVLink protocol documentation `_ lists a number of possible frames of reference. Up until Copter 3.2.1 the actual frame used is always relative to the home location (as indicated by MAV_FRAME_LOCAL_NED). Starting from Copter 3.3 you can specify `other frames `_, From 1dda2a222580b376422ccbc689f5dda1b306b50c Mon Sep 17 00:00:00 2001 From: muramura Date: Mon, 20 May 2024 06:49:27 +0900 Subject: [PATCH 475/475] copter: Change the reference URL --- docs/guide/copter/guided_mode.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/guide/copter/guided_mode.rst b/docs/guide/copter/guided_mode.rst index b96ba3171..e7ec0def5 100644 --- a/docs/guide/copter/guided_mode.rst +++ b/docs/guide/copter/guided_mode.rst @@ -83,8 +83,8 @@ for all positional movement commands until it is set to another value. .. tip:: You can also set the position by sending the MAVLink commands - `SET_POSITION_TARGET_GLOBAL_INT `_ or - `SET_POSITION_TARGET_LOCAL_NED `_, specifying + `SET_POSITION_TARGET_GLOBAL_INT `_ or + `SET_POSITION_TARGET_LOCAL_NED `_, specifying a ``type_mask`` bitmask that enables the position parameters. The main difference between these commands is that the former allows you to specify the location relative to the "global" frames (like ``Vehicle.simple_goto()``), while the later lets you specify the location in NED co-ordinates relative @@ -175,7 +175,7 @@ When moving the vehicle you can send separate commands to control the yaw (and o .. tip:: You can also control the velocity using the - `SET_POSITION_TARGET_GLOBAL_INT `_ + `SET_POSITION_TARGET_GLOBAL_INT `_ MAVLink command, as described in :ref:`example_guided_mode_send_global_velocity`. @@ -189,8 +189,8 @@ ArduPilot does not currently support controlling the vehicle by specifying accel .. note:: - The `SET_POSITION_TARGET_GLOBAL_INT `_ and - `SET_POSITION_TARGET_LOCAL_NED `_ + The `SET_POSITION_TARGET_GLOBAL_INT `_ and + `SET_POSITION_TARGET_LOCAL_NED `_ MAVLink commands allow you to specify the acceleration, force and yaw. However, commands setting these parameters are ignored by the vehicle. @@ -221,7 +221,7 @@ to encode the message and then calling :py:func:`send_mavlink() `_ +`SET_POSITION_TARGET_LOCAL_NED `_ message we call ``message_factory.set_position_target_local_ned_encode()`` with values for all the message fields as arguments: @@ -248,7 +248,7 @@ really intended for a specific component. .. _guided_mode_how_to_send_commands_command_long: -In Copter, the `COMMAND_LONG message `_ can be used send/package +In Copter, the `COMMAND_LONG message `_ can be used send/package *a number* of different `supported MAV_CMD commands `_. The factory function is again the lower case message name with suffix ``_encode`` (``message_factory.command_long_encode``). The message parameters include the actual command to be sent (in the code fragment below ``MAV_CMD_CONDITION_YAW``) and its fields. @@ -474,7 +474,7 @@ Other information ================= * `NED Frame `_ -* `MISSION_ITEM `_ +* `MISSION_ITEM `_ * `GUIDED Mode for Copter `_ (wiki). * `GUIDED mode for Plane `_ (wiki). * `Copter Commands in Guided Mode `_ (wiki).