mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-10 15:09:25 +08:00
[python] refactor messages
This commit is contained in:
@@ -14,7 +14,7 @@ sys.path.append(PPRZ_SRC + "/sw/lib/python")
|
||||
PPRZ_HOME = getenv("PAPARAZZI_HOME", PPRZ_SRC)
|
||||
|
||||
from ivy_msg_interface import IvyMessagesInterface
|
||||
import messages_xml_map
|
||||
from pprz_msg.message import PprzMessage
|
||||
|
||||
WIDTH = 450
|
||||
LABEL_WIDTH = 166
|
||||
@@ -23,18 +23,16 @@ HEIGHT = 800
|
||||
BORDER = 1
|
||||
|
||||
|
||||
class Message:
|
||||
class Message(PprzMessage):
|
||||
def __init__(self, class_name, name):
|
||||
messages_xml_map.parse_messages()
|
||||
self.field_value = []
|
||||
self.field_names = messages_xml_map.message_dictionary[class_name][name]
|
||||
super(Message, self).__init__(class_name, name)
|
||||
self.field_controls = []
|
||||
self.index = None
|
||||
self.last_seen = time.clock()
|
||||
self.name = name
|
||||
|
||||
|
||||
class Aircraft:
|
||||
class Aircraft(object):
|
||||
def __init__(self, ac_id):
|
||||
self.ac_id = ac_id
|
||||
self.messages = {}
|
||||
@@ -42,7 +40,7 @@ class Aircraft:
|
||||
|
||||
|
||||
class MessagesFrame(wx.Frame):
|
||||
def message_recv(self, msg_class, msg_name, ac_id, values):
|
||||
def message_recv(self, msg_class, msg_name, ac_id, msg):
|
||||
"""Handle incoming messages
|
||||
|
||||
Callback function for IvyMessagesInterface
|
||||
@@ -53,8 +51,8 @@ class MessagesFrame(wx.Frame):
|
||||
:type msg_name: str
|
||||
:param ac_id: aircraft id
|
||||
:type ac_id: int
|
||||
:param values: message values
|
||||
:type values: list
|
||||
:param msg: message
|
||||
:type msg: PprzMessage
|
||||
"""
|
||||
# only show messages of the requested class
|
||||
if msg_class != self.msg_class:
|
||||
@@ -62,7 +60,7 @@ class MessagesFrame(wx.Frame):
|
||||
if ac_id in self.aircrafts and msg_name in self.aircrafts[ac_id].messages:
|
||||
if time.time() - self.aircrafts[ac_id].messages[msg_name].last_seen < 0.2:
|
||||
return
|
||||
wx.CallAfter(self.gui_update, msg_class, msg_name, ac_id, values)
|
||||
wx.CallAfter(self.gui_update, msg_class, msg_name, ac_id, msg)
|
||||
|
||||
def find_page(self, book, name):
|
||||
if book.GetPageCount() < 1:
|
||||
@@ -119,7 +117,7 @@ class MessagesFrame(wx.Frame):
|
||||
messages_book = aircraft.messages_book
|
||||
aircraft.messages[name] = Message(msg_class, name)
|
||||
field_panel = wx.Panel(messages_book)
|
||||
grid_sizer = wx.FlexGridSizer(len(aircraft.messages[name].field_names), 2)
|
||||
grid_sizer = wx.FlexGridSizer(len(aircraft.messages[name].get_fieldnames()), 2)
|
||||
|
||||
index = self.find_page(messages_book, name)
|
||||
messages_book.InsertPage(index, field_panel, name, imageId=1)
|
||||
@@ -129,7 +127,7 @@ class MessagesFrame(wx.Frame):
|
||||
for message_name in aircraft.messages:
|
||||
aircraft.messages[message_name].index = self.find_page(messages_book, message_name)
|
||||
|
||||
for field_name in aircraft.messages[name].field_names:
|
||||
for field_name in aircraft.messages[name].get_fieldnames():
|
||||
name_text = wx.StaticText(field_panel, -1, field_name)
|
||||
size = name_text.GetSize()
|
||||
size.x = LABEL_WIDTH
|
||||
@@ -147,7 +145,7 @@ class MessagesFrame(wx.Frame):
|
||||
field_panel.SetSizer(grid_sizer)
|
||||
field_panel.Layout()
|
||||
|
||||
def gui_update(self, msg_class, msg_name, ac_id, values):
|
||||
def gui_update(self, msg_class, msg_name, ac_id, msg):
|
||||
if ac_id not in self.aircrafts:
|
||||
self.add_new_aircraft(ac_id)
|
||||
|
||||
@@ -159,8 +157,8 @@ class MessagesFrame(wx.Frame):
|
||||
aircraft.messages_book.SetPageImage(aircraft.messages[msg_name].index, 1)
|
||||
self.aircrafts[ac_id].messages[msg_name].last_seen = time.time()
|
||||
|
||||
for index in range(0, len(values)):
|
||||
aircraft.messages[msg_name].field_controls[index].SetLabel(values[index])
|
||||
for index in range(0, len(msg.get_fieldvalues())):
|
||||
aircraft.messages[msg_name].field_controls[index].SetLabel(msg.get_field(index))
|
||||
|
||||
def __init__(self, msg_class="telemetry"):
|
||||
wx.Frame.__init__(self, id=-1, parent=None, name=u'MessagesFrame', size=wx.Size(WIDTH, HEIGHT), style=wx.DEFAULT_FRAME_STYLE, title=u'Messages')
|
||||
|
||||
@@ -6,9 +6,17 @@ import os
|
||||
import sys
|
||||
import re
|
||||
|
||||
# if PAPARAZZI_SRC not set, then assume the tree containing this
|
||||
# file is a reasonable substitute
|
||||
PPRZ_SRC = os.getenv("PAPARAZZI_SRC", os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
||||
'../../../../')))
|
||||
sys.path.append(PPRZ_SRC + "/sw/lib/python")
|
||||
|
||||
class IvyMessagesInterface():
|
||||
def __init__(self, callback, init=True, verbose=True, bind_regex="(.*)"):
|
||||
from pprz_msg.message import PprzMessage
|
||||
|
||||
|
||||
class IvyMessagesInterface(object):
|
||||
def __init__(self, callback, init=True, verbose=False, bind_regex='(.*)'):
|
||||
self.callback = callback
|
||||
self.ivy_id = 0
|
||||
self.verbose = verbose
|
||||
@@ -27,7 +35,7 @@ class IvyMessagesInterface():
|
||||
except:
|
||||
pass
|
||||
|
||||
def init_ivy(self, init, bind_regex):
|
||||
def init_ivy(self, init=True, bind_regex='(.*)'):
|
||||
if init:
|
||||
IvyInit("Messages %i" % os.getpid(), "READY", 0, lambda x,y: y, lambda x,y: y)
|
||||
logging.getLogger('Ivy').setLevel(logging.WARN)
|
||||
@@ -56,13 +64,16 @@ class IvyMessagesInterface():
|
||||
|
||||
# check which message class it is
|
||||
# pass non-telemetry messages with ac_id 0
|
||||
if data[0] in ["ground", "ground_dl", "dl"]:
|
||||
if data[0] in ["sim", "ground_dl", "dl"]:
|
||||
if self.verbose:
|
||||
print("ignoring message " + ' '.join(data))
|
||||
sys.stdout.flush()
|
||||
return
|
||||
elif data[0] in ["ground"]:
|
||||
msg_class = data[0]
|
||||
msg_name = data[1]
|
||||
ac_id = 0
|
||||
values = list(filter(None, data[2:]))
|
||||
elif data[0] == "sim":
|
||||
return
|
||||
else:
|
||||
try:
|
||||
ac_id = int(data[0])
|
||||
@@ -74,4 +85,6 @@ class IvyMessagesInterface():
|
||||
msg_class = "telemetry"
|
||||
msg_name = data[1]
|
||||
values = list(filter(None, data[2:]))
|
||||
self.callback(msg_class, msg_name, ac_id, values)
|
||||
msg = PprzMessage(msg_class, msg_name)
|
||||
msg.set_values(values)
|
||||
self.callback(msg_class, msg_name, ac_id, msg)
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
"""
|
||||
Paparazzi message representation
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
import sys
|
||||
import json
|
||||
import messages_xml_map
|
||||
|
||||
|
||||
class PprzMessageError(Exception):
|
||||
def __init__(self, message, inner_exception=None):
|
||||
self.message = message
|
||||
self.inner_exception = inner_exception
|
||||
self.exception_info = sys.exc_info()
|
||||
def __str__(self):
|
||||
return self.message
|
||||
|
||||
|
||||
class PprzMessage(object):
|
||||
"""base Paparazzi message class"""
|
||||
def __init__(self, class_name, name):
|
||||
self._class_name = class_name
|
||||
self._name = name
|
||||
self._id = messages_xml_map.get_msg_id(class_name, name)
|
||||
self._fieldnames = messages_xml_map.get_msg_fields(class_name, name)
|
||||
self._fieldvalues = []
|
||||
|
||||
def get_fieldnames(self):
|
||||
return self._fieldnames
|
||||
|
||||
def get_fieldvalues(self):
|
||||
return self._fieldvalues
|
||||
|
||||
def get_field(self, idx):
|
||||
return self._fieldvalues[idx]
|
||||
|
||||
def set_values(self, values):
|
||||
if len(values) == len(self._fieldnames):
|
||||
self._fieldvalues = values
|
||||
else:
|
||||
raise PprzMessageError("Error: fields not matching")
|
||||
|
||||
def __str__(self):
|
||||
ret = '%s.%s {' % (self._class_name, self._name)
|
||||
for idx, f in enumerate(self._fieldnames):
|
||||
ret += '%s : %s, ' % (f, self._fieldvalues[idx])
|
||||
ret = ret[0:-2] + '}'
|
||||
return ret
|
||||
|
||||
def to_dict(self, payload_only=False):
|
||||
d = {}
|
||||
if not payload_only:
|
||||
d['msgname'] = self._name
|
||||
d['msgclass'] = self._class_name
|
||||
for idx, f in enumerate(self._fieldnames):
|
||||
d[f] = self._fieldvalues[idx]
|
||||
return d
|
||||
|
||||
def to_json(self, payload_only=False):
|
||||
return json.dumps(self.to_dict(payload_only))
|
||||
@@ -7,7 +7,7 @@ import os
|
||||
# if PAPARAZZI_HOME not set, then assume the tree containing this
|
||||
# file is a reasonable substitute
|
||||
PPRZ_HOME = os.getenv("PAPARAZZI_HOME", os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
||||
'../../../')))
|
||||
'../../../..')))
|
||||
|
||||
default_messages_file = '%s/conf/messages.xml' % PPRZ_HOME
|
||||
|
||||
@@ -61,6 +61,30 @@ def parse_messages(messages_file=default_messages_file):
|
||||
message_dictionary_types[class_name][message_id].append(the_field.attrib['type'])
|
||||
|
||||
|
||||
def get_msg_fields(msg_class, msg_name):
|
||||
if not message_dictionary:
|
||||
parse_messages()
|
||||
if msg_class in message_dictionary:
|
||||
if msg_name in message_dictionary[msg_class]:
|
||||
return message_dictionary[msg_class][msg_name]
|
||||
else:
|
||||
print("Error: msg_name %s not found in msg_class %s." % (msg_name, msg_class))
|
||||
else:
|
||||
print("Error: msg_class %s not found." % msg_class)
|
||||
return []
|
||||
|
||||
|
||||
def get_msg_id(msg_class, msg_name):
|
||||
if not message_dictionary:
|
||||
parse_messages()
|
||||
try:
|
||||
return message_dictionary_name_id[msg_class][msg_name]
|
||||
except KeyError:
|
||||
print("Error: msg_name %s not found in msg_class %s." % (msg_name, msg_class))
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
def test():
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser()
|
||||
Reference in New Issue
Block a user