diff --git a/sw/ground_segment/python/log_annotate.py b/sw/ground_segment/python/log_annotate.py index 82c686dee2..2b71639ee3 100755 --- a/sw/ground_segment/python/log_annotate.py +++ b/sw/ground_segment/python/log_annotate.py @@ -9,58 +9,57 @@ from ivy.std_api import * import logging class Base: - def __init__(self): - self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) - self.window.connect("destroy", self.destroy) + def __init__(self): + self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) + self.window.connect("destroy", self.destroy) - self.entry = gtk.Entry() - self.entry.set_width_chars(120) - self.entry.connect("key-release-event", self.key_release_event) - self.entry.show() + self.entry = gtk.Entry() + self.entry.set_width_chars(120) + self.entry.connect("key-release-event", self.key_release_event) + self.entry.show() - self.window.add(self.entry) - self.window.show() - self.ivy_init() - self.ticks = 0 + self.window.add(self.entry) + self.window.show() + self.ivy_init() + self.ticks = 0 - def ontick(self): - if self.ticks == 5: - IvyStop() - elif self.ticks <= 2: - IvySendMsg("1 BAT " + self.text) - self.ticks = self.ticks + 1 + def ontick(self): + if self.ticks == 5: + IvyStop() + elif self.ticks <= 2: + IvySendMsg("1 BAT " + self.text) + self.ticks = self.ticks + 1 - def ivy_init(self): - logging.getLogger('Ivy').setLevel(logging.WARN) - IvyInit("Log Annotate", - "Annotate Ready Msg", - 0 - ) + def ivy_init(self): + logging.getLogger('Ivy').setLevel(logging.WARN) + IvyInit("Log Annotate", + "Annotate Ready Msg", + 0) - def key_release_event(self, widget, event, data=None): - if event.string == '\r': # Return - self.text = self.entry.get_text() - self.destroy(self, None) - if event.string == '\033': # Escape - self.destroy(self, None) - return False + def key_release_event(self, widget, event, data=None): + if event.string == '\r': # Return + self.text = self.entry.get_text() + self.destroy(self, None) + if event.string == '\033': # Escape + self.destroy(self, None) + return False - def delete_event(self, widget, event, data=None): - return False + def delete_event(self, widget, event, data=None): + return False - def destroy(self, widget, data=None): - gtk.main_quit() + def destroy(self, widget, data=None): + gtk.main_quit() - def main(self): - IvyStart("") - gtk.main() + def main(self): + IvyStart("") + gtk.main() - if self.text: - timerid = IvyTimerRepeatAfter(0, # number of time to be called - 100, # delay in ms between calls - self.ontick # handler to call - ) - IvyMainLoop() + if self.text: + timerid = IvyTimerRepeatAfter(0, # number of time to be called + 100, # delay in ms between calls + self.ontick # handler to call + ) + IvyMainLoop() if __name__ == "__main__": base = Base() diff --git a/sw/ground_segment/python/onboard_log_transform.py b/sw/ground_segment/python/onboard_log_transform.py index f83778d991..821aba060e 100755 --- a/sw/ground_segment/python/onboard_log_transform.py +++ b/sw/ground_segment/python/onboard_log_transform.py @@ -16,74 +16,70 @@ import messages_xml_map class OnboardLogTransformTool(): def __init__(self): - messages_xml_map.ParseMessages() - self.data_types = { 'float' : ['f', 4], - 'uint8' : ['B', 1], - 'uint16' : ['H', 2], - 'uint32' : ['L', 4], - 'int8' : ['b', 1], - 'int16' : ['h', 2], - 'int32' : ['l', 4] - } + messages_xml_map.ParseMessages() + self.data_types = { 'float' : ['f', 4], + 'uint8' : ['B', 1], + 'uint16' : ['H', 2], + 'uint32' : ['L', 4], + 'int8' : ['b', 1], + 'int16' : ['h', 2], + 'int32' : ['l', 4] + } def Unpack(self, data_fields, type, start, length): return struct.unpack(type, "".join(data_fields[start:start + length]))[0] def ProcessLine(self, line): - fields = line.strip().split(' ') - [timestamp, pprz_tstamp, ac_id, msg_id] = fields[0:4] - data_fields = map(lambda x: chr(int(x, 16)), fields[5:]) - ac_id = int(ac_id) - timestamp = float(pprz_tstamp) - msg_id = int(msg_id) + fields = line.strip().split(' ') + [timestamp, pprz_tstamp, ac_id, msg_id] = fields[0:4] + data_fields = map(lambda x: chr(int(x, 16)), fields[5:]) + ac_id = int(ac_id) + timestamp = float(pprz_tstamp) + msg_id = int(msg_id) - # print "Next message: ", timestamp, pprz_tstamp, ac_id, msg_id - # print messages_xml_map.message_dictionary_id_name.keys() - # print messages_xml_map.message_dictionary_types.keys() - - msg_name = messages_xml_map.message_dictionary_id_name['telemetry'][msg_id] - msg_fields = messages_xml_map.message_dictionary_types['telemetry'][msg_id] + # print "Next message: ", timestamp, pprz_tstamp, ac_id, msg_id + # print messages_xml_map.message_dictionary_id_name.keys() + # print messages_xml_map.message_dictionary_types.keys() - result = "%f %i %s " % (timestamp, ac_id, msg_name) + msg_name = messages_xml_map.message_dictionary_id_name['telemetry'][msg_id] + msg_fields = messages_xml_map.message_dictionary_types['telemetry'][msg_id] - field_offset = 0 - for field in msg_fields: - if field[-2:] == "[]": - baseType = field[:-2] - array_length = int(self.Unpack(data_fields, 'B', field_offset, 1)) - field_offset = field_offset + 1 - for count in range(0, array_length): - array_value = str(self.Unpack(data_fields, self.data_types[baseType][0], field_offset, self.data_types[baseType][1])) - field_offset = field_offset + self.data_types[baseType][1] - if (count == array_length - 1): - result += array_value + " " - else: - result += array_value + "," - else: - result += str(self.Unpack(data_fields, self.data_types[field][0], field_offset, self.data_types[field][1])) + " " - field_offset = field_offset + self.data_types[field][1] + result = "%f %i %s " % (timestamp, ac_id, msg_name) + + field_offset = 0 + for field in msg_fields: + if field[-2:] == "[]": + baseType = field[:-2] + array_length = int(self.Unpack(data_fields, 'B', field_offset, 1)) + field_offset = field_offset + 1 + for count in range(0, array_length): + array_value = str(self.Unpack(data_fields, self.data_types[baseType][0], field_offset, self.data_types[baseType][1])) + field_offset = field_offset + self.data_types[baseType][1] + if (count == array_length - 1): + result += array_value + " " + else: + result += array_value + "," + else: + result += str(self.Unpack(data_fields, self.data_types[field][0], field_offset, self.data_types[field][1])) + " " + field_offset = field_offset + self.data_types[field][1] - if (field_offset > len(data_fields)): - print "finished without parsing %s" % field - break + if (field_offset > len(data_fields)): + print "finished without parsing %s" % field + break - return result[:-1] + return result[:-1] def Run(self, logfile): - # open log file - INPUT = open(logfile, "r") - for line in INPUT: - print self.ProcessLine(line) - - # print self.ProcessLine(line) - # except: - # pass - INPUT.close() + # open log file + INPUT = open(logfile, "r") + for line in INPUT: + print self.ProcessLine(line) + INPUT.close() def main(): - log_transform = OnboardLogTransformTool() - log_transform.Run(sys.argv[1]) + log_transform = OnboardLogTransformTool() + log_transform.Run(sys.argv[1]) if __name__ == '__main__': - main() + main() diff --git a/sw/ground_segment/python/real_time_plot/messagepicker.py b/sw/ground_segment/python/real_time_plot/messagepicker.py index dad7bb87e0..97e17471bf 100755 --- a/sw/ground_segment/python/real_time_plot/messagepicker.py +++ b/sw/ground_segment/python/real_time_plot/messagepicker.py @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import absolute_import, print_function + import wx import getopt import sys @@ -11,96 +13,96 @@ sys.path.append(os.getenv("PAPARAZZI_HOME") + "/sw/lib/python") import messages_tool class MessagePicker(wx.Frame): - def __init__(self, parent, callback, initIvy = True): - wx.Frame.__init__(self, parent, name="MessagePicker", title=u'Message Picker', size=wx.Size(320,640)) - - self.aircrafts = {} - self.callback = callback + def __init__(self, parent, callback, initIvy = True): + wx.Frame.__init__(self, parent, name="MessagePicker", title=u'Message Picker', size=wx.Size(320,640)) - self.tree = wx.TreeCtrl(self) - self.root = self.tree.AddRoot("Telemetry") - self.tree.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick) - self.tree.Bind(wx.EVT_CHAR, self.OnKeyChar) - self.Bind( wx.EVT_CLOSE, self.OnClose) - self.message_interface = messages_tool.IvyMessagesInterface(self.msg_recv, initIvy) + self.aircrafts = {} + self.callback = callback - def OnClose(self, event): - self.message_interface.Stop() - self.Destroy() + self.tree = wx.TreeCtrl(self) + self.root = self.tree.AddRoot("Telemetry") + self.tree.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick) + self.tree.Bind(wx.EVT_CHAR, self.OnKeyChar) + self.Bind( wx.EVT_CLOSE, self.OnClose) + self.message_interface = messages_tool.IvyMessagesInterface(self.msg_recv, initIvy) - def msg_recv(self, ac_id, name, values): - self.tree.Expand(self.root) - if not self.aircrafts.has_key(ac_id): - ac_node = self.tree.AppendItem(self.root, str(ac_id)) - self.aircrafts[ac_id] = messages_tool.Aircraft(ac_id) - self.aircrafts[ac_id].messages_book = ac_node + def OnClose(self, event): + self.message_interface.Stop() + self.Destroy() - aircraft = self.aircrafts[ac_id] - ac_node = aircraft.messages_book + def msg_recv(self, ac_id, name, values): + self.tree.Expand(self.root) + if ac_id not in self.aircrafts: + ac_node = self.tree.AppendItem(self.root, str(ac_id)) + self.aircrafts[ac_id] = messages_tool.Aircraft(ac_id) + self.aircrafts[ac_id].messages_book = ac_node - if not aircraft.messages.has_key(name): - msg_node = self.tree.AppendItem(ac_node, str(name)) - self.tree.SortChildren(ac_node) - aircraft.messages[name] = messages_tool.Message("telemetry", name) - for field in aircraft.messages[name].field_names: - item = self.tree.AppendItem(msg_node, field) + aircraft = self.aircrafts[ac_id] + ac_node = aircraft.messages_book - def OnKeyChar(self, event): - if event.GetKeyCode() != 13: - return False - node = self.tree.GetSelection() - field_name = self.tree.GetItemText(node) + if name not in aircraft.messages: + msg_node = self.tree.AppendItem(ac_node, str(name)) + self.tree.SortChildren(ac_node) + aircraft.messages[name] = messages_tool.Message("telemetry", name) + for field in aircraft.messages[name].field_names: + item = self.tree.AppendItem(msg_node, field) - parent = self.tree.GetItemParent(node) - message_name = self.tree.GetItemText(parent) + def OnKeyChar(self, event): + if event.GetKeyCode() != 13: + return False + node = self.tree.GetSelection() + field_name = self.tree.GetItemText(node) - grandparent = self.tree.GetItemParent(parent) - ac_id = self.tree.GetItemText(grandparent) + parent = self.tree.GetItemParent(node) + message_name = self.tree.GetItemText(parent) - if node == self.root or parent == self.root or grandparent == self.root: - # if not leaf, double click = expand - if self.tree.IsExpanded(node): - self.tree.Collapse(node) - else: - self.tree.Expand(node) - return + grandparent = self.tree.GetItemParent(parent) + ac_id = self.tree.GetItemText(grandparent) - self.callback(int(ac_id), message_name, field_name) - - def OnDoubleClick(self, event): - node = self.tree.GetSelection() - field_name = self.tree.GetItemText(node) + if node == self.root or parent == self.root or grandparent == self.root: + # if not leaf, double click = expand + if self.tree.IsExpanded(node): + self.tree.Collapse(node) + else: + self.tree.Expand(node) + return - parent = self.tree.GetItemParent(node) - message_name = self.tree.GetItemText(parent) + self.callback(int(ac_id), message_name, field_name) - grandparent = self.tree.GetItemParent(parent) - ac_id = self.tree.GetItemText(grandparent) + def OnDoubleClick(self, event): + node = self.tree.GetSelection() + field_name = self.tree.GetItemText(node) - if node == self.root or parent == self.root or grandparent == self.root: - # if not leaf, double click = expand - if self.tree.IsExpanded(node): - self.tree.Collapse(node) - else: - self.tree.Expand(node) - return + parent = self.tree.GetItemParent(node) + message_name = self.tree.GetItemText(parent) - self.callback(int(ac_id), message_name, field_name) + grandparent = self.tree.GetItemParent(parent) + ac_id = self.tree.GetItemText(grandparent) + + if node == self.root or parent == self.root or grandparent == self.root: + # if not leaf, double click = expand + if self.tree.IsExpanded(node): + self.tree.Collapse(node) + else: + self.tree.Expand(node) + return + + self.callback(int(ac_id), message_name, field_name) class TestApp(wx.App): - def OnInit(self): - self.main = MessagePicker(None, callback) - self.main.Show() - self.SetTopWindow(self.main) + def OnInit(self): + self.main = MessagePicker(None, callback) + self.main.Show() + self.SetTopWindow(self.main) - return True + return True def test(): application = TestApp(0) application.MainLoop() def callback(ac_id, message, field): - print ac_id, message, field + print(ac_id, message, field) if __name__ == '__main__': test() diff --git a/sw/ground_segment/python/real_time_plot/plotframe.py b/sw/ground_segment/python/real_time_plot/plotframe.py index c2c3899fd8..7763af1ef6 100644 --- a/sw/ground_segment/python/real_time_plot/plotframe.py +++ b/sw/ground_segment/python/real_time_plot/plotframe.py @@ -108,7 +108,7 @@ class PlotFrame(wx.Frame): def __init__(self, parent): self._init_ctrls(parent) - + self.canvas = plotpanel.create(self.panel1, self) self.dynamic_menus = {} @@ -128,21 +128,21 @@ class PlotFrame(wx.Frame): self.editMax.SetValue(str(max_)) def OnClose(self, event): - # need to forward close to canvas so that ivy is shut down, otherwise ivy hangs the shutdown - self.canvas.OnClose() - self.Destroy() - + # need to forward close to canvas so that ivy is shut down, otherwise ivy hangs the shutdown + self.canvas.OnClose() + self.Destroy() + def OnErase(self, event): pass - + def OnSize(self, event): - self.canvas.OnSize( event.GetSize()) + self.canvas.OnSize( event.GetSize()) def OnSliderTimeCommandScroll(self, event): value = event.GetPosition() self.canvas.SetPlotInterval(value) self.editTime.SetValue( '%.3f' % (value/1000.0)) - + def OnEditTimeTextEnter(self, event): try: value = int(float(event.GetString()) * 1000.0) @@ -169,7 +169,7 @@ class PlotFrame(wx.Frame): def OnMenu1Item_pauseMenu(self, event): self.canvas.Pause(event.IsChecked()) - + def AddCurve(self, menu_id, title, use_as_x = False): curveMenu = wx.Menu(title='') @@ -186,7 +186,7 @@ class PlotFrame(wx.Frame): self.Bind(wx.EVT_MENU, self.OnMenuScaleCurve, id=menu_id*10+2) self.Bind(wx.EVT_MENU, self.OnMenuRealTime, id=menu_id*10+3) self.Bind(wx.EVT_MENU, self.OnMenuUseAsXAxis, id=menu_id*10+4) - + self.dynamic_menus[menu_id] = self.menuCurves.AppendSubMenu(submenu=curveMenu, text=title) def OnMenuDeleteCurve(self, event): @@ -198,25 +198,25 @@ class PlotFrame(wx.Frame): def OnMenuOffsetCurve(self, event): menu_id = (event.GetId()-1) / 10 - + default_value = str(self.canvas.FindPlot(menu_id).offset) value = wx.GetTextFromUser("Enter a value to offset the plot", "Offset", default_value) try: - value = float(value) - self.canvas.OffsetPlot( menu_id, value) + value = float(value) + self.canvas.OffsetPlot( menu_id, value) except: - pass + pass def OnMenuScaleCurve(self, event): menu_id = (event.GetId()-2) / 10 - + default_value = str(self.canvas.FindPlot(menu_id).scale) value = wx.GetTextFromUser("Enter a factor to scale the plot", "Scale", default_value) try: - value = float(value) - self.canvas.ScalePlot( menu_id, value) + value = float(value) + self.canvas.ScalePlot( menu_id, value) except: - pass + pass def OnMenuRealTime(self,event): menu_id = (event.GetId()-3) / 10 @@ -227,15 +227,15 @@ class PlotFrame(wx.Frame): menu_id = (event_id-4) / 10 value = event.IsChecked() - if value: - # go through and clear the checks from any other curves - for i in self.dynamic_menus: - for item in self.dynamic_menus[i].GetSubMenu().GetMenuItems(): - if item.GetText() == u'_Use as X-axis' and event_id != item.GetId(): - item.Check(False) - self.canvas.SetXAxis(menu_id) + if value: + # go through and clear the checks from any other curves + for i in self.dynamic_menus: + for item in self.dynamic_menus[i].GetSubMenu().GetMenuItems(): + if item.GetText() == u'_Use as X-axis' and event_id != item.GetId(): + item.Check(False) + self.canvas.SetXAxis(menu_id) else: - self.canvas.ClearXAxis() + self.canvas.ClearXAxis() def OnEditMinText(self, event): diff --git a/sw/ground_segment/python/real_time_plot/plotpanel.py b/sw/ground_segment/python/real_time_plot/plotpanel.py index a05e715733..278b9fca3e 100644 --- a/sw/ground_segment/python/real_time_plot/plotpanel.py +++ b/sw/ground_segment/python/real_time_plot/plotpanel.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, print_function import wx from ivy.std_api import * @@ -29,19 +30,19 @@ class plot_data: self.offset = 0.0 if (color != None): - self.color = color + self.color = color else: - r,g,b = random.randint(0,255),random.randint(0,255),random.randint(0,255) - self.color = wx.Color(r,g,b) + r,g,b = random.randint(0,255),random.randint(0,255),random.randint(0,255) + self.color = wx.Color(r,g,b) def SetRealTime(self, value): - self.real_time = value + self.real_time = value def SetOffset(self, value): - self.offset = value - + self.offset = value + def SetScale(self, value): - self.scale = value + self.scale = value def SetPlotSize(self, size): self.size = size @@ -53,23 +54,23 @@ class plot_data: self.avg = 0.0 self.std_dev = 0.0 - def AddPoint(self, point, x_axis): - self.data[self.index] = point + def AddPoint(self, point, x_axis): + self.data[self.index] = point - if self.real_time or (x_axis != None): - self.index = (self.index + 1) % self.size # increment index to next point - self.data[self.index] = None + if self.real_time or (x_axis != None): + self.index = (self.index + 1) % self.size # increment index to next point + self.data[self.index] = None def DrawTitle(self, dc, margin, width, height): - text ='avg:%.2f std:%.2f %s' % (self.avg, self.std_dev, self.title) + text ='avg:%.2f std:%.2f %s' % (self.avg, self.std_dev, self.title) - (w,h) = dc.GetTextExtent(text) - dc.SetBrush(wx.Brush(self.color)) - dc.DrawRectangle( width-h-margin, height, h, h) - dc.DrawText(text, width-2*margin-w-h, height) - return h + (w,h) = dc.GetTextExtent(text) + dc.SetBrush(wx.Brush(self.color)) + dc.DrawRectangle( width-h-margin, height, h, h) + dc.DrawText(text, width-2*margin-w-h, height) + return h def DrawCurve(self, dc, width, height, margin, _max_, _min_, x_axis): if width != self.size: @@ -77,12 +78,12 @@ class plot_data: return if (not self.real_time) and (x_axis == None): - self.index = (self.index + 1) % self.size # increment index to next point - self.data[self.index] = None + self.index = (self.index + 1) % self.size # increment index to next point + self.data[self.index] = None if x_axis != None: - (x_min, x_max) = x_axis.GetXMinMax() - + (x_min, x_max) = x_axis.GetXMinMax() + dc.SetPen(wx.Pen(self.color,1)) if _max_ < _min_: (_min_, _max_) = (-1,1) #prevent divide by zero or inversion if _max_ == _min_: (_min_, _max_) = (_max_-0.5, _max_+0.5) @@ -95,52 +96,54 @@ class plot_data: lines = [] point_1 = None for i in range(self.size): - ix = (i+self.index) % self.size - point = self.data[ix] - if point == None: continue - n += 1 - sums = sums + point - sum_squares = sum_squares + (point*point) + ix = (i+self.index) % self.size + point = self.data[ix] + if point == None: continue + n += 1 + sums = sums + point + sum_squares = sum_squares + (point*point) - if x_axis != None: - x = x_axis.data[ix] - if x == None: continue - dx = (width-1) / (x_max-x_min) - x = int((x-x_min) * dx) + if x_axis != None: + x = x_axis.data[ix] + if x == None: continue + dx = (width-1) / (x_max-x_min) + x = int((x-x_min) * dx) - else: - x = i * width / self.size + else: + x = i * width / self.size - scaled_point = (point + self.offset) * self.scale - y = height - margin - int((scaled_point - _min_)*dy) - - if point_1 != None: - line = (point_1[0], point_1[1], x, y) - lines.append( line) - point_1 = (x,y) - dc.DrawLineList(lines) + scaled_point = (point + self.offset) * self.scale + y = height - margin - int((scaled_point - _min_)*dy) - if n > 0: - self.avg = sums / n - self.std_dev = math.sqrt(math.fabs((sum_squares / n) - (self.avg * self.avg))) + if point_1 != None: + line = (point_1[0], point_1[1], x, y) + lines.append( line) + point_1 = (x,y) + dc.DrawLineList(lines) + + if n > 0: + self.avg = sums / n + self.std_dev = math.sqrt(math.fabs((sum_squares / n) - (self.avg * self.avg))) def GetXMinMax(self): - x_min = 1e32 - x_max = -1e32 + x_min = 1e32 + x_max = -1e32 - for i in range(self.size): - point = self.data[i] - if point == None: continue + for i in range(self.size): + point = self.data[i] + if point == None: continue - x_min = min( x_min, point) - x_max = max( x_max, point) + x_min = min( x_min, point) + x_max = max( x_max, point) - if x_max < x_min: (x_min, x_max) = (-1,1) #prevent divide by zero or inversion - if x_max == x_min: (x_min, x_max) = (x_max-0.5, x_max+0.5) + if x_max < x_min: + (x_min, x_max) = (-1,1) #prevent divide by zero or inversion + if x_max == x_min: + (x_min, x_max) = (x_max-0.5, x_max+0.5) - self.x_max = x_max - self.x_min = x_min - return (x_min, x_max) + self.x_max = x_max + self.x_min = x_min + return (x_min, x_max) _IVY_APPNAME='JobyPlot' @@ -185,19 +188,19 @@ class PlotPanel(): self.timer = wx.FutureCall( self.plot_interval, self.OnTimer) def SetAutoScale(self, value): - self.auto_scale = value - + self.auto_scale = value + def SetMin(self, value): - self.min = value - + self.min = value + def SetMax(self, value): - self.max = value + self.max = value def Pause(self, pause): - if pause: - self.timer.Stop() - else: - self.timer = wx.FutureCall( self.plot_interval, self.OnTimer) + if pause: + self.timer.Stop() + else: + self.timer = wx.FutureCall( self.plot_interval, self.OnTimer) def ResetScale(self): self.max = -1e32 @@ -211,17 +214,17 @@ class PlotPanel(): pass def ShowMessagePicker(self, parent): - frame = messagepicker.MessagePicker(parent, self.BindCurve, False) - frame.Show() + frame = messagepicker.MessagePicker(parent, self.BindCurve, False) + frame.Show() def InitIvy(self): # initialising the bus IvyInit(_IVY_APPNAME, # application name for Ivy - "",#"[%s is ready]" % IVYAPPNAME, # ready message - 0, # main loop is local (ie. using IvyMainloop) - lambda x,y: y, # handler called on connection/deconnection - lambda x,y: y # handler called when a diemessage is received - ) + "",#"[%s is ready]" % IVYAPPNAME, # ready message + 0, # main loop is local (ie. using IvyMainloop) + lambda x,y: y, # handler called on connection/deconnection + lambda x,y: y # handler called when a diemessage is received + ) # starting the bus # Note: env variable IVYBUS will be used if no parameter or empty string @@ -239,15 +242,15 @@ class PlotPanel(): self.BindCurve(int(ac_id), message, field) def OnIvyMsg(self, agent, *larg): - #print larg[0] + #print(larg[0]) data = larg[0].split(' ') ac_id = int(data[0]) message = data[1] - if not self.plots.has_key(ac_id): + if ac_id not in self.plots: return - if not self.plots[ac_id].has_key(message): + if message not in self.plots[ac_id]: return for field in self.plots[ac_id][message]: @@ -256,62 +259,63 @@ class PlotPanel(): point = float(data[ix+2]) if self.x_axis == None or self.x_axis.id != plot.id: - if self.auto_scale: - scaled_point = (point + plot.offset) * plot.scale - self.max = max( self.max, scaled_point) - self.min = min( self.min, scaled_point) + if self.auto_scale: + scaled_point = (point + plot.offset) * plot.scale + self.max = max( self.max, scaled_point) + self.min = min( self.min, scaled_point) if self.x_axis != None: - plot.index = self.x_axis.index + plot.index = self.x_axis.index plot.AddPoint(point, self.x_axis) def BindCurve(self, ac_id, message, field, color = None, use_as_x = False): # -- add this telemetry to our list of things to plot ... message_string = _IVY_STRING % (ac_id, message) - #print 'Binding to %s' % message_string + #print('Binding to %s' % message_string) - if not self.plots.has_key(ac_id): + if ac_id not in self.plots: self.plots[ac_id] = {} - if not self.plots[ac_id].has_key(message): + if message not in self.plots[ac_id]: self.plots[ac_id][message] = {} - if self.plots[ac_id][message].has_key(field): - self.plots[ac_id][message][field].color = wx.Color(random.randint(0,255),random.randint(0,255),random.randint(0,255)) - return + if field in self.plots[ac_id][message]: + self.plots[ac_id][message][field].color = wx.Color(random.randint(0,255),random.randint(0,255),random.randint(0,255)) + return ivy_id = IvyBindMsg(self.OnIvyMsg, str(message_string)) title = '%i:%s:%s' % (ac_id, message, field) self.plots[ac_id][message][field] = plot_data( ivy_id, title, self.plot_size, color) self.frame.AddCurve( ivy_id, title, use_as_x) if (use_as_x): - self.x_axis = self.plots[ac_id][message][field] + self.x_axis = self.plots[ac_id][message][field] def CalcMinMax(self, plot): - if not self.auto_scale: return - for x in plot.data: - self.max = max(self.max, x) - self.min = min(self.min, x) - self.frame.SetMinMax(self.min, self.max) - - def FindPlotName(self, ivy_id): - for ac_id in self.plots: - for msg in self.plots[ac_id]: - for field in self.plots[ac_id][msg]: - if self.plots[ac_id][msg][field].id == ivy_id: - return (ac_id, msg, field) - return (None, None, None) - - def FindPlot(self, ivy_id): - (ac_id, msg, field) = self.FindPlotName( ivy_id) - if (ac_id == None): - return None + if not self.auto_scale: return + for x in plot.data: + self.max = max(self.max, x) + self.min = min(self.min, x) + self.frame.SetMinMax(self.min, self.max) + + def FindPlotName(self, ivy_id): + for ac_id in self.plots: + for msg in self.plots[ac_id]: + for field in self.plots[ac_id][msg]: + if self.plots[ac_id][msg][field].id == ivy_id: + return (ac_id, msg, field) + return (None, None, None) + + def FindPlot(self, ivy_id): + (ac_id, msg, field) = self.FindPlotName( ivy_id) + if (ac_id == None): + return None + + return self.plots[ac_id][msg][field] - return self.plots[ac_id][msg][field] - def RemovePlot(self, ivy_id): (ac_id, msg, field) = self.FindPlotName( ivy_id) - if ac_id == None: return + if ac_id == None: + return if (self.x_axis != None) and (self.x_axis.id == ivy_id): self.x_axis = None @@ -319,32 +323,36 @@ class PlotPanel(): IvyUnBindMsg( ivy_id) del self.plots[ac_id][msg][field] if len(self.plots[ac_id][msg]) == 0: - del self.plots[ac_id][msg] + del self.plots[ac_id][msg] def OffsetPlot(self, ivy_id, offset): plot = self.FindPlot( ivy_id) - if plot == None: return - + if plot == None: + return + plot.SetOffset(offset) - print 'panel value: %.2f' % value + print('panel value: %.2f' % value) CalcMinMax(plot) def ScalePlot(self, ivy_id, offset): plot = self.FindPlot( ivy_id) - if plot == None: return - + if plot == None: + return + plot.SetScale(offset) CalcMinMax(plot) def SetRealTime(self, ivy_id, value): plot = self.FindPlot( ivy_id) - if plot == None: return + if plot == None: + return plot.SetRealTime(value) def SetXAxis(self, ivy_id): plot = self.FindPlot( ivy_id) - if plot == None: return + if plot == None: + return self.x_axis = plot @@ -354,7 +362,7 @@ class PlotPanel(): def OnSize(self, size): (width, height) = size if( self.width == width and self.height == height): - return + return self.pixmap = wx.EmptyBitmap(width, height) self.width = width @@ -367,7 +375,7 @@ class PlotPanel(): self.timer.Restart(self.plot_interval) self.frame.SetMinMax(self.min, self.max) self.DrawFrame() - + def DrawFrame(self): dc = wx.ClientDC(self.parent) bdc = wx.BufferedDC( dc, self.pixmap) @@ -378,61 +386,64 @@ class PlotPanel(): title_y = 2 for ac_id in self.plots: - for message in self.plots[ac_id]: - for field in self.plots[ac_id][message]: - plot = self.plots[ac_id][message][field] - if (self.x_axis != None) and (self.x_axis.id == plot.id): continue - title_height = plot.DrawTitle(bdc, 2, self.width, title_y) - plot.DrawCurve(bdc, self.width, self.height, self.margin, self.max, self.min, self.x_axis) + for message in self.plots[ac_id]: + for field in self.plots[ac_id][message]: + plot = self.plots[ac_id][message][field] + if (self.x_axis != None) and (self.x_axis.id == plot.id): + continue + title_height = plot.DrawTitle(bdc, 2, self.width, title_y) + plot.DrawCurve(bdc, self.width, self.height, self.margin, self.max, self.min, self.x_axis) - title_y += title_height + 2 + title_y += title_height + 2 def DrawBackground(self, dc, width, height): - # Time Graduations - dc.SetFont(self.font) + # Time Graduations + dc.SetFont(self.font) - if self.x_axis == None: - t = self.plot_interval * width - t1 = "0.0s" - t2 = "-%.1fs" % (t/2000.0) - t3 = "-%.1fs" % (t/1000.0) - else: - x_max = self.x_axis.x_max - x_min = self.x_axis.x_min - t1 = "%.2f" % x_max - t2 = "%.2f" % (x_min + (x_max-x_min)/2.0) - t3 = "%.2f" % x_min + if self.x_axis == None: + t = self.plot_interval * width + t1 = "0.0s" + t2 = "-%.1fs" % (t/2000.0) + t3 = "-%.1fs" % (t/1000.0) + else: + x_max = self.x_axis.x_max + x_min = self.x_axis.x_min + t1 = "%.2f" % x_max + t2 = "%.2f" % (x_min + (x_max-x_min)/2.0) + t3 = "%.2f" % x_min - (w,h) = dc.GetTextExtent(t1) - dc.DrawText(t1, width-w, height-h) - #(w,h) = dc.GetTextExtent(t2) #save time since h will be the same - dc.DrawText(t2, width/2, height-h) - #(w,h) = dc.GetTextExtent(t3) #save time since h will be the same - dc.DrawText(t3, 0, height-h) + (w,h) = dc.GetTextExtent(t1) + dc.DrawText(t1, width-w, height-h) + #(w,h) = dc.GetTextExtent(t2) #save time since h will be the same + dc.DrawText(t2, width/2, height-h) + #(w,h) = dc.GetTextExtent(t3) #save time since h will be the same + dc.DrawText(t3, 0, height-h) - # Y graduations - if self.max == -1e32: return + # Y graduations + if self.max == -1e32: + return - (_min_, _max_) = (self.min, self.max) - if _max_ < _min_: #prevent divide by zero or inversion - (_min_, _max_) = (-1, 1) - if _max_ == _min_: - (_min_, _max_) = (_max_-0.5, _max_+0.5) - - delta = _max_-_min_ - dy = (height - self.margin*2) / delta - scale = math.log10( delta) - d = math.pow(10.0, math.floor(scale)) - u = d - if delta < 2*d: u=d/5 - elif delta < 5*d: u=d/2 - tick_min =_min_ - math.fmod(_min_, u) - for i in range( int(delta/u) + 1): - tick = tick_min + float(i)*u - s = str(tick) - (w,h) = dc.GetTextExtent(s) - y = height-self.margin-int((tick-_min_)*dy)-h/2 - dc.DrawText(s, 0, y) + (_min_, _max_) = (self.min, self.max) + if _max_ < _min_: #prevent divide by zero or inversion + (_min_, _max_) = (-1, 1) + if _max_ == _min_: + (_min_, _max_) = (_max_-0.5, _max_+0.5) + delta = _max_-_min_ + dy = (height - self.margin*2) / delta + scale = math.log10( delta) + d = math.pow(10.0, math.floor(scale)) + u = d + if delta < 2*d: + u=d/5 + elif delta < 5*d: + u=d/2 + tick_min =_min_ - math.fmod(_min_, u) + for i in range( int(delta/u) + 1): + tick = tick_min + float(i)*u + s = str(tick) + (w,h) = dc.GetTextExtent(s) + y = height-self.margin-int((tick-_min_)*dy)-h/2 + dc.DrawText(s, 0, y) diff --git a/sw/ground_segment/python/real_time_plot/realtimeplotapp.py b/sw/ground_segment/python/real_time_plot/realtimeplotapp.py index dae388ab37..c47d016370 100755 --- a/sw/ground_segment/python/real_time_plot/realtimeplotapp.py +++ b/sw/ground_segment/python/real_time_plot/realtimeplotapp.py @@ -7,10 +7,10 @@ import sys import plotframe modules ={u'PlotFrame': [1, 'Main frame of Application', u'plotframe.py'], - u'messages_xml_map': [0, '', u'messages_xml_map.py'], - u'plotpanel': [0, '', u'plotpanel.py'], - u'realtimeplotapp': [0, '', u'realtimeplotapp.py'], - u'textdroptarget': [0, '', u'textdroptarget.py']} + u'messages_xml_map': [0, '', u'messages_xml_map.py'], + u'plotpanel': [0, '', u'plotpanel.py'], + u'realtimeplotapp': [0, '', u'realtimeplotapp.py'], + u'textdroptarget': [0, '', u'textdroptarget.py']} class RealTimePlotApp(wx.App): def OnInit(self): @@ -20,9 +20,9 @@ class RealTimePlotApp(wx.App): opts, args = getopt.getopt(sys.argv[1:], "p:", ["plot"]) for o,a in opts: - if o in ("-p", "--plot"): - [ac_id, message, field, color, use_x] = a.split(':') - self.main.AddPlot(int(ac_id), message, field, color, bool(int(use_x))) + if o in ("-p", "--plot"): + [ac_id, message, field, color, use_x] = a.split(':') + self.main.AddPlot(int(ac_id), message, field, color, bool(int(use_x))) return True def main(): diff --git a/sw/ground_segment/python/real_time_plot/textdroptarget.py b/sw/ground_segment/python/real_time_plot/textdroptarget.py index e93f48c884..28d3cb2551 100644 --- a/sw/ground_segment/python/real_time_plot/textdroptarget.py +++ b/sw/ground_segment/python/real_time_plot/textdroptarget.py @@ -3,11 +3,11 @@ import wx class TextDropTarget(wx.TextDropTarget): """ This object implements Drop Target functionality for Text """ def __init__(self, reference): - """ Initialize the Drop Target, passing in the Object Reference to - indicate what should receive the dropped text """ - wx.TextDropTarget.__init__(self) - self.reference = reference - + """ Initialize the Drop Target, passing in the Object Reference to + indicate what should receive the dropped text """ + wx.TextDropTarget.__init__(self) + self.reference = reference + def OnDropText(self, x, y, data): - """ When text is dropped, send it to the object specified """ - self.reference.OnDropText(data) + """ When text is dropped, send it to the object specified """ + self.reference.OnDropText(data)