Commit d87a36fc authored by Hamish Willee's avatar Hamish Willee
Browse files

Delete unsupported flight replay example

parent 30750480
Showing with 0 additions and 275 deletions
+0 -275
=========================
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.
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 <http://www.droneshare.com/mission/101>`_.
.. figure:: flight_replay_example.png
Droneshare Mission #101
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 <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 <get_started_connect_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 ``--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::
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.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.
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
Some comments:
* ``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 <https://github.com/hamishwillee/dronekit-python/blob/master/examples/flight_replay/flight_replay.py>`_ for its implementation).
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`):
.. code:: python
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()
Known issues
============
There are no known issues with this example.
Source code
===========
The full source code at documentation build-time is listed below (`current version on github <https://github.com/dronekit/dronekit-python/blob/master/examples/flight_replay/flight_replay.py>`_):
.. literalinclude:: ../../examples/flight_replay/flight_replay.py
:language: python
docs/examples/flight_replay_example.png

587 KB

......@@ -21,7 +21,6 @@ during missions and outside missions using custom commands.
Create Attribute in App <create_attribute>
Follow Me (Linux only)<follow_me>
Drone Delivery <drone_delivery>
Flight Replay <flight_replay>
Channel Overrides <channel_overrides>
Performance Test <performance_test>
......
"""
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, Command
from pymavlink import mavutil
import json, urllib, math
#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, 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"""
# 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
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
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()
# 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.
#Close vehicle object before exiting script
print "Close vehicle object"
vehicle.close()
print("Completed...")
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment