00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 import csv
00021 import time
00022
00023 from mavros.msg import Waypoint, WaypointList
00024 from mavros.srv import WaypointPull, WaypointPush, WaypointClear, \
00025 WaypointSetCurrent, WaypointGOTO
00026
00027
00028 FRAMES = {
00029 Waypoint.FRAME_GLOBAL: 'GAA',
00030 Waypoint.FRAME_GLOBAL_REL_ALT: 'GRA',
00031 Waypoint.FRAME_LOCAL_ENU: 'LOC-ENU',
00032 Waypoint.FRAME_LOCAL_NED: 'LOC-NED',
00033 Waypoint.FRAME_MISSION: 'MIS'
00034 }
00035
00036 NAV_CMDS = {
00037 Waypoint.NAV_LAND: 'LAND',
00038 Waypoint.NAV_LOITER_TIME: 'LOITER-TIME',
00039 Waypoint.NAV_LOITER_TURNS: 'LOITER-TURNS',
00040 Waypoint.NAV_LOITER_UNLIM: 'LOITER-UNLIM',
00041 Waypoint.NAV_RETURN_TO_LAUNCH: 'RTL',
00042 Waypoint.NAV_TAKEOFF: 'TAKEOFF',
00043 Waypoint.NAV_WAYPOINT: 'WAYPOINT',
00044
00045 112: 'COND-DELAY',
00046 113: 'COND-CHANGE-ALT',
00047 114: 'COND-DISTANCE',
00048 115: 'COND-YAW',
00049 177: 'DO-JUMP',
00050 178: 'DO-CHANGE-SPEED',
00051 181: 'DO-SET-RELAY',
00052 182: 'DO-REPEAT-RELAY',
00053 183: 'DO-SET-SERVO',
00054 184: 'DO-REPEAT-SERVO',
00055 201: 'DO-SET-ROI',
00056 }
00057
00058
00059 class WaypointFile(object):
00060 """Base class for waypoint file parsers"""
00061 def read(self, file_):
00062 """Returns a iterable of waypoints"""
00063 raise NotImplementedError
00064
00065 def write(self, file_, waypoints):
00066 """Writes waypoints to file"""
00067 raise NotImplementedError
00068
00069
00070 class QGroundControlWP(WaypointFile):
00071 """Parse QGC waypoint file"""
00072
00073 file_header = 'QGC WPL 120'
00074 known_versions = (110, 120)
00075
00076 class CSVDialect(csv.Dialect):
00077 delimiter = '\t'
00078 doublequote = False
00079 skipinitialspace = True
00080 lineterminator = '\r\n'
00081 quoting = csv.QUOTE_NONE
00082
00083 def read(self, file_):
00084 got_header = False
00085 for data in csv.reader(file_, self.CSVDialect):
00086 if data[0].startswith('#'):
00087 continue;
00088
00089 if not got_header:
00090 qgc, wpl, ver = data[0].split(' ', 3)
00091 ver = int(ver)
00092 if qgc == 'QGC' and wpl == 'WPL' and ver in self.known_versions:
00093 got_header = True
00094
00095 else:
00096 yield Waypoint(
00097 is_current = bool(int(data[1])),
00098 frame = int(data[2]),
00099 command = int(data[3]),
00100 param1 = float(data[4]),
00101 param2 = float(data[5]),
00102 param3 = float(data[6]),
00103 param4 = float(data[7]),
00104 x_lat = float(data[8]),
00105 y_long = float(data[9]),
00106 z_alt = float(data[10]),
00107 autocontinue = bool(int(data[11]))
00108 )
00109
00110 def write(self, file_, waypoints):
00111 writer = csv.writer(file_, self.CSVDialect)
00112 writer.writerow((self.file_header ,))
00113 for seq, w in enumerate(waypoints):
00114 writer.writerow((
00115 seq,
00116 int(w.is_current),
00117 w.frame,
00118 w.command,
00119 w.param1,
00120 w.param2,
00121 w.param3,
00122 w.param4,
00123 w.x_lat,
00124 w.y_long,
00125 w.z_alt,
00126 int(w.autocontinue)
00127 ))