GPS Logger is a very simple AERPAW sample application that only logs the location of the vehicle (based on information from the autopilot) but does not control the vehicle at all. The purpose of this sample application is to allow the monitoring of the vehicle while the vehicle is controlled externally. This allows for drones and rover to be operated under manual control from the pilot, while still logging their position. Additionally, the location of other vehicles (e.g., Wolflink shuttles, helikites, etc.) can be monitored using this application.
The sample script is found in $VEHICLE_CONTROL/GPSLogger/gps_logger.py
Minimal usage:
python gps_logger.py --conn <connection>
or
python3 gps_logger.py --conn <connection>
Optional parameters:
--output: [default gps_data_YYYY-MM-DD_HH:MM:SS.csv] specific output file to use
--samplerate: [default 1Hz] sample rate in Hz (samples / sec)
The connection string <connection str> specifies where to connect in the MAVLink tree (allowing the status messages to reach from autopilot to the script). At this time the script connects to the MAVLink filter. Currently the correct connection string for AERPAW (both testbed and development modes) is 192.168.32.26:14550 where the IP address corresponds to the E-VM IP address and the port is where the MAVLink filter expects to find the vehicle control script.
By default the GPS logger script periodically (by default once a second) outputs the current location of the vehicle (obtained from the autopilot's position estimator - not a raw GPS stream). The --output parameter allows the experimenter to change the filename where the GPS coordinates are being saved. The default filename is gps_data_YYYY-MM-DD_HH:MM:SS.csv
Finally, the optional parameter --samplerate allows an experimenter to request a higher sample rate from the autopilot. The raw GPS readings into the autopilot have a rate of 10 Hz. However, the autopilot uses its EKF location estimator to "interpolate" between these raw readings, so the samplerate available to the experimenter can be as high as 100 Hz. The location readings obtained this way are neither the raw readings from the GPS receiver, nor a simple interpolation or extrapolation between these points, but rather position estimates by integrating the inertial measurement unit (IMU), barometer, magnetometer and other sensors if present, and take into account the input to the drone, wind estimates, etc. It is usually far more precise than the location received from the GPS receiver.
A given row in the file dump has this file format:
line,longitude,latitude,altitude,(pitch,yaw,roll),velocity,voltage,YYYY-MM-DD HH:MM:SS.000000,gps status,satellites
This script will take periodic snapshots of the autopilot's state and dump it to a CSV file. The information included is the vehicle's position (lat, lon, altitude), the vehicle's battery voltage, the GPS status, and the number of visible satellites.
This script will continually run once started, even if it loses connection to the vehicle. If it loses its connection (heartbeat), the script will complain in the standard output. When run on the companion computer of the vehicle, it should never lose physical connection (as it's based on a USB cable). The script may, however, lose the stream of heartbeats if if the MAVLink filter trips (e.g., if the pilot breaks the geofence). The script would not dump new rows to the log without a connection.
Because the script doesn't close automatically or on connection loss, the experimenters will need to kill it explicitly by either sending it a keyboard interrupt, or with something like:
kill $(ps aux | grep gps_logger | awk '/python/ {print $s}')
If preferable by the use case, the user can easily change the script to stop logging and exit after the vehicle has been disarmed.
It's probably wise to pipe the standard output of this script into a log file to capture connect/disconnect times (if any).
The GPS logger can be used to monitor a lot more than just the position, voltage, gps status and satellites. The script is based on DroneKit. As such, every variable that DroneKit offers is available to the experimenter. The available states are documented on this page. For convenience the list of available attributes is available below.
The relevant function to modify if the experimenter wishes to monitor additional attributes is:
_dump(vehicle: Vehicle, line_num: int, writer: object)
In that function, the experimenter should do two things:
obtain the value of interest by assigning to a variable of type string. For example, for vehicle ground speed: groundspeed = str(vehicle.groundspeed)
include the variable in the log: writer.writerow([line_num, lon, lat, alt, volt, timestamp, fix, num_sat,groundspeed])
# 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
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 "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 "Mode: %s" % vehicle.mode.name # settable
print "Armed: %s" % vehicle.armed # settable