[tools] Phyton-based Airframe File Editor

Squashed commit of the following:

commit 67afebebdf3a2743b6c97ebac1a267c16aeff9b6
Author: Felix Ruess <felix.ruess@gmail.com>
Date:   Mon Sep 30 18:02:23 2013 +0200

    [tools] airframe editor: minor fixes and pep8

commit f7ea77c13ea6d9df89afc098d033dae88d876b7d
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Tue Mar 5 17:41:22 2013 +0100

    New Group identification tag

commit 0c20d2824ec4739954e7ee6930ec9c99966683fa
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Tue Mar 5 16:28:47 2013 +0100

    Delete old grouping tags to avoid growing in time

commit 43902b8810711dba167c87fc9c35babc9c833a31
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Tue Mar 5 16:01:09 2013 +0100

    Better xml loading error handling

commit a2590591708787fa2ba13b69dc8f64ea932d5979
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Tue Mar 5 14:13:28 2013 +0100

    Run xml_airframe standalone for batch conversions

commit 1092bf0db9785e9434e41a69a460e6e00a19e81e
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Tue Mar 5 14:07:48 2013 +0100

    Save DTD path and initial comment from airframe.xml

commit bf2a10603e20a66d7de3f6a097a4c5f091695047
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Tue Mar 5 10:12:15 2013 +0100

    Do not forget airframe name

commit 44ddc63a181219c74e9a25d4c3a2a6a1e96acdb8
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Fri Feb 15 16:28:48 2013 +0100

    Commenting change in airframe

commit 172724335a78abd140f442518857e65a46e5ed97
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Fri Feb 15 16:26:26 2013 +0100

    XML Structure

commit 15e6cc8daf05b00d64b93f86a1b1322d991fffad
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Fri Feb 15 09:26:12 2013 +0100

    MenuBar

commit 896303a1717e9efa5824bc3765267c55434ee0b9
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Thu Feb 14 22:39:11 2013 +0100

    auto-grep

commit 808339828f7e6c69d92112f91064716b59f66cc5
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Wed Feb 13 21:55:21 2013 +0100

    Search for defines

commit 28bfce357b7b047c54d960dda992acd12a5a898e
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Wed Feb 13 20:35:23 2013 +0100

    Show section content - editable

commit 2dbfc5aed93d0f336c6509cab74d94f97c4b9d61
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Wed Feb 13 18:54:26 2013 +0100

    Boards

commit 97ebb81240795ba4740018f17fc31e9a695111db
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Wed Feb 13 17:53:35 2013 +0100

    Finally Fixed XML Output

commit b27ddfb401abf8c7aa81770db9f0410ab66da27f
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Wed Feb 13 16:25:38 2013 +0100

    Better Size Management

commit e7fa8a66786d2ad15236211e80852f188a608b0f
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Wed Feb 13 07:54:12 2013 +0100

    Rename

commit 129bdda836b8d7d3064f7b79e54a7cae8a29bae9
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Wed Feb 13 02:16:14 2013 +0100

    Generate Nice and Grouped XML

commit b6fc1f53ade5fc7f0e6b6cdadc9d07ab1307c414
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Wed Feb 13 01:24:22 2013 +0100

    Editor Update

commit 996e70fe0db7737325ec24b0960e504aff58b105
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Wed Feb 13 00:28:34 2013 +0100

    Restructure

commit abcaedb90ae5f3de1ea520e354337008c06f3db2
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Tue Feb 12 18:48:13 2013 +0100

    Automatic Airframe Re-Origanization

commit 2faeb74a7d604d3a07b647692737af063bf9e2f6
Author: Felix Ruess <felix.ruess@gmail.com>
Date:   Tue Feb 12 17:40:38 2013 +0100

    fix typo

commit c991428d6411277a4d293a2e8e50b4da091ede96
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Tue Feb 12 16:54:17 2013 +0100

    Pretty Print

commit 8eac7f8f2cfe8b5eeaf4e2e90ec470be0a56dacc
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Tue Feb 12 15:38:19 2013 +0100

    Open Files

commit daf9a4723d71222e111b1c1274e45273eb275029
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Tue Feb 12 14:54:45 2013 +0100

    Open File

commit fb0a2eb10451bb19989ef35311ac10d69ba0f937
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Tue Feb 12 14:47:15 2013 +0100

    Cleanup

commit 6d7aeef7bf31e7c05738d8ccd90e91468bae24db
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Tue Feb 12 14:29:33 2013 +0100

    Grouped paparazzi

commit 2ec961acd51fd64337697152c92f49b82c560048
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Tue Feb 12 13:29:32 2013 +0100

    paparazzi.py

commit d0cb88cbbb7dc763d5a5545948c494fcad906b26
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Tue Feb 12 10:10:57 2013 +0100

    Attempt to add comments in xml

commit c10455d93e700438c91e34198d96bda5791d5aa9
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Tue Feb 12 10:10:33 2013 +0100

    Paparazzi-Common

commit 74214985f45b4c590af3702c2ec6a9e351b45895
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Tue Feb 12 09:54:15 2013 +0100

    Rename for Clarity

commit 8ce5ecbd2477dffba9c06ca8e51357e83783aaef
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Tue Feb 12 09:48:54 2013 +0100

    Module for gui stuff

commit 293d776409c150e826b37d815a6198176fc2cacb
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Tue Feb 12 09:12:26 2013 +0100

    Read SubBlocks

commit f166629579088fb905dfdfdfcc52632c524eb506
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Mon Feb 11 23:15:33 2013 +0100

    DataGrid

commit ab06a1e1f6a50aaa1fe92109993fe3ea80ba3cdb
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Mon Feb 11 21:59:50 2013 +0100

    Solve Merge Errors

commit 90e3f626ad46657ebc9720e15de8b39e327afeea
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Mon Feb 11 21:27:52 2013 +0100

    TreeView

commit 730cb7960d9c291ec3a9a2cdd3d05606c0d7c2b7
Author: Felix Ruess <felix.ruess@gmail.com>
Date:   Mon Feb 11 19:02:42 2013 +0100

    get paparazzi_home from env, indentation 4spaces as in pep8

commit 2df5c4c972ec994fe3d42810e26c3b4166acc381
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Mon Feb 11 17:49:50 2013 +0100

    Airframe Editor

commit f71e2dd434121ecc16dbd2c682e1b6f89281388b
Author: Christophe De Wagter <dewagter@gmail.com>
Date:   Mon Feb 11 15:55:02 2013 +0100

    Phyton-based Airframe File Editor
This commit is contained in:
Christophe De Wagter
2014-05-18 14:07:57 +02:00
committed by Felix Ruess
parent 81d3759f73
commit 84be7ddba2
6 changed files with 733 additions and 2 deletions
+2 -2
View File
@@ -73,8 +73,8 @@
<define name="PITCH_NEUTRAL_DEFAULT" value="0"/>
</section>
<!-- Local magnetic field -->
<section name="AHRS" prefix="AHRS_">
<!-- Local magnetic field -->
<define name="H_X" value="0.51562740288882"/>
<define name="H_Y" value="-0.05707735220832"/>
<define name="H_Z" value="0.85490967783446"/>
@@ -236,7 +236,7 @@
<load name="nav_line.xml"/>
</modules>
<!-- --------------------------------------------------------------------------- -->
<!--+-+-+-+-+-+-+- PHOTOGRAMMETRY -+-+-+-+-+-+-+-->
<section name="Photogrammetry" prefix="PHOTOGRAMMETRY_">
+358
View File
@@ -0,0 +1,358 @@
#!/usr/bin/env python
from __future__ import print_function
import pygtk
import gtk
pygtk.require('2.0')
from os import path
# Owm Modules
import gui_dialogs
import xml_airframe
import paparazzi
# Airframe File
airframe_file = path.join(paparazzi.airframes_dir, "examples/quadrotor_lisa_m_2_pwm_spektrum.xml")
class AirframeEditor:
# General Functions
def load_airframe_xml(self):
global airframe_file
self.tvcolumn.set_title(airframe_file.replace(paparazzi.airframes_dir, ""))
[e, self.xml, self.xml_header] = xml_airframe.load(airframe_file)
if e:
gui_dialogs.error_loading_xml(e.__str__())
raise e
xml_airframe.fill_tree(self.xml, self.treestore)
def update_combo(self, combo, c_list):
combo.set_sensitive(False)
combo.get_model().clear()
for i in c_list:
combo.append_text(i)
combo.set_active(0)
combo.set_sensitive(True)
# CallBack Functions
def find_firmwares(self, widget):
list_of_firmwares = paparazzi.get_list_of_firmwares()
self.update_combo(self.firmwares_combo, list_of_firmwares)
def find_modules(self, widget):
list_of_modules = paparazzi.get_list_of_modules()
self.update_combo(self.modules_combo, list_of_modules)
def find_subsystems(self, widget):
self.textbox.set_text(self.firmwares_combo.get_active_text())
list_of_subsystems = paparazzi.get_list_of_subsystems(self.firmwares_combo.get_active_text())
self.update_combo(self.subsystems_combo, list_of_subsystems)
def find_boards(self, widget):
list_of_boards = paparazzi.get_list_of_boards()
self.update_combo(self.boards_combo, list_of_boards)
def find_module_defines(self, widget):
mod = paparazzi.get_module_information(self.modules_combo.get_active_text())
print(mod.description)
txt = mod.description + "\n"
for d in mod.defines:
txt += "define: " + d[0].__str__() + " = " + d[1].__str__() + "; [" + d[2].__str__() + "] // " + d[3].__str__() + "\n"
for c in mod.configures:
txt += "configure: " + c[0].__str__() + " = " + c[1].__str__() + "; [" + c[2].__str__() + "] // " + c[3].__str__() + "\n"
self.text_box.set_text(txt)
self.gridstore.clear()
for d in mod.defines:
self.gridstore.append(["define", d[0], d[1], d[2], d[3]])
def reorganize_xml(self, widget):
self.xml = xml_airframe.reorganize_airframe_xml(self.xml)
xml_airframe.fill_tree(self.xml, self.treestore)
def about(self, widget):
gui_dialogs.about(paparazzi.home_dir)
def open(self, widget):
global airframe_file
filename = gui_dialogs.filechooser(paparazzi.airframes_dir)
if filename == "":
print("No file selected")
return
airframe_file = filename
self.load_airframe_xml()
def search(self, widget):
ret = paparazzi.search(self.textbox.get_text())
self.text_box.set_text(ret)
print(ret)
# Tree Callbacks
def select_section(self, widget):
#get data from highlighted selection
treeselection = self.datagrid.get_selection()
(model, row_iter) = treeselection.get_selected()
if row_iter is not None:
name_of_data = self.gridstore.get_value(row_iter, 1)
#print("Selected ",name_of_data)
self.textbox.set_text(name_of_data)
# xml_airframe.defines(self.treestore.get_value(row_iter, 1), self.gridstore)
def select(self, widget):
#get data from highlighted selection
treeselection = self.treeview.get_selection()
(model, row_iter) = treeselection.get_selected()
if row_iter is not None:
name_of_data = self.treestore.get_value(row_iter, 0)
#print("Selected ",name_of_data)
self.textbox.set_text(name_of_data)
xml_airframe.defines(self.treestore.get_value(row_iter, 1), self.gridstore)
# Constructor Functions
def fill_tree_from_airframe(self):
# create a TreeStore with one string column to use as the model
self.treestore = gtk.TreeStore(str, object)
# create the TreeView using treestore
self.treeview = gtk.TreeView(self.treestore)
# create the TreeViewColumn to display the data
self.tvcolumn = gtk.TreeViewColumn('')
# add self.tvcolumn to treeview
self.treeview.append_column(self.tvcolumn)
self.treeview.connect("cursor-changed", self.select)
self.cell = gtk.CellRendererText()
self.tvcolumn.pack_start(self.cell, True)
self.tvcolumn.add_attribute(self.cell, 'text', 0)
self.treeview.set_reorderable(True)
def fill_datagrid_from_section(self):
# create a TreeStore with one string column to use as the model
self.gridstore = gtk.ListStore(str, str, str, str, str)
self.datagrid = gtk.TreeView(self.gridstore)
self.type_column = gtk.TreeViewColumn('Type')
self.name_column = gtk.TreeViewColumn('Name')
self.value_column = gtk.TreeViewColumn('Value')
self.unit_column = gtk.TreeViewColumn('Unit')
self.desc_column = gtk.TreeViewColumn('Description')
self.datagrid.append_column(self.type_column)
self.datagrid.append_column(self.name_column)
self.datagrid.append_column(self.value_column)
self.datagrid.append_column(self.unit_column)
self.datagrid.append_column(self.desc_column)
self.datagrid.connect("cursor-changed", self.select_section)
self.type_cell = gtk.CellRendererText()
self.type_cell.Editable = False
self.name_cell = gtk.CellRendererText()
self.name_cell.Editable = False
self.value_cell = gtk.CellRendererText()
self.value_cell.Editable = True
self.value_cell.set_property("editable", True)
self.unit_cell = gtk.CellRendererText()
self.unit_cell.Editable = False
self.desc_cell = gtk.CellRendererText()
self.desc_cell.Editable = False
self.type_column.pack_start(self.type_cell, True)
self.type_column.add_attribute(self.type_cell, 'text', 0)
self.name_column.pack_start(self.name_cell, True)
self.name_column.add_attribute(self.name_cell, 'text', 1)
self.value_column.pack_start(self.value_cell, True)
self.value_column.add_attribute(self.value_cell, 'text', 2)
self.unit_column.pack_start(self.unit_cell, True)
self.unit_column.add_attribute(self.unit_cell, 'text', 3)
self.desc_column.pack_start(self.desc_cell, True)
self.desc_column.add_attribute(self.desc_cell, 'text', 4)
self.datagrid.set_search_column(1)
self.name_column.set_sort_column_id(0)
self.datagrid.set_reorderable(True)
def destroy(self, widget, data=None):
gtk.main_quit()
def __init__(self):
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.set_title("Paparazzi Airframe File Editor")
self.my_vbox = gtk.VBox()
# MenuBar
mb = gtk.MenuBar()
# File
filemenu = gtk.Menu()
# File Title
filem = gtk.MenuItem("File")
filem.set_submenu(filemenu)
openm = gtk.MenuItem("Open")
openm.connect("activate", self.open)
filemenu.append(openm)
exitm = gtk.MenuItem("Exit")
exitm.connect("activate", gtk.main_quit)
filemenu.append(exitm)
mb.append(filem)
# Help
helpmenu = gtk.Menu()
# Help Title
helpm = gtk.MenuItem("Help")
helpm.set_submenu(helpmenu)
aboutm = gtk.MenuItem("About")
aboutm.connect("activate", self.about)
helpmenu.append(aboutm)
mb.append(helpm)
self.my_vbox.pack_start(mb, False)
##### Buttons
self.btnExit = gtk.Button("Exit")
self.btnExit.connect("clicked", self.destroy)
self.btnExit.set_tooltip_text("Close application")
self.btnOpen = gtk.Button("Open")
self.btnOpen.connect("clicked", self.open)
self.btnRun = gtk.Button("Reorganize XML")
self.btnRun.connect("clicked", self.reorganize_xml)
self.btnFirmwares = gtk.Button("Firmwares")
self.btnFirmwares.connect("clicked", self.find_firmwares)
self.btnSubSystem = gtk.Button("SubSystems")
self.btnSubSystem.connect("clicked", self.find_subsystems)
self.btnModules = gtk.Button("Add Modules")
self.btnModules.connect("clicked", self.find_modules)
self.btnModuleDefines = gtk.Button("Define")
self.btnModuleDefines.connect("clicked", self.find_module_defines)
self.btnAbout = gtk.Button("About")
self.btnAbout.connect("clicked", self.about)
self.toolbar = gtk.HBox()
self.toolbar.pack_start(self.btnOpen)
self.toolbar.pack_start(self.btnRun)
self.toolbar.pack_start(self.btnAbout)
self.toolbar.pack_start(self.btnExit)
self.my_vbox.pack_start(self.toolbar, False)
self.firmwares_combo = gtk.combo_box_entry_new_text()
self.find_firmwares(self.firmwares_combo)
self.firmwares_combo.connect("changed", self.find_subsystems)
self.subsystems_combo = gtk.combo_box_entry_new_text()
self.boards_combo = gtk.combo_box_entry_new_text()
self.find_boards(self.boards_combo)
self.firmwarebar = gtk.HBox()
self.firmwarebar.pack_start(self.btnFirmwares)
self.firmwarebar.pack_start(self.btnSubSystem)
self.firmwarebar.pack_start(self.firmwares_combo)
self.firmwarebar.pack_start(self.boards_combo)
self.firmwarebar.pack_start(self.subsystems_combo)
self.modules_combo = gtk.combo_box_entry_new_text()
self.find_modules(self.modules_combo)
self.modules_combo.connect("changed", self.find_module_defines)
#self.modulebar = gtk.HBox()
self.firmwarebar.pack_start(self.btnModules)
self.firmwarebar.pack_start(self.btnModuleDefines)
self.firmwarebar.pack_start(self.modules_combo)
#self.my_vbox.pack_start(self.modulebar)
self.my_vbox.pack_start(self.firmwarebar, False)
##### Middle
self.editor = gtk.HBox()
self.fill_tree_from_airframe()
self.scrolltree = gtk.ScrolledWindow()
self.scrolltree.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.scrolltree.add(self.treeview)
self.scrolltree.set_size_request(400,600)
self.editor.pack_start(self.scrolltree)
self.fill_datagrid_from_section()
self.datagrid.set_size_request(900, 600)
self.editor.pack_start(self.datagrid)
self.my_vbox.pack_start(self.editor)
self.text_box = gtk.Label("")
self.text_box.set_size_request(600, 1000)
self.scrolltext = gtk.ScrolledWindow()
self.scrolltext.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.scrolltext.add_with_viewport(self.text_box)
self.scrolltext.set_size_request(400, 100)
self.my_vbox.pack_start(self.scrolltext)
self.load_airframe_xml()
##### Bottom
self.searchbar = gtk.HBox()
self.textbox = gtk.Entry()
#self.textbox.connect("changed",self.textchanged)
self.btnSearch = gtk.Button("Search...")
self.btnSearch.connect("clicked", self.search)
self.searchbar.pack_start(self.textbox)
self.searchbar.pack_start(self.btnSearch)
self.my_vbox.pack_start(self.searchbar, False)
self.window.add(self.my_vbox)
self.window.show_all()
self.window.connect("destroy", self.destroy)
def main(self):
gtk.main()
if __name__ == "__main__":
import sys
if len(sys.argv) > 1:
airframe_file = sys.argv[1]
gui = AirframeEditor()
gui.main()
+56
View File
@@ -0,0 +1,56 @@
#!/usr/bin/env python
from __future__ import print_function
import gtk
from os import path
if gtk.pygtk_version < (2, 3, 90):
print("Please upgrade your pygtk")
raise SystemExit
def filechooser(pathname):
dialog = gtk.FileChooserDialog("Open ...", None,
gtk.FILE_CHOOSER_ACTION_OPEN,
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
gtk.STOCK_OPEN, gtk.RESPONSE_OK))
dialog.set_default_response(gtk.RESPONSE_OK)
dialog.set_current_folder(pathname)
filter = gtk.FileFilter()
filter.set_name("Airframe File")
filter.add_pattern("*.xml")
dialog.add_filter(filter)
response = dialog.run()
filename = ""
if response == gtk.RESPONSE_OK:
filename = dialog.get_filename()
elif response == gtk.RESPONSE_CANCEL:
print("No file selected")
return filename
def error_loading_xml(s):
err_msg = gtk.MessageDialog(None, gtk.DIALOG_DESTROY_WITH_PARENT,
gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE,
"Error Loading XML: " + s)
err_msg.run()
err_msg.destroy()
def about(home):
about_d = gtk.AboutDialog()
about_d.set_program_name("Paparazzi Airframe Editor")
about_d.set_version("0.1")
about_d.set_copyright("(c) GPL v2")
about_d.set_comments("Airframe Editor")
about_d.set_website("http://paparazzi.github.io")
about_d.set_logo(gtk.gdk.pixbuf_new_from_file(path.join(home, "data/pictures/penguin_icon.png")))
about_d.run()
about_d.destroy()
+95
View File
@@ -0,0 +1,95 @@
#!/usr/bin/env python
from __future__ import print_function
import glob
from collections import namedtuple
from os import path, getenv
#from subprocess import call
import commands
import lxml.etree as ET
# if PAPARAZZI_HOME not set, then assume the tree containing this
# file is a reasonable substitute
home_dir = getenv("PAPARAZZI_HOME", path.normpath(path.join(
path.dirname(path.abspath(__file__)), '../../../')))
# Directories
firmwares_dir = path.join(home_dir, "conf/firmwares/")
modules_dir = path.join(home_dir, "conf/modules/")
airframes_dir = path.join(home_dir, "conf/airframes/")
boards_dir = path.join(home_dir, "conf/boards/")
# Structures
PprzModule = namedtuple("PprzModule", "description defines configures")
# List Of Stuff
def get_list_of_files(directory, extension):
mylist = glob.glob(path.join(directory, "*" + extension))
mylist.sort()
ret = []
for it in mylist:
ret.append( it.replace(directory, "").replace(extension, ""))
return ret
def get_list_of_modules():
return get_list_of_files( modules_dir, ".xml")
def get_list_of_firmwares():
return get_list_of_files( firmwares_dir, ".makefile")
def get_list_of_boards():
return get_list_of_files( boards_dir, ".makefile")
def get_list_of_subsystems(firmware):
subsys_dir = path.join( firmwares_dir, "subsystems/" + firmware + "/")
# \todo how about shared
#subsys_dir = path.join( firmwares_dir, "subsystems/shared/" )
return get_list_of_files(subsys_dir, ".makefile")
def get_list_of_servo_drivers():
# \todo where do we know this?
return ["Ppm", "Asctec", "Scilab"]
def get_module_information(module_name):
str_desc = ""
lst_def = []
lst_conf = []
try:
xml = ET.parse(path.join(modules_dir, module_name + ".xml"))
root = xml.getroot().find("doc")
str_desc = root.find("description").text
for block in root.iter("define"):
lst_def.append([block.get("name"), block.get("value"), block.get("unit"), block.get("description")])
for block in root.iter("configure"):
lst_conf.append([block.get("name"), block.get("value"), block.get("unit"), block.get("description")])
except (IOError, ET.XMLSyntaxError) as e:
print(e.__str__())
return PprzModule(description=str_desc, defines=lst_def, configures=lst_conf)
def search(string):
#return call(["grep", "-r", string , home_dir + "/sw/airborne/"])
#return system("grep -r " + string + " " + home_dir + "/sw/airborne/")
cmd = "grep -r " + string + " " + home_dir + "/sw/airborne/"
status, output = commands.getstatusoutput(cmd)
return output.replace(home_dir + "/sw/airborne/", "")
if __name__ == '__main__':
print("====HOME==== ", home_dir)
print("----MODULES---- ", modules_dir)
print(get_list_of_modules())
for mod in get_list_of_modules():
print(mod, " ---> ", get_module_information(mod))
print("----FIRMWARES---- ", firmwares_dir)
print(get_list_of_firmwares())
for firm in get_list_of_firmwares():
print(firm, " ---> ", get_list_of_subsystems(firm))
print("shared", " ---> ", get_list_of_subsystems("shared"))
print("----BOARDS---- ", firmwares_dir)
print(get_list_of_boards())
+195
View File
@@ -0,0 +1,195 @@
#!/usr/bin/env python
from __future__ import print_function
import lxml.etree as ET
import StringIO
import xml_common
import paparazzi
def find_and_add(source, target, search):
temp = source.getroot().findall("./" + search)
for t in temp:
xml_common.indent(t, 1)
target.extend(temp)
def find_and_add_sections_with_name(source, target, find_name):
temp = source.getroot().findall("./*[@name='" + find_name + "']")
for t in temp:
xml_common.indent(t, 1)
target.extend(temp)
group_identification_string = " ************************* "
def find_or_add_group(source, target, search):
groupname = group_identification_string + search + group_identification_string
target.append(ET.Comment(groupname))
for block in source.getroot():
if isinstance(block, ET._Comment):
if block.__str__() == "<!--" + groupname + "-->":
source.getroot().remove(block)
def reorganize_airframe_xml(airframe_xml):
some_file_like_object = StringIO.StringIO("<airframe/>")
airframe_xml_tree = ET.parse(some_file_like_object)
airframe = airframe_xml_tree.getroot()
if 'name' not in airframe_xml.getroot().attrib:
print("Airframe has no name!")
else:
airframe.set('name', airframe_xml.getroot().get('name'))
find_or_add_group(airframe_xml, airframe, "FIRMWARE")
find_and_add(airframe_xml, airframe, "firmware")
find_and_add_sections_with_name(airframe_xml, airframe, "AUTOPILOT")
find_or_add_group(airframe_xml, airframe, "MODULES")
find_and_add(airframe_xml, airframe, "modules")
find_or_add_group(airframe_xml, airframe, "ACTUATORS")
find_and_add(airframe_xml, airframe, "servos")
find_and_add(airframe_xml, airframe, "commands")
find_and_add(airframe_xml, airframe, "ap_only_commands")
find_and_add(airframe_xml, airframe, "rc_commands")
find_and_add_sections_with_name(airframe_xml, airframe, "AUTO1")
find_and_add_sections_with_name(airframe_xml, airframe, "SERVO_MIXER_GAINS")
find_and_add_sections_with_name(airframe_xml, airframe, "MIXER")
find_and_add_sections_with_name(airframe_xml, airframe, "MIXING")
find_and_add(airframe_xml, airframe, "command_laws")
find_and_add_sections_with_name(airframe_xml, airframe, "TRIM")
find_and_add_sections_with_name(airframe_xml, airframe, "FAILSAFE")
find_or_add_group(airframe_xml, airframe, "SENSORS")
find_and_add_sections_with_name(airframe_xml, airframe, "ADC")
find_and_add_sections_with_name(airframe_xml, airframe, "INFRARED")
find_and_add_sections_with_name(airframe_xml, airframe, "IMU")
find_and_add_sections_with_name(airframe_xml, airframe, "AHRS")
find_and_add_sections_with_name(airframe_xml, airframe, "INS")
find_and_add_sections_with_name(airframe_xml, airframe, "XSENS")
find_or_add_group(airframe_xml, airframe, "GAINS")
# Fixedwing
find_and_add_sections_with_name(airframe_xml, airframe, "HORIZONTAL CONTROL")
find_and_add_sections_with_name(airframe_xml, airframe, "VERTICAL CONTROL")
find_and_add_sections_with_name(airframe_xml, airframe, "AGGRESSIVE")
# Rotorcraft
find_and_add_sections_with_name(airframe_xml, airframe, "STABILIZATION_RATE")
find_and_add_sections_with_name(airframe_xml, airframe, "STABILIZATION_ATTITUDE")
find_and_add_sections_with_name(airframe_xml, airframe, "GUIDANCE_V")
find_and_add_sections_with_name(airframe_xml, airframe, "GUIDANCE_H")
find_or_add_group(airframe_xml, airframe, "MISC")
find_and_add(airframe_xml, airframe, "*")
xml_common.indent(airframe)
temp = airframe.findall("./*")
for t in temp:
t.tail = "\n\n "
#print(etree.tostring(airframe))
#ET.ElementTree(airframe_xml_tree).write('test.xml')
return airframe_xml_tree
def get_airframe_header(airframe_file):
try:
with open(airframe_file) as inputFileHandle:
fullfile = inputFileHandle.read()
pos = fullfile.find("<airframe")
if pos > 0:
return fullfile[0:pos]
else:
return ""
except IOError:
return ""
def add_text_before_file(text_file, new_string):
try:
fullfile = ""
with open(text_file) as inputFileHandle:
fullfile = inputFileHandle.read()
inputFileHandle.close()
with open(text_file, 'w') as outputFileHandle:
outputFileHandle.write(new_string)
outputFileHandle.write(fullfile)
outputFileHandle.close()
except IOError:
return
def load(airframe_file):
try:
my_xml = ET.parse(airframe_file)
return [None, my_xml, get_airframe_header(airframe_file)]
except (IOError, ET.XMLSyntaxError, ET.XMLSyntaxError) as e:
print(" ERROR: Loading XML failed: ")
print(e)
quit()
def fill_tree_children(block, tree, parent):
for elem in block:
ename = elem.get("name")
if ename is None:
ename = ""
# Only add sub-blocks if there are children
if len(elem) or ((block.tag != "section") & (block.tag != "load")):
if not isinstance(elem, ET._Comment):
piter = tree.append(parent, [elem.tag.__str__() + " " + ename, elem])
fill_tree_children(elem, tree, piter)
def fill_tree(my_xml, tree):
root = my_xml.getroot()
tree.clear()
add_place = None
for block in root:
if not isinstance(block, ET._Comment):
name = block.get("name")
if name is None:
name = ""
# print(block.tag.__str__() + " " + name)
piter = tree.append(add_place, [block.tag.__str__() + " " + name, block])
fill_tree_children(block, tree, piter)
else:
add_place = tree.append(None, [block.__str__().replace("<!--" + group_identification_string, "[").replace(
group_identification_string + "-->", "]"), block])
def defines(elem, grid):
grid.clear()
for e in elem.findall("./define"):
grid.append(["define", e.get("name"), e.get("value"), e.get("unit"), e.get("description")])
for e in elem.findall("./configure"):
grid.append(["configure", e.get("name"), e.get("value"), e.get("unit"), e.get("description")])
if __name__ == '__main__':
import sys
outputfile = 'test.xml'
if len(sys.argv) > 1:
airframe_file = sys.argv[1]
if len(sys.argv) > 2:
outputfile = sys.argv[2]
if len(sys.argv) > 3:
outputfile = airframe_file
else:
airframe_file = "../../../conf/airframes/CDW/yapa_xsens.xml"
print(airframe_file)
[e, airframe, hdr] = load(airframe_file)
xml = reorganize_airframe_xml(airframe)
ET.ElementTree(xml.getroot()).write(outputfile)
add_text_before_file(outputfile, hdr)
+27
View File
@@ -0,0 +1,27 @@
from __future__ import print_function
def indent(elem, level=0, more_sibs=False):
i = "\n"
num_kids = len(elem)
if level:
i += (level-1) * ' '
#print(level, elem.tag, num_kids, more_sibs)
if num_kids:
if not elem.text or not elem.text.strip():
elem.text = i + " "
if level:
elem.text += ' '
count = 0
for kid in elem:
indent(kid, level+1, count < num_kids - 1)
count += 1
if not elem.tail or not elem.tail.strip():
elem.tail = i
if more_sibs:
elem.tail += ' '
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = i
if more_sibs:
elem.tail += ' '