diff --git a/Varianten/AdapterFIDEROS/resources/input/sensorconfig.xml b/Varianten/AdapterFIDEROS/resources/input/sensorconfig.xml index 940d688f6e21a385f546ab51f3c628388f51035a..3bd937a47a62327c0646189bc73cfd0d7f2de9c9 100644 --- a/Varianten/AdapterFIDEROS/resources/input/sensorconfig.xml +++ b/Varianten/AdapterFIDEROS/resources/input/sensorconfig.xml @@ -1,12 +1,14 @@ <?xml version="1.0"?> <configuration> <sensor type="ray" name="lds_lfcd_sensor"> - <range> - <min>0.3</min> - <max>5.2</max> - </range> - <noise> - <stddev>0.09</stddev> - </noise> + <ray> + <range> + <min>0.3</min> + <max>5.2</max> + </range> + <noise> + <stddev>0.09</stddev> + </noise> + </ray> </sensor> </configuration> diff --git a/Varianten/AdapterFIDEROS/resources/output/turtlebot3_burger.gazebo.xacro b/Varianten/AdapterFIDEROS/resources/output/turtlebot3_burger.gazebo.xacro index db59909444c0a2b3ca9406381ba40019ba288296..1e40bbc64c7e02f18099498b7dff4c245cf67e28 100644 --- a/Varianten/AdapterFIDEROS/resources/output/turtlebot3_burger.gazebo.xacro +++ b/Varianten/AdapterFIDEROS/resources/output/turtlebot3_burger.gazebo.xacro @@ -115,14 +115,14 @@ </horizontal> </scan> <range> - <min>0.120</min> - <max>3.5</max> + <min></min> + <max>5.2</max> <resolution>0.015</resolution> </range> <noise> <type>gaussian</type> <mean>0.0</mean> - <stddev>0.01</stddev> + <stddev>0.09</stddev> </noise> </ray> <plugin name="gazebo_ros_lds_lfcd_controller" filename="libgazebo_ros_laser.so"> diff --git a/Varianten/AdapterFIDEROS/src/Adapter.java b/Varianten/AdapterFIDEROS/src/Adapter.java index 20e7dd67147f65e377669cd1e66b041a43cd8f3b..269ced87849951a26bb607014a1fedbfe8913859 100644 --- a/Varianten/AdapterFIDEROS/src/Adapter.java +++ b/Varianten/AdapterFIDEROS/src/Adapter.java @@ -34,7 +34,7 @@ public class Adapter { } /** - * Executes given XPath expression for elements. + * Executes given XPath expression for elements with JDOM Document as source. * * @param doc The JDOM Document * @param xPath XPath expression @@ -48,6 +48,21 @@ public class Adapter { return result; } + /** + * Executes given XPath expression for elements with Element as source. + * + * @param elem The Element + * @param xPath XPath expression + * @return List with all elements found or empty list if no match found + */ + public static List<Element> xQueryElements(Element elem, String xPath) { + XPathFactory xFactory = XPathFactory.instance(); + XPathExpression<Element> expr = xFactory.compile(xPath, Filters.element()); + List<Element> result = expr.evaluate(elem); + + return result; + } + /** * Executes given XPath expression for attributes. * @@ -102,10 +117,44 @@ public class Adapter { List<Attribute> attributeList2 = element2.getAttributes(); if(!element1.getName().equals(element2.getName())) return false; - if(!attributeList1.equals(attributeList2)) return false; + if(attributeList1.size()!=attributeList2.size()) return false; + for(int i=0; i<attributeList1.size(); i++) { + if(!attributeList1.get(i).getName().equals(attributeList2.get(i).getName())) return false; + if(!attributeList1.get(i).getValue().equals(attributeList2.get(i).getValue())) return false; + } + return true; } + /** + * Recursive replacement of all text values in destElements with their corresponding + * new ones from srcElements. + * (srcElements and destElements must be matching tags!) + * + * TODO maybe add tags that are in srcElements but not yet in destElements + * + * @param srcElements Element list with new values + * @param destElements Element list with values to be replaced + * @return true if reached deepest Element or false if not + */ + public static boolean replace(List<Element> srcElements, List<Element> destElements) { + if(srcElements.isEmpty()&&destElements.isEmpty()) return true; + if(srcElements.isEmpty()^destElements.isEmpty()) { + System.out.println("Error during value replacement: Sensor xml trees have mismatching deph (maybe tags with no value)"); + System.exit(-1); + } + for(Element src : srcElements) { + for(Element dest : destElements) { + if(equalTag(src, dest)) { + boolean deadEnd = replace(src.getChildren(), dest.getChildren()); + if(deadEnd) dest.setText(src.getText()); + break; + } + } + } + return false; + } + /** * @param args */ @@ -165,9 +214,9 @@ public class Adapter { } for(Element cSensor : cSensorList) { - for(Element gSensor : gSensorList) { + for(Element gSensor : gSensorList) { if(equalTag(cSensor, gSensor)) { - //TODO automatischer Abgleich aller cSensor-Informationen mit gSensor und Wertersetzung + replace(cSensor.getChildren(),gSensor.getChildren()); } } } diff --git a/Varianten/FeatureModelConfigurator/src/Configurator.jak b/Varianten/FeatureModelConfigurator/src/Configurator.jak new file mode 100644 index 0000000000000000000000000000000000000000..656bc98e11d9ac55d3c0e8dba95a993cedb171f7 --- /dev/null +++ b/Varianten/FeatureModelConfigurator/src/Configurator.jak @@ -0,0 +1,170 @@ + +import java.util.List; +import java.util.ArrayList; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.*; +import org.jsoup.nodes.Document.OutputSettings; +import org.jsoup.nodes.Document.OutputSettings.Syntax; +import org.jsoup.parser.Parser; + +SoUrCe RooT ConfiguratorMain "../features/ConfiguratorMain/Configurator.jak"; + +/** + * Main class for the car configurator. + * Is refined by modules, which add selected components to component list. + * This class has to save a file containing the configuration + * and launch the test seletion application afterwards. + * + * + * Naming conventions: + * m_: Member variable + * s: String + * n: Integer number (int, long,...) + * f: Floating point number (float, double,...) + * o: Object + * a: Collection (List, Array,...) + * + */ + +abstract class Configurator$$ConfiguratorMain { + //module list + private List m_aModuleList; + //output path + private String m_sOutputPath = "./test.xml"; + //TODO: set this + //path for test case selector, which has to be launched from this application + private String m_sTestCaseSelectorPath; + //TODO: set this + //path for the Gazebo adapter, which has to be launched from this application + private String m_sGazeboAdapterPath; + //TODO: properly set this + //path to the feature model xml + private String m_sFeatureModelPath = "./model.xml"; + //document representation of the feature model + private Document m_oFeatureModelDoc; + //representation of a single module with all of its types + class Module { + String sModuleName; + ArrayList aModuleTypes; + } + + + public static void main(String[] args) { + new Configurator().save(); + } + + public void save() { + //transform list to XML document using jsoup + Document oDoc = Jsoup.parse("<?xml version=\"1.0\"?>\n", "", Parser.xmlParser()); + Element oStruct = new Element("specification"); + oDoc.appendChild(oStruct); + + //if the module list was initialized + if(m_aModuleList!=null) { + for(int i=0; i<m_aModuleList.size(); i++) { + //Add module and tag to Document + Element oModuleElement = new Element("module"); + //Add name + Module oModule = (Module)m_aModuleList.get(i); + oModuleElement.attr("name", oModule.sModuleName); + //Create type String + ArrayList<String> aTypes = oModule.aModuleTypes; + String sTypesString = ""; + //concat String + for(int j=0; j<aTypes.size(); j++) { + sTypesString += aTypes.get(j); + //add comma if it's not the last Type + if(j<aTypes.size()-1) + sTypesString += ", "; + } + oModuleElement.attr("types", sTypesString); + oStruct.appendChild(oModuleElement); + } + } + + //generate xml String + OutputSettings oOutputSettings = new OutputSettings(); + oOutputSettings.syntax(Syntax.xml); + oDoc.outputSettings(oOutputSettings); + String sDoc = oDoc.toString(); + System.out.println(sDoc); + + //save to file + try { + BufferedWriter writer = new BufferedWriter(new FileWriter(m_sOutputPath)); + writer.write(sDoc); + writer.close(); + } + catch (IOException oEx) { + System.out.println(oEx); + } + } + + //get all parents of a given module from the Feature Model file + private Module GetModuleParents(String sModuleName) throws IOException { + Module oModule = new Module(); + //set name + oModule.sModuleName = sModuleName; + //init Doc if not done + if(m_oFeatureModelDoc==null) { + File oModel = new File(m_sFeatureModelPath); + m_oFeatureModelDoc = Jsoup.parse(oModel, "UTF-8"); + } + //should have size 1 + org.jsoup.select.Elements aModuleBuffer = m_oFeatureModelDoc.getElementsByAttributeValue("name", sModuleName); + if(aModuleBuffer.size()>1) { + //somethings wrong + //TODO: properly log this + System.out.println("Found more than one module with the name " + sModuleName); + } + Element oModuleElement = aModuleBuffer.first(); + //get all anchestors + aModuleBuffer = oModuleElement.parents(); + ArrayList<String> aTypes = new ArrayList(); + //itterate through parents of module + for(int i=0; i<aModuleBuffer.size(); i++) { + Element oElement = aModuleBuffer.get(i); + String sElementName = oElement.attr("name"); + //break if we reach the Main class, as there are no types further up + if(sElementName.equals("ConfiguratorMain")) { + break; + } + aTypes.add(sElementName); + } + oModule.aModuleTypes = aTypes; + return oModule; + } + + //add a module name and module type to the feature list. Init list, if not already done + public void addToModuleList(String sModuleName) { + //init List, if not already done + if(m_aModuleList==null) { + m_aModuleList = new ArrayList(); + } + //get the module types + Module oModule; + try { + oModule = GetModuleParents(sModuleName); + } + catch (IOException oEx) { + System.out.print(oEx); + return; + } + m_aModuleList.add(oModule); + } +} + +SoUrCe Waffle "../features/Waffle/Configurator.jak";/** + * TODO description + */ +public class Configurator extends Configurator$$ConfiguratorMain { + public void save() { + Super().addToModuleList("Waffle"); + Super().save(); + } +} \ No newline at end of file