diff --git a/Varianten/AdapterFIDEROS/resources/input/.project b/Varianten/AdapterFIDEROS/resources/input/.project deleted file mode 100644 index 51c04125a58701cd79e952c69e1c90f23aa39ee7..0000000000000000000000000000000000000000 --- a/Varianten/AdapterFIDEROS/resources/input/.project +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<projectDescription> - <name>turtlebots</name> - <comment></comment> - <projects> - </projects> - <buildSpec> - <buildCommand> - <name>de.ovgu.featureide.core.extensibleFeatureProjectBuilder</name> - <arguments> - <dictionary> - <key>build</key> - <value>src</value> - </dictionary> - <dictionary> - <key>composer</key> - <value>de.ovgu.featureide.composer.ahead</value> - </dictionary> - <dictionary> - <key>equations</key> - <value>configs</value> - </dictionary> - <dictionary> - <key>source</key> - <value>features</value> - </dictionary> - </arguments> - </buildCommand> - <buildCommand> - <name>org.eclipse.jdt.core.javabuilder</name> - <arguments> - </arguments> - </buildCommand> - </buildSpec> - <natures> - <nature>org.eclipse.jdt.core.javanature</nature> - <nature>de.ovgu.featureide.core.featureProjectNature</nature> - </natures> -</projectDescription> diff --git a/src/var/FeatureModelConfigurator/configs/config.xml b/src/var/FeatureModelConfigurator/configs/config.xml new file mode 100644 index 0000000000000000000000000000000000000000..d12aa2324d08dba19c6a138868dacb765a25b59e --- /dev/null +++ b/src/var/FeatureModelConfigurator/configs/config.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<configuration> + <feature automatic="selected" name="ConfiguratorMain"/> + <feature automatic="selected" name="Templates"/> + <feature automatic="unselected" name="turtlebot3_burger"/> + <feature automatic="unselected" name="turtlebot3_burger_for_autorace"/> + <feature automatic="unselected" name="turtlebot3_burgertest1"/> + <feature manual="selected" name="turtlebot3_waffle"/> + <feature automatic="unselected" name="turtlebot3_waffle_pi"/> + <feature automatic="selected" name="Sensors"/> + <feature manual="selected" name="NO_CHANGE"/> + <feature automatic="unselected" name="Custom"/> + <feature automatic="unselected" name="Pi_Camera"/> + <feature automatic="unselected" name="imu"/> + <feature automatic="unselected" name="lds_lfcd_sensor"/> + <feature automatic="unselected" name="realsense_R200"/> + <feature automatic="unselected" name="Pi_Camera___turtlebot3_burger_for_autorace"/> + <feature automatic="unselected" name="Pi_Camera___turtlebot3_waffle_pi"/> + <feature automatic="unselected" name="head_rplidar_sensor___turtlebot3_burgertest1"/> + <feature automatic="unselected" name="imu___turtlebot3_burger"/> + <feature automatic="unselected" name="imu___turtlebot3_burger_for_autorace"/> + <feature automatic="unselected" name="imu___turtlebot3_burgertest1"/> + <feature automatic="unselected" name="imu___turtlebot3_waffle"/> + <feature automatic="unselected" name="imu___turtlebot3_waffle_pi"/> + <feature automatic="unselected" name="lds_lfcd_sensor___turtlebot3_burger"/> + <feature automatic="unselected" name="lds_lfcd_sensor___turtlebot3_burger_for_autorace"/> + <feature automatic="unselected" name="lds_lfcd_sensor___turtlebot3_waffle"/> + <feature automatic="unselected" name="lds_lfcd_sensor___turtlebot3_waffle_pi"/> + <feature automatic="unselected" name="realsense_R200___turtlebot3_waffle"/> +</configuration> diff --git a/src/var/FeatureModelConfigurator/configs/test.xml b/src/var/FeatureModelConfigurator/configs/test.xml deleted file mode 100644 index 2346818cebe5c92c872f1136b7c1060e2f9d3646..0000000000000000000000000000000000000000 --- a/src/var/FeatureModelConfigurator/configs/test.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<configuration> - <feature automatic="selected" name="ConfiguratorMain"/> - <feature automatic="selected" name="Templates"/> - <feature automatic="unselected" name="turtlebot3_burger"/> - <feature automatic="unselected" name="turtlebot3_burger_for_autorace"/> - <feature automatic="unselected" name="turtlebot3_burgertest1"/> - <feature manual="selected" name="turtlebot3_waffle"/> - <feature automatic="unselected" name="turtlebot3_waffle_pi"/> - <feature automatic="selected" name="Sensors"/> - <feature manual="selected" name="NO_CHANGE"/> - <feature automatic="unselected" name="Custom"/> - <feature automatic="unselected" name="Pi_Camera"/> - <feature automatic="unselected" name="imu"/> - <feature automatic="unselected" name="lds_lfcd_sensor"/> - <feature automatic="unselected" name="realsense_R200"/> -</configuration> diff --git a/src/var/FeatureModelConfigurator/features/ConfiguratorMain/Adapter.java b/src/var/FeatureModelConfigurator/features/ConfiguratorMain/Adapter.java index 79b93235dc2da251b83332dbaf4874b1531a8dcc..c535d1ad4a9cf07c17492b6f78935f87598491e5 100644 --- a/src/var/FeatureModelConfigurator/features/ConfiguratorMain/Adapter.java +++ b/src/var/FeatureModelConfigurator/features/ConfiguratorMain/Adapter.java @@ -52,7 +52,7 @@ public class Adapter extends XMLHelper { String out_gxPath = getConfigVal(adapterConfig, "output/gazebo_xacro", "path"); String out_uxPath = getConfigVal(adapterConfig, "output/urdf_xacro", "path"); String out_bnPath = getConfigVal(adapterConfig, "output/botname", "path"); - + String in_fmName = getConfigVal(adapterConfig, "input/featuremodel", "name"); String in_gxName = ""; String in_uxName = ""; @@ -60,6 +60,9 @@ public class Adapter extends XMLHelper { String out_uxName = getConfigVal(adapterConfig, "output/urdf_xacro", "name"); String out_bnName = getConfigVal(adapterConfig, "output/botname", "name"); + String scAutoPath = in_scPath+"autogenerated/"; + String scOtherPath = in_scPath+"other/"; + String unwantedPrefix = getConfigVal(adapterConfig, "output/botname", "remove_prefix"); String unwantedSuffix = getConfigVal(adapterConfig, "output/botname", "remove_suffix"); @@ -88,22 +91,44 @@ public class Adapter extends XMLHelper { case "Custom": List<Attribute> sensorList = xQueryAttributes(featureModel, "//sensor/@name"); - List<String> scList = getFileNames(in_scPath); + List<String> scAutoList = getFileNames(scAutoPath); + List<String> scOtherList = getFileNames(scOtherPath); + List<String> scList = new ArrayList<String>(); + scList.addAll(scAutoList); + scList.addAll(scOtherList); + +// for(Attribute sensor : sensorList) { +// boolean inDirectory = false; +// for(String fileName : scList) { +// if(fileName.equals(sensor.getValue()+SC_ENDING)) { +// inDirectory = true; +// } +// } +// if(!inDirectory) { +// System.err.println("Cannot handle \'"+sensor.getValue()+"\': No input file known."); +// System.exit(-1); +// } +// } + for(Attribute sensor : sensorList) { - boolean inDirectory = false; - for(String fileName : scList) { - if(fileName.equals(sensor.getValue()+SC_ENDING)) { - inDirectory = true; - } - } - if(!inDirectory) { + String fileName = sensor.getValue()+SC_ENDING; + List<String> fileMatches= findFile(fileName, in_scPath); + + if(fileMatches.isEmpty()) { System.err.println("Cannot handle \'"+sensor.getValue()+"\': No input file known."); System.exit(-1); } - } - - for(Attribute sensor : sensorList) { - sensorConfigList.add(readXml(in_scPath+sensor.getValue()+SC_ENDING)); + + if(fileMatches.size()==1) { + sensorConfigList.add(readXml(fileMatches.get(0))); + } + else { + System.err.println("Cannot handle \'"+sensor.getValue()+"\': Multiple input files found:"); + for(String match : fileMatches) { + System.err.println("\'"+match+"\'"); + } + System.exit(-1); + } } break; default: diff --git a/src/var/FeatureModelConfigurator/features/ConfiguratorMain/XMLHelper.java b/src/var/FeatureModelConfigurator/features/ConfiguratorMain/XMLHelper.java index 3a1030ba7bc31b32d8a1b0874a934e5ff6803631..588c9b03c628d00683abeb51572c6445b3676783 100644 --- a/src/var/FeatureModelConfigurator/features/ConfiguratorMain/XMLHelper.java +++ b/src/var/FeatureModelConfigurator/features/ConfiguratorMain/XMLHelper.java @@ -83,6 +83,80 @@ public class XMLHelper { return directoryNames; } + /** + * Check whether the given directory exists and if not, create it. + * + * @param path Path to directory as String + * @return false if directory denoted by path does not exist and could not be created; true otherwise + */ + public static boolean checkDirectory(String path) { + File directory = new File(path); + if(!directory.exists()) { + boolean created = directory.mkdir(); + if(!created) { + System.err.println("Error: Directory \'"+directory.getPath()+"\' does not exist and could not be created."); + return false; + } + } + + return true; + } + + /** + * Recursively delete a directory and its contents. + * + * @param path Path to directory as String + */ + public static void deleteDirectory(String path) { + File element = new File(path); + File[] content = element.listFiles(); + if(content != null) { + for(File file : content) { + deleteDirectory(file.getPath()); + } + } + if(!element.delete()) { + System.err.println("Error: Could not delete file/ directory: \'"+element.getPath()+"\'."); + } + } + + /** + * Finds a file by recursive search in the directory given by path. + * + * @param name Name of the file including file ending as String + * @param path Path to directory to be searched as String + * @return path to all file matches as List<String> (e.g. .../sensorconfig/other/imu.xml) + */ + public static List<String> findFile(String name, String path) { + List<String> accumulator = new ArrayList<String>(); + + return findFile(name, path, accumulator); + } + + /** + * Executes file search for findFile(String name, String path). + * + * @param name Name of the file including file ending as String + * @param path Path to directory to be searched as String + * @param result Accumulator for all file matches as List<String> + * @return path to all file matches as list<String> (e.g. .../sensorconfig/other/imu.xml) + */ + private static List<String> findFile(String name, String path, List<String> result) { + File element = new File(path); + File[] content = element.listFiles(); + if(content != null) { + for(File file : content) { + List<String> subResult = findFile(name, path+"/"+file.getName(), result); + result.addAll(subResult); + } + } + if(element.getName().equals(name)) { + result.add(element.getName()); + } + + return result; + } + /** * Executes given XPath expression for elements with JDOM Document as source. * diff --git a/src/var/FeatureModelConfigurator/features/Pi_Camera___turtlebot3_burger_for_autorace/Configurator.jak b/src/var/FeatureModelConfigurator/features/Pi_Camera___turtlebot3_burger_for_autorace/Configurator.jak new file mode 100644 index 0000000000000000000000000000000000000000..e47de5e282964728ee19f47974d114af5f48fb5b --- /dev/null +++ b/src/var/FeatureModelConfigurator/features/Pi_Camera___turtlebot3_burger_for_autorace/Configurator.jak @@ -0,0 +1,9 @@ +/** + * TODO description + */ +public refines class Configurator { + public void save() { + Super().addToModuleList("Pi_Camera___turtlebot3_burger_for_autorace"); + Super().save(); + } +} \ No newline at end of file diff --git a/src/var/FeatureModelConfigurator/features/Pi_Camera___turtlebot3_waffle_pi/Configurator.jak b/src/var/FeatureModelConfigurator/features/Pi_Camera___turtlebot3_waffle_pi/Configurator.jak new file mode 100644 index 0000000000000000000000000000000000000000..d496ca86eb7438580f24986c534dd56b02a0dbf8 --- /dev/null +++ b/src/var/FeatureModelConfigurator/features/Pi_Camera___turtlebot3_waffle_pi/Configurator.jak @@ -0,0 +1,9 @@ +/** + * TODO description + */ +public refines class Configurator { + public void save() { + Super().addToModuleList("Pi_Camera___turtlebot3_waffle_pi"); + Super().save(); + } +} \ No newline at end of file diff --git a/src/var/FeatureModelConfigurator/features/head_rplidar_sensor___turtlebot3_burgertest1/Configurator.jak b/src/var/FeatureModelConfigurator/features/head_rplidar_sensor___turtlebot3_burgertest1/Configurator.jak new file mode 100644 index 0000000000000000000000000000000000000000..1d5d4a5d7378b7c7a91de4e25c9313c43e73367c --- /dev/null +++ b/src/var/FeatureModelConfigurator/features/head_rplidar_sensor___turtlebot3_burgertest1/Configurator.jak @@ -0,0 +1,9 @@ +/** + * TODO description + */ +public refines class Configurator { + public void save() { + Super().addToModuleList("head_rplidar_sensor___turtlebot3_burgertest1"); + Super().save(); + } +} \ No newline at end of file diff --git a/src/var/FeatureModelConfigurator/features/imu___turtlebot3_burger/Configurator.jak b/src/var/FeatureModelConfigurator/features/imu___turtlebot3_burger/Configurator.jak new file mode 100644 index 0000000000000000000000000000000000000000..9b71da33b40344a9535fe4e84fc3d276d29a347c --- /dev/null +++ b/src/var/FeatureModelConfigurator/features/imu___turtlebot3_burger/Configurator.jak @@ -0,0 +1,9 @@ +/** + * TODO description + */ +public refines class Configurator { + public void save() { + Super().addToModuleList("imu___turtlebot3_burger"); + Super().save(); + } +} \ No newline at end of file diff --git a/src/var/FeatureModelConfigurator/features/imu___turtlebot3_burger_for_autorace/Configurator.jak b/src/var/FeatureModelConfigurator/features/imu___turtlebot3_burger_for_autorace/Configurator.jak new file mode 100644 index 0000000000000000000000000000000000000000..f9bb2e58f615c8b27c2334f6f34740c007abc622 --- /dev/null +++ b/src/var/FeatureModelConfigurator/features/imu___turtlebot3_burger_for_autorace/Configurator.jak @@ -0,0 +1,9 @@ +/** + * TODO description + */ +public refines class Configurator { + public void save() { + Super().addToModuleList("imu___turtlebot3_burger_for_autorace"); + Super().save(); + } +} \ No newline at end of file diff --git a/src/var/FeatureModelConfigurator/features/imu___turtlebot3_burgertest1/Configurator.jak b/src/var/FeatureModelConfigurator/features/imu___turtlebot3_burgertest1/Configurator.jak new file mode 100644 index 0000000000000000000000000000000000000000..634c601f1ac3551866911045c8208a31afc32281 --- /dev/null +++ b/src/var/FeatureModelConfigurator/features/imu___turtlebot3_burgertest1/Configurator.jak @@ -0,0 +1,9 @@ +/** + * TODO description + */ +public refines class Configurator { + public void save() { + Super().addToModuleList("imu___turtlebot3_burgertest1"); + Super().save(); + } +} \ No newline at end of file diff --git a/src/var/FeatureModelConfigurator/features/imu___turtlebot3_waffle/Configurator.jak b/src/var/FeatureModelConfigurator/features/imu___turtlebot3_waffle/Configurator.jak new file mode 100644 index 0000000000000000000000000000000000000000..22954e595f0c34dfee1f4b3986c73b99a57f5858 --- /dev/null +++ b/src/var/FeatureModelConfigurator/features/imu___turtlebot3_waffle/Configurator.jak @@ -0,0 +1,9 @@ +/** + * TODO description + */ +public refines class Configurator { + public void save() { + Super().addToModuleList("imu___turtlebot3_waffle"); + Super().save(); + } +} \ No newline at end of file diff --git a/src/var/FeatureModelConfigurator/features/imu___turtlebot3_waffle_pi/Configurator.jak b/src/var/FeatureModelConfigurator/features/imu___turtlebot3_waffle_pi/Configurator.jak new file mode 100644 index 0000000000000000000000000000000000000000..4fbd791a2c1bfc422030cb717d2333ac16de68a4 --- /dev/null +++ b/src/var/FeatureModelConfigurator/features/imu___turtlebot3_waffle_pi/Configurator.jak @@ -0,0 +1,9 @@ +/** + * TODO description + */ +public refines class Configurator { + public void save() { + Super().addToModuleList("imu___turtlebot3_waffle_pi"); + Super().save(); + } +} \ No newline at end of file diff --git a/src/var/FeatureModelConfigurator/features/lds_lfcd_sensor___turtlebot3_burger/Configurator.jak b/src/var/FeatureModelConfigurator/features/lds_lfcd_sensor___turtlebot3_burger/Configurator.jak new file mode 100644 index 0000000000000000000000000000000000000000..8d44c3c9efca9df3712060f68d4e9c1e635a0b97 --- /dev/null +++ b/src/var/FeatureModelConfigurator/features/lds_lfcd_sensor___turtlebot3_burger/Configurator.jak @@ -0,0 +1,9 @@ +/** + * TODO description + */ +public refines class Configurator { + public void save() { + Super().addToModuleList("lds_lfcd_sensor___turtlebot3_burger"); + Super().save(); + } +} \ No newline at end of file diff --git a/src/var/FeatureModelConfigurator/features/lds_lfcd_sensor___turtlebot3_burger_for_autorace/Configurator.jak b/src/var/FeatureModelConfigurator/features/lds_lfcd_sensor___turtlebot3_burger_for_autorace/Configurator.jak new file mode 100644 index 0000000000000000000000000000000000000000..7b76968e53d62cf6492628dfea04ae7664b896ab --- /dev/null +++ b/src/var/FeatureModelConfigurator/features/lds_lfcd_sensor___turtlebot3_burger_for_autorace/Configurator.jak @@ -0,0 +1,9 @@ +/** + * TODO description + */ +public refines class Configurator { + public void save() { + Super().addToModuleList("lds_lfcd_sensor___turtlebot3_burger_for_autorace"); + Super().save(); + } +} \ No newline at end of file diff --git a/src/var/FeatureModelConfigurator/features/lds_lfcd_sensor___turtlebot3_waffle/Configurator.jak b/src/var/FeatureModelConfigurator/features/lds_lfcd_sensor___turtlebot3_waffle/Configurator.jak new file mode 100644 index 0000000000000000000000000000000000000000..dfc19c2add5d5f3af9d0a0fe30739664967c1b0c --- /dev/null +++ b/src/var/FeatureModelConfigurator/features/lds_lfcd_sensor___turtlebot3_waffle/Configurator.jak @@ -0,0 +1,9 @@ +/** + * TODO description + */ +public refines class Configurator { + public void save() { + Super().addToModuleList("lds_lfcd_sensor___turtlebot3_waffle"); + Super().save(); + } +} \ No newline at end of file diff --git a/src/var/FeatureModelConfigurator/features/lds_lfcd_sensor___turtlebot3_waffle_pi/Configurator.jak b/src/var/FeatureModelConfigurator/features/lds_lfcd_sensor___turtlebot3_waffle_pi/Configurator.jak new file mode 100644 index 0000000000000000000000000000000000000000..3ab85a4b1558be1dcaf7b805e5a109f4b3928109 --- /dev/null +++ b/src/var/FeatureModelConfigurator/features/lds_lfcd_sensor___turtlebot3_waffle_pi/Configurator.jak @@ -0,0 +1,9 @@ +/** + * TODO description + */ +public refines class Configurator { + public void save() { + Super().addToModuleList("lds_lfcd_sensor___turtlebot3_waffle_pi"); + Super().save(); + } +} \ No newline at end of file diff --git a/src/var/FeatureModelConfigurator/features/realsense_R200___turtlebot3_waffle/Configurator.jak b/src/var/FeatureModelConfigurator/features/realsense_R200___turtlebot3_waffle/Configurator.jak new file mode 100644 index 0000000000000000000000000000000000000000..9013a074b44c09ae405f0d21fe30b9ed4e406f33 --- /dev/null +++ b/src/var/FeatureModelConfigurator/features/realsense_R200___turtlebot3_waffle/Configurator.jak @@ -0,0 +1,9 @@ +/** + * TODO description + */ +public refines class Configurator { + public void save() { + Super().addToModuleList("realsense_R200___turtlebot3_waffle"); + Super().save(); + } +} \ No newline at end of file diff --git a/src/var/FeatureModelConfigurator/model.xml b/src/var/FeatureModelConfigurator/model.xml index c63c0f7ad9eabc37b6861f39d44e72942f0d8580..73ef3642b20f4977ba6d8a105d9ced93ab92a35b 100644 --- a/src/var/FeatureModelConfigurator/model.xml +++ b/src/var/FeatureModelConfigurator/model.xml @@ -27,6 +27,19 @@ <feature name="imu" /> <feature name="lds_lfcd_sensor" /> <feature name="realsense_R200" /> + <feature name="Pi_Camera___turtlebot3_burger_for_autorace" /> + <feature name="Pi_Camera___turtlebot3_waffle_pi" /> + <feature name="head_rplidar_sensor___turtlebot3_burgertest1" /> + <feature name="imu___turtlebot3_burger" /> + <feature name="imu___turtlebot3_burger_for_autorace" /> + <feature name="imu___turtlebot3_burgertest1" /> + <feature name="imu___turtlebot3_waffle" /> + <feature name="imu___turtlebot3_waffle_pi" /> + <feature name="lds_lfcd_sensor___turtlebot3_burger" /> + <feature name="lds_lfcd_sensor___turtlebot3_burger_for_autorace" /> + <feature name="lds_lfcd_sensor___turtlebot3_waffle" /> + <feature name="lds_lfcd_sensor___turtlebot3_waffle_pi" /> + <feature name="realsense_R200___turtlebot3_waffle" /> </and> </alt> </and> diff --git a/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/Pi_Camera___turtlebot3_burger_for_autorace.xml b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/Pi_Camera___turtlebot3_burger_for_autorace.xml new file mode 100644 index 0000000000000000000000000000000000000000..a1d8f9b7cf4e750ae338d34ede753c4fabcaa482 --- /dev/null +++ b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/Pi_Camera___turtlebot3_burger_for_autorace.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <gazebo reference="camera_rgb_frame"> + <sensor type="camera" name="Pi Camera"> + <always_on>true</always_on> + <visualize>false</visualize> + <camera> + <horizontal_fov>1.085595</horizontal_fov> + <image> + <width>320</width> + <height>240</height> + <format>R8G8B8</format> + </image> + <clip> + <near>0.03</near> + <far>100</far> + </clip> + </camera> + <plugin name="camera_controller" filename="libgazebo_ros_camera.so"> + <alwaysOn>true</alwaysOn> + <updateRate>30.0</updateRate> + <cameraName>camera</cameraName> + <frameName>camera_rgb_optical_frame</frameName> + <imageTopicName>image</imageTopicName> + <cameraInfoTopicName>camera_info</cameraInfoTopicName> + <hackBaseline>0.07</hackBaseline> + <distortionK1>0.0</distortionK1> + <distortionK2>0.0</distortionK2> + <distortionK3>0.0</distortionK3> + <distortionT1>0.0</distortionT1> + <distortionT2>0.0</distortionT2> + </plugin> + </sensor> + </gazebo> +</configuration> diff --git a/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/Pi_Camera___turtlebot3_waffle_pi.xml b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/Pi_Camera___turtlebot3_waffle_pi.xml new file mode 100644 index 0000000000000000000000000000000000000000..6db0669c7a51a7a643854eb5101336af41388133 --- /dev/null +++ b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/Pi_Camera___turtlebot3_waffle_pi.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <gazebo reference="camera_rgb_frame"> + <sensor type="camera" name="Pi Camera"> + <always_on>true</always_on> + <visualize>false</visualize> + <camera> + <horizontal_fov>1.085595</horizontal_fov> + <image> + <width>640</width> + <height>480</height> + <format>R8G8B8</format> + </image> + <clip> + <near>0.03</near> + <far>100</far> + </clip> + </camera> + <plugin name="camera_controller" filename="libgazebo_ros_camera.so"> + <alwaysOn>true</alwaysOn> + <updateRate>30.0</updateRate> + <cameraName>camera</cameraName> + <frameName>camera_rgb_optical_frame</frameName> + <imageTopicName>rgb/image_raw</imageTopicName> + <cameraInfoTopicName>rgb/camera_info</cameraInfoTopicName> + <hackBaseline>0.07</hackBaseline> + <distortionK1>0.0</distortionK1> + <distortionK2>0.0</distortionK2> + <distortionK3>0.0</distortionK3> + <distortionT1>0.0</distortionT1> + <distortionT2>0.0</distortionT2> + </plugin> + </sensor> + </gazebo> +</configuration> diff --git a/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/head_rplidar_sensor___turtlebot3_burgertest1.xml b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/head_rplidar_sensor___turtlebot3_burgertest1.xml new file mode 100644 index 0000000000000000000000000000000000000000..24581912fb04a0caaf0ed6433996b94dfb41fb49 --- /dev/null +++ b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/head_rplidar_sensor___turtlebot3_burgertest1.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <gazebo reference="base_scan"> + <material>Gazebo/FlatBlack</material> + <sensor type="gpu_ray" name="head_rplidar_sensor"> + <pose>0 0 0.06 0 0 0</pose> + <visualize>false</visualize> + <update_rate>40</update_rate> + <ray> + <scan> + <horizontal> + <samples>720</samples> + <resolution>1</resolution> + <min_angle>-3.14159265</min_angle> + <max_angle>3.14159265</max_angle> + </horizontal> + </scan> + <range> + <min>0.2</min> + <max>30.0</max> + <resolution>0.01</resolution> + </range> + <noise> + <type>gaussian</type> + <mean>0.0</mean> + <stddev>0.01</stddev> + </noise> + </ray> + <plugin name="gazebo_ros_head_rplidar_controller" filename="libgazebo_ros_gpu_laser.so"> + <topicName>scan</topicName> + <frameName>laser</frameName> + </plugin> + </sensor> + </gazebo> +</configuration> diff --git a/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/imu___turtlebot3_burger.xml b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/imu___turtlebot3_burger.xml new file mode 100644 index 0000000000000000000000000000000000000000..3143fdd9905a2bac84972e319cec7a36549b2c6b --- /dev/null +++ b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/imu___turtlebot3_burger.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <gazebo reference="imu_link"> + <sensor type="imu" name="imu"> + <always_on>true</always_on> + <visualize>false</visualize> + </sensor> + <material>Gazebo/FlatBlack</material> + </gazebo> +</configuration> diff --git a/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/imu___turtlebot3_burger_for_autorace.xml b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/imu___turtlebot3_burger_for_autorace.xml new file mode 100644 index 0000000000000000000000000000000000000000..3143fdd9905a2bac84972e319cec7a36549b2c6b --- /dev/null +++ b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/imu___turtlebot3_burger_for_autorace.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <gazebo reference="imu_link"> + <sensor type="imu" name="imu"> + <always_on>true</always_on> + <visualize>false</visualize> + </sensor> + <material>Gazebo/FlatBlack</material> + </gazebo> +</configuration> diff --git a/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/imu___turtlebot3_burgertest1.xml b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/imu___turtlebot3_burgertest1.xml new file mode 100644 index 0000000000000000000000000000000000000000..3143fdd9905a2bac84972e319cec7a36549b2c6b --- /dev/null +++ b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/imu___turtlebot3_burgertest1.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <gazebo reference="imu_link"> + <sensor type="imu" name="imu"> + <always_on>true</always_on> + <visualize>false</visualize> + </sensor> + <material>Gazebo/FlatBlack</material> + </gazebo> +</configuration> diff --git a/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/imu___turtlebot3_waffle.xml b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/imu___turtlebot3_waffle.xml new file mode 100644 index 0000000000000000000000000000000000000000..7689837e2fd17f6479c5087e569cd95359f3cbee --- /dev/null +++ b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/imu___turtlebot3_waffle.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <gazebo reference="imu_link"> + <sensor type="imu" name="imu"> + <always_on>true</always_on> + <visualize>false</visualize> + </sensor> + <material>Gazebo/Grey</material> + </gazebo> +</configuration> diff --git a/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/imu___turtlebot3_waffle_pi.xml b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/imu___turtlebot3_waffle_pi.xml new file mode 100644 index 0000000000000000000000000000000000000000..7689837e2fd17f6479c5087e569cd95359f3cbee --- /dev/null +++ b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/imu___turtlebot3_waffle_pi.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <gazebo reference="imu_link"> + <sensor type="imu" name="imu"> + <always_on>true</always_on> + <visualize>false</visualize> + </sensor> + <material>Gazebo/Grey</material> + </gazebo> +</configuration> diff --git a/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/lds_lfcd_sensor___turtlebot3_burger.xml b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/lds_lfcd_sensor___turtlebot3_burger.xml new file mode 100644 index 0000000000000000000000000000000000000000..8383bdc602cde9a4e1f2aefce794978c9f07fc95 --- /dev/null +++ b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/lds_lfcd_sensor___turtlebot3_burger.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <gazebo reference="base_scan"> + <material>Gazebo/FlatBlack</material> + <sensor type="ray" name="lds_lfcd_sensor"> + <pose>0 0 0 0 0 0</pose> + <visualize>false</visualize> + <update_rate>5</update_rate> + <ray> + <scan> + <horizontal> + <samples>360</samples> + <resolution>1</resolution> + <min_angle>0.0</min_angle> + <max_angle>6.28319</max_angle> + </horizontal> + </scan> + <range> + <min>0.120</min> + <max>16</max> + <resolution>0.015</resolution> + </range> + <noise> + <type>gaussian</type> + <mean>0.0</mean> + <stddev>0.01</stddev> + </noise> + </ray> + <plugin name="gazebo_ros_lds_lfcd_controller" filename="libgazebo_ros_laser.so"> + <topicName>scan</topicName> + <frameName>base_scan</frameName> + </plugin> + </sensor> + </gazebo> +</configuration> diff --git a/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/lds_lfcd_sensor___turtlebot3_burger_for_autorace.xml b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/lds_lfcd_sensor___turtlebot3_burger_for_autorace.xml new file mode 100644 index 0000000000000000000000000000000000000000..d45c61c07264a8f9ba86998f76087990f20f627b --- /dev/null +++ b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/lds_lfcd_sensor___turtlebot3_burger_for_autorace.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <gazebo reference="base_scan"> + <material>Gazebo/FlatBlack</material> + <sensor type="ray" name="lds_lfcd_sensor"> + <pose>0 0 0 0 0 0</pose> + <visualize>false</visualize> + <update_rate>5</update_rate> + <ray> + <scan> + <horizontal> + <samples>360</samples> + <resolution>1</resolution> + <min_angle>0.0</min_angle> + <max_angle>6.28319</max_angle> + </horizontal> + </scan> + <range> + <min>0.120</min> + <max>3.5</max> + <resolution>0.015</resolution> + </range> + <noise> + <type>gaussian</type> + <mean>0.0</mean> + <stddev>0.01</stddev> + </noise> + </ray> + <plugin name="gazebo_ros_lds_lfcd_controller" filename="libgazebo_ros_laser.so"> + <topicName>scan</topicName> + <frameName>base_scan</frameName> + </plugin> + </sensor> + </gazebo> +</configuration> diff --git a/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/lds_lfcd_sensor___turtlebot3_waffle.xml b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/lds_lfcd_sensor___turtlebot3_waffle.xml new file mode 100644 index 0000000000000000000000000000000000000000..d45c61c07264a8f9ba86998f76087990f20f627b --- /dev/null +++ b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/lds_lfcd_sensor___turtlebot3_waffle.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <gazebo reference="base_scan"> + <material>Gazebo/FlatBlack</material> + <sensor type="ray" name="lds_lfcd_sensor"> + <pose>0 0 0 0 0 0</pose> + <visualize>false</visualize> + <update_rate>5</update_rate> + <ray> + <scan> + <horizontal> + <samples>360</samples> + <resolution>1</resolution> + <min_angle>0.0</min_angle> + <max_angle>6.28319</max_angle> + </horizontal> + </scan> + <range> + <min>0.120</min> + <max>3.5</max> + <resolution>0.015</resolution> + </range> + <noise> + <type>gaussian</type> + <mean>0.0</mean> + <stddev>0.01</stddev> + </noise> + </ray> + <plugin name="gazebo_ros_lds_lfcd_controller" filename="libgazebo_ros_laser.so"> + <topicName>scan</topicName> + <frameName>base_scan</frameName> + </plugin> + </sensor> + </gazebo> +</configuration> diff --git a/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/lds_lfcd_sensor___turtlebot3_waffle_pi.xml b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/lds_lfcd_sensor___turtlebot3_waffle_pi.xml new file mode 100644 index 0000000000000000000000000000000000000000..d45c61c07264a8f9ba86998f76087990f20f627b --- /dev/null +++ b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/lds_lfcd_sensor___turtlebot3_waffle_pi.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <gazebo reference="base_scan"> + <material>Gazebo/FlatBlack</material> + <sensor type="ray" name="lds_lfcd_sensor"> + <pose>0 0 0 0 0 0</pose> + <visualize>false</visualize> + <update_rate>5</update_rate> + <ray> + <scan> + <horizontal> + <samples>360</samples> + <resolution>1</resolution> + <min_angle>0.0</min_angle> + <max_angle>6.28319</max_angle> + </horizontal> + </scan> + <range> + <min>0.120</min> + <max>3.5</max> + <resolution>0.015</resolution> + </range> + <noise> + <type>gaussian</type> + <mean>0.0</mean> + <stddev>0.01</stddev> + </noise> + </ray> + <plugin name="gazebo_ros_lds_lfcd_controller" filename="libgazebo_ros_laser.so"> + <topicName>scan</topicName> + <frameName>base_scan</frameName> + </plugin> + </sensor> + </gazebo> +</configuration> diff --git a/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/realsense_R200___turtlebot3_waffle.xml b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/realsense_R200___turtlebot3_waffle.xml new file mode 100644 index 0000000000000000000000000000000000000000..53771ede1ae5e3ee00ac84e6cb8c1d4259a578e0 --- /dev/null +++ b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/autogenerated/realsense_R200___turtlebot3_waffle.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <gazebo reference="camera_rgb_frame"> + <sensor type="depth" name="realsense_R200"> + <always_on>true</always_on> + <visualize>false</visualize> + <camera> + <horizontal_fov>1.3439</horizontal_fov> + <image> + <width>1920</width> + <height>1080</height> + <format>R8G8B8</format> + </image> + <depth_camera /> + <clip> + <near>0.03</near> + <far>100</far> + </clip> + </camera> + <plugin name="camera_controller" filename="libgazebo_ros_openni_kinect.so"> + <baseline>0.2</baseline> + <alwaysOn>true</alwaysOn> + <updateRate>30.0</updateRate> + <cameraName>camera</cameraName> + <frameName>camera_rgb_optical_frame</frameName> + <imageTopicName>rgb/image_raw</imageTopicName> + <depthImageTopicName>depth/image_raw</depthImageTopicName> + <pointCloudTopicName>depth/points</pointCloudTopicName> + <cameraInfoTopicName>rgb/camera_info</cameraInfoTopicName> + <depthImageCameraInfoTopicName>depth/camera_info</depthImageCameraInfoTopicName> + <pointCloudCutoff>0.4</pointCloudCutoff> + <hackBaseline>0.07</hackBaseline> + <distortionK1>0.0</distortionK1> + <distortionK2>0.0</distortionK2> + <distortionK3>0.0</distortionK3> + <distortionT1>0.0</distortionT1> + <distortionT2>0.0</distortionT2> + <CxPrime>0.0</CxPrime> + <Cx>0.0</Cx> + <Cy>0.0</Cy> + <focalLength>0</focalLength> + <hackBaseline>0</hackBaseline> + </plugin> + </sensor> + </gazebo> +</configuration> diff --git a/src/var/FeatureModelConfigurator/resources/input/sensorconfig/Pi_Camera.xml b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/other/Pi_Camera.xml similarity index 100% rename from src/var/FeatureModelConfigurator/resources/input/sensorconfig/Pi_Camera.xml rename to src/var/FeatureModelConfigurator/resources/input/sensorconfig/other/Pi_Camera.xml diff --git a/src/var/FeatureModelConfigurator/resources/input/sensorconfig/imu.xml b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/other/imu.xml similarity index 100% rename from src/var/FeatureModelConfigurator/resources/input/sensorconfig/imu.xml rename to src/var/FeatureModelConfigurator/resources/input/sensorconfig/other/imu.xml diff --git a/src/var/FeatureModelConfigurator/resources/input/sensorconfig/lds_lfcd_sensor.xml b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/other/lds_lfcd_sensor.xml similarity index 100% rename from src/var/FeatureModelConfigurator/resources/input/sensorconfig/lds_lfcd_sensor.xml rename to src/var/FeatureModelConfigurator/resources/input/sensorconfig/other/lds_lfcd_sensor.xml diff --git a/src/var/FeatureModelConfigurator/resources/input/sensorconfig/realsense_R200.xml b/src/var/FeatureModelConfigurator/resources/input/sensorconfig/other/realsense_R200.xml similarity index 100% rename from src/var/FeatureModelConfigurator/resources/input/sensorconfig/realsense_R200.xml rename to src/var/FeatureModelConfigurator/resources/input/sensorconfig/other/realsense_R200.xml diff --git a/src/var/FeatureModelConfigurator/src/Adapter.java b/src/var/FeatureModelConfigurator/src/Adapter.java index 79b93235dc2da251b83332dbaf4874b1531a8dcc..c535d1ad4a9cf07c17492b6f78935f87598491e5 100644 --- a/src/var/FeatureModelConfigurator/src/Adapter.java +++ b/src/var/FeatureModelConfigurator/src/Adapter.java @@ -52,7 +52,7 @@ public class Adapter extends XMLHelper { String out_gxPath = getConfigVal(adapterConfig, "output/gazebo_xacro", "path"); String out_uxPath = getConfigVal(adapterConfig, "output/urdf_xacro", "path"); String out_bnPath = getConfigVal(adapterConfig, "output/botname", "path"); - + String in_fmName = getConfigVal(adapterConfig, "input/featuremodel", "name"); String in_gxName = ""; String in_uxName = ""; @@ -60,6 +60,9 @@ public class Adapter extends XMLHelper { String out_uxName = getConfigVal(adapterConfig, "output/urdf_xacro", "name"); String out_bnName = getConfigVal(adapterConfig, "output/botname", "name"); + String scAutoPath = in_scPath+"autogenerated/"; + String scOtherPath = in_scPath+"other/"; + String unwantedPrefix = getConfigVal(adapterConfig, "output/botname", "remove_prefix"); String unwantedSuffix = getConfigVal(adapterConfig, "output/botname", "remove_suffix"); @@ -88,22 +91,44 @@ public class Adapter extends XMLHelper { case "Custom": List<Attribute> sensorList = xQueryAttributes(featureModel, "//sensor/@name"); - List<String> scList = getFileNames(in_scPath); + List<String> scAutoList = getFileNames(scAutoPath); + List<String> scOtherList = getFileNames(scOtherPath); + List<String> scList = new ArrayList<String>(); + scList.addAll(scAutoList); + scList.addAll(scOtherList); + +// for(Attribute sensor : sensorList) { +// boolean inDirectory = false; +// for(String fileName : scList) { +// if(fileName.equals(sensor.getValue()+SC_ENDING)) { +// inDirectory = true; +// } +// } +// if(!inDirectory) { +// System.err.println("Cannot handle \'"+sensor.getValue()+"\': No input file known."); +// System.exit(-1); +// } +// } + for(Attribute sensor : sensorList) { - boolean inDirectory = false; - for(String fileName : scList) { - if(fileName.equals(sensor.getValue()+SC_ENDING)) { - inDirectory = true; - } - } - if(!inDirectory) { + String fileName = sensor.getValue()+SC_ENDING; + List<String> fileMatches= findFile(fileName, in_scPath); + + if(fileMatches.isEmpty()) { System.err.println("Cannot handle \'"+sensor.getValue()+"\': No input file known."); System.exit(-1); } - } - - for(Attribute sensor : sensorList) { - sensorConfigList.add(readXml(in_scPath+sensor.getValue()+SC_ENDING)); + + if(fileMatches.size()==1) { + sensorConfigList.add(readXml(fileMatches.get(0))); + } + else { + System.err.println("Cannot handle \'"+sensor.getValue()+"\': Multiple input files found:"); + for(String match : fileMatches) { + System.err.println("\'"+match+"\'"); + } + System.exit(-1); + } } break; default: diff --git a/src/var/FeatureModelConfigurator/src/XMLHelper.java b/src/var/FeatureModelConfigurator/src/XMLHelper.java index 3a1030ba7bc31b32d8a1b0874a934e5ff6803631..588c9b03c628d00683abeb51572c6445b3676783 100644 --- a/src/var/FeatureModelConfigurator/src/XMLHelper.java +++ b/src/var/FeatureModelConfigurator/src/XMLHelper.java @@ -83,6 +83,80 @@ public class XMLHelper { return directoryNames; } + /** + * Check whether the given directory exists and if not, create it. + * + * @param path Path to directory as String + * @return false if directory denoted by path does not exist and could not be created; true otherwise + */ + public static boolean checkDirectory(String path) { + File directory = new File(path); + if(!directory.exists()) { + boolean created = directory.mkdir(); + if(!created) { + System.err.println("Error: Directory \'"+directory.getPath()+"\' does not exist and could not be created."); + return false; + } + } + + return true; + } + + /** + * Recursively delete a directory and its contents. + * + * @param path Path to directory as String + */ + public static void deleteDirectory(String path) { + File element = new File(path); + File[] content = element.listFiles(); + if(content != null) { + for(File file : content) { + deleteDirectory(file.getPath()); + } + } + if(!element.delete()) { + System.err.println("Error: Could not delete file/ directory: \'"+element.getPath()+"\'."); + } + } + + /** + * Finds a file by recursive search in the directory given by path. + * + * @param name Name of the file including file ending as String + * @param path Path to directory to be searched as String + * @return path to all file matches as List<String> (e.g. .../sensorconfig/other/imu.xml) + */ + public static List<String> findFile(String name, String path) { + List<String> accumulator = new ArrayList<String>(); + + return findFile(name, path, accumulator); + } + + /** + * Executes file search for findFile(String name, String path). + * + * @param name Name of the file including file ending as String + * @param path Path to directory to be searched as String + * @param result Accumulator for all file matches as List<String> + * @return path to all file matches as list<String> (e.g. .../sensorconfig/other/imu.xml) + */ + private static List<String> findFile(String name, String path, List<String> result) { + File element = new File(path); + File[] content = element.listFiles(); + if(content != null) { + for(File file : content) { + List<String> subResult = findFile(name, path+"/"+file.getName(), result); + result.addAll(subResult); + } + } + if(element.getName().equals(name)) { + result.add(element.getName()); + } + + return result; + } + /** * Executes given XPath expression for elements with JDOM Document as source. * diff --git a/src/var/FeatureModelImplGenerator/src/Adapter.java b/src/var/FeatureModelImplGenerator/src/Adapter.java index 79b93235dc2da251b83332dbaf4874b1531a8dcc..c535d1ad4a9cf07c17492b6f78935f87598491e5 100644 --- a/src/var/FeatureModelImplGenerator/src/Adapter.java +++ b/src/var/FeatureModelImplGenerator/src/Adapter.java @@ -52,7 +52,7 @@ public class Adapter extends XMLHelper { String out_gxPath = getConfigVal(adapterConfig, "output/gazebo_xacro", "path"); String out_uxPath = getConfigVal(adapterConfig, "output/urdf_xacro", "path"); String out_bnPath = getConfigVal(adapterConfig, "output/botname", "path"); - + String in_fmName = getConfigVal(adapterConfig, "input/featuremodel", "name"); String in_gxName = ""; String in_uxName = ""; @@ -60,6 +60,9 @@ public class Adapter extends XMLHelper { String out_uxName = getConfigVal(adapterConfig, "output/urdf_xacro", "name"); String out_bnName = getConfigVal(adapterConfig, "output/botname", "name"); + String scAutoPath = in_scPath+"autogenerated/"; + String scOtherPath = in_scPath+"other/"; + String unwantedPrefix = getConfigVal(adapterConfig, "output/botname", "remove_prefix"); String unwantedSuffix = getConfigVal(adapterConfig, "output/botname", "remove_suffix"); @@ -88,22 +91,44 @@ public class Adapter extends XMLHelper { case "Custom": List<Attribute> sensorList = xQueryAttributes(featureModel, "//sensor/@name"); - List<String> scList = getFileNames(in_scPath); + List<String> scAutoList = getFileNames(scAutoPath); + List<String> scOtherList = getFileNames(scOtherPath); + List<String> scList = new ArrayList<String>(); + scList.addAll(scAutoList); + scList.addAll(scOtherList); + +// for(Attribute sensor : sensorList) { +// boolean inDirectory = false; +// for(String fileName : scList) { +// if(fileName.equals(sensor.getValue()+SC_ENDING)) { +// inDirectory = true; +// } +// } +// if(!inDirectory) { +// System.err.println("Cannot handle \'"+sensor.getValue()+"\': No input file known."); +// System.exit(-1); +// } +// } + for(Attribute sensor : sensorList) { - boolean inDirectory = false; - for(String fileName : scList) { - if(fileName.equals(sensor.getValue()+SC_ENDING)) { - inDirectory = true; - } - } - if(!inDirectory) { + String fileName = sensor.getValue()+SC_ENDING; + List<String> fileMatches= findFile(fileName, in_scPath); + + if(fileMatches.isEmpty()) { System.err.println("Cannot handle \'"+sensor.getValue()+"\': No input file known."); System.exit(-1); } - } - - for(Attribute sensor : sensorList) { - sensorConfigList.add(readXml(in_scPath+sensor.getValue()+SC_ENDING)); + + if(fileMatches.size()==1) { + sensorConfigList.add(readXml(fileMatches.get(0))); + } + else { + System.err.println("Cannot handle \'"+sensor.getValue()+"\': Multiple input files found:"); + for(String match : fileMatches) { + System.err.println("\'"+match+"\'"); + } + System.exit(-1); + } } break; default: diff --git a/src/var/FeatureModelImplGenerator/src/ImplGenerator.java b/src/var/FeatureModelImplGenerator/src/ImplGenerator.java index 5e057cbab87e2cb0562d2155af2bec2ac89662a6..d115a04d155e0d42156b980b385af83f046eba59 100644 --- a/src/var/FeatureModelImplGenerator/src/ImplGenerator.java +++ b/src/var/FeatureModelImplGenerator/src/ImplGenerator.java @@ -47,41 +47,23 @@ public class ImplGenerator { private ImplGenerator() { - //check if resources directory exists - File resourcesDir = new File(m_sResourcesDirPath); - if(!resourcesDir.exists()) { - //if not, create it - boolean bCreated = resourcesDir.mkdir(); - if(!bCreated) { - System.out.println("directory " + resourcesDir.getPath() + " could not be created."); - return; - } + //check if resources directory exists and if not, create it + if(!XMLHelper.checkDirectory(m_sResourcesDirPath)) { + return; } - //check if resources/input directory exists - File rInputDir = new File(m_sResourcesDirPath+"/input"); - if(!rInputDir.exists()) { - //if not, create it - boolean bCreated = rInputDir.mkdir(); - if(!bCreated) { - System.out.println("directory " + rInputDir.getPath() + " could not be created."); - return; - } + //check if resources/input directory exists and if not, create it + if(!XMLHelper.checkDirectory(m_sResourcesDirPath+"/input")) { + return; } - //check if resources/output directory exists - File rOutputDir = new File(m_sResourcesDirPath+"/output"); - if(!rOutputDir.exists()) { - //if not, create it - boolean bCreated = rOutputDir.mkdir(); - if(!bCreated) { - System.out.println("directory " + rOutputDir.getPath() + " could not be created."); - return; - } + //check if resources/output directory exists and if not, create it + if(!XMLHelper.checkDirectory(m_sResourcesDirPath+"/output")) { + return; } //autogenerate sensor config files - //SensorConfigSetup oScSetup = new SensorConfigSetup(); + SensorConfigSetup oScSetup = new SensorConfigSetup(); //set up the feature model ModelSetup oMSetup = new ModelSetup(); diff --git a/src/var/FeatureModelImplGenerator/src/ModelSetup.java b/src/var/FeatureModelImplGenerator/src/ModelSetup.java index 3d4e7c13b747b102c78eba6067b7651f9b4c2210..0ead6270bc913cc2a62f12a792bbbbcec11db4e9 100644 --- a/src/var/FeatureModelImplGenerator/src/ModelSetup.java +++ b/src/var/FeatureModelImplGenerator/src/ModelSetup.java @@ -47,19 +47,31 @@ public class ModelSetup extends XMLHelper{ String in_scPath = getConfigVal(ModelSetupConfig, "input/sensorconfig", "path"); String in_gxPath = getConfigVal(ModelSetupConfig, "input/gazebo_xacro", "path"); String out_mPath = getConfigVal(ModelSetupConfig, "output/model", "path"); + String in_mName = getConfigVal(ModelSetupConfig, "input/model", "name"); String out_mName = getConfigVal(ModelSetupConfig, "output/model", "name"); + String scAutoPath = in_scPath+"autogenerated/"; + String scOtherPath = in_scPath+"other/"; + //Declare Document. Document model = readXml(in_mPath+in_mName); //Get sensorconfig- and gazebomodel file names. - //in_scPath and in_gxPath may contain other files that will be filtered out! - List<String> scDirectoryFilesList = getFileNames(in_scPath); - List<String> scList = new ArrayList<String>(); - for(String s : scDirectoryFilesList) { + //scAutoPath, scOtherPath and in_gxPath may contain other files that will be filtered out! + List<String> scAutoDirectoryFilesList = getFileNames(scAutoPath); + List<String> scAutoList = new ArrayList<String>(); + for(String s : scAutoDirectoryFilesList) { + if(s.endsWith(SC_ENDING)) { + scAutoList.add(s); + } + } + + List<String> scOtherDirectoryFilesList = getFileNames(scOtherPath); + List<String> scOtherList = new ArrayList<String>(); + for(String s : scOtherDirectoryFilesList) { if(s.endsWith(SC_ENDING)) { - scList.add(s); + scOtherList.add(s); } } @@ -74,16 +86,37 @@ public class ModelSetup extends XMLHelper{ //Check whether feature input was empty. //It is possible to have no sensors (so you can build a custom bot with no sensors), //but at least one bot template is required! - if(scList.isEmpty()) { - System.out.println("Warning: No sensorconfig \'"+SC_ENDING+"\' files found in \'"+in_scPath+"\'."); + if(scAutoList.isEmpty()) { + System.out.println("Warning: No sensorconfig \'"+SC_ENDING+"\' files found in \'"+scAutoPath+"\'."); + } + if(scOtherList.isEmpty()) { + System.out.println("Warning: No sensorconfig \'"+SC_ENDING+"\' files found in \'"+scOtherPath+"\'."); } if(gxList.isEmpty()) { System.err.println("Error: No gazebo model \'"+GX_ENDING+"\' files found in \'"+in_gxPath+"\'."); System.exit(-1); } + //Check whether sensorconfigs in .../autogenerated/ and .../other/ have distinct names. + //FeatureIDE does not allow for duplicate feature names. + List<String> testList = new ArrayList<String>(); + testList.addAll(scAutoList); + testList.addAll(scOtherList); + Collections.sort(testList); + if(!testList.isEmpty()) { + for(int i = 0; i < testList.size()-1; i++) { + String name1 = testList.get(i); + String name2 = testList.get(i+1); + if(name1.equals(name2)) { + System.err.println("Error: At least two sensorconfig files have the same name: \'"+name1+"\'"); + System.exit(-1); + } + } + } + //Sort features alphabetically (ascending order; upper case first; then lower case). - Collections.sort(scList); + Collections.sort(scAutoList); + Collections.sort(scOtherList); Collections.sort(gxList); //############################################### @@ -111,16 +144,22 @@ public class ModelSetup extends XMLHelper{ } //Add features to model. - for(String sc : scList) { + for(String gx : gxList) { + String featureName = gx.substring(0, gx.length() - GX_ENDING.length()); + Element feature = new Element("feature").setAttribute("name", featureName); + templates.addContent(feature); + } + + for(String sc : scOtherList) { String featureName = sc.substring(0, sc.length() - SC_ENDING.length()); Element feature = new Element("feature").setAttribute("name", featureName); custom.addContent(feature); } - for(String gx : gxList) { - String featureName = gx.substring(0, gx.length() - GX_ENDING.length()); + for(String sc : scAutoList) { + String featureName = sc.substring(0, sc.length() - SC_ENDING.length()); Element feature = new Element("feature").setAttribute("name", featureName); - templates.addContent(feature); + custom.addContent(feature); } //############################################### diff --git a/src/var/FeatureModelImplGenerator/src/SensorConfigSetup.java b/src/var/FeatureModelImplGenerator/src/SensorConfigSetup.java index 45a6475450f9a9c520f19513ce443ca5da41b054..2e29aef96a9af85a426f1d2c6b5bf3cc7c02ecb8 100644 --- a/src/var/FeatureModelImplGenerator/src/SensorConfigSetup.java +++ b/src/var/FeatureModelImplGenerator/src/SensorConfigSetup.java @@ -29,38 +29,15 @@ public class SensorConfigSetup extends XMLHelper{ } /** - * Check whether the given directory exists and if not, create it. + * Takes a file name and alters it so a FeatureIDE model will accept it. + * FeatureIDE says it only takes the following regex as valid feature names: ^[a-zA-Z]+\w*$ + * This function will replace all \W characters (no word character) with '_'. * - * @param path Path to directory as String + * @param name Name to be changes as String. + * @return Corrected name */ - private static void createDirectory(String path) { - File directory = new File(path); - if(!directory.exists()) { - boolean created = directory.mkdir(); - if(!created) { - System.err.println("Error: Directory \'"+directory.getPath()+"\' does not exist and could not be created."); - System.exit(-1); - } - } - } - - /** - * Recursively delete a directory and its contents. - * - * @param path Path to directory as String - */ - private static void deleteDirectory(String path) { - File directory = new File(path); - File[] content = directory.listFiles(); - if(content != null) { - for(File file : content) { - deleteDirectory(file.getPath()); - } - } - if(!directory.delete()) { - System.err.println("Error: Could not delete file/ directory: \'"+directory.getPath()+"\'."); - } - + private static String fixName(String name) { + return name.replaceAll("\\W", "_"); } /** @@ -79,12 +56,17 @@ public class SensorConfigSetup extends XMLHelper{ //Get modelsetup.config values. String in_scPath = getConfigVal(ModelSetupConfig, "input/sensorconfig", "path");///TODO String in_gxPath = getConfigVal(ModelSetupConfig, "input/gazebo_xacro", "path"); - String out_mPath = getConfigVal(ModelSetupConfig, "output/model", "path"); - //Declare Document. - //Document xy = + String scAutoPath = in_scPath+"autogenerated/"; + String scOtherPath = in_scPath+"other/"; + + //Declare Documents and their corresponding file names. + List<Document> gazeboModelList = new ArrayList<Document>(); + List<String> gazeboModelNamesList = new ArrayList<String>(); + List<Document> sensorConfigList = new ArrayList<Document>(); + List<String> sensorConfigNamesList = new ArrayList<String>(); - //Get sensorconfig- and gazebomodel file names. + //Get gazebomodel file names. //in_gxPath may contain other files that will be filtered out! List<String> gxDirectoryFilesList = getFileNames(in_gxPath); List<String> gxList = new ArrayList<String>(); @@ -96,32 +78,76 @@ public class SensorConfigSetup extends XMLHelper{ //Check whether input was empty. if(gxList.isEmpty()) { - System.err.println("Error: No gazebo model \'"+GX_ENDING+"\' files found in \'"+in_gxPath+"\'. Could not autogenerate sensorconfig files"); - System.exit(-1); + System.out.println("Warning: No gazebo model \'"+GX_ENDING+"\' files found in \'"+in_gxPath+"\'. Could not autogenerate sensorconfig files"); + } + + //Get all gazebomodel files as List<Document>. + for(String gx : gxList) { + gazeboModelList.add(readXml(in_gxPath+gx)); + gazeboModelNamesList.add(gx.substring(0, gx.length() - GX_ENDING.length())); } //############################################### //######### Check directories ################### - String scAuto = in_scPath+"autogenerated/"; - String scOther = in_scPath+"other/"; - - createDirectory(in_scPath); - if((new File(scAuto)).exists()) { - deleteDirectory(scAuto); + checkDirectory(in_scPath); + if((new File(scAutoPath)).exists()) { + deleteDirectory(scAutoPath); } - createDirectory(scAuto); - createDirectory(scOther); + checkDirectory(scAutoPath); + checkDirectory(scOtherPath); //############################################### //######### Generate sensorconfigs ############## - + for(int i = 0; i < gazeboModelList.size(); i++) { + Document gazeboModel = gazeboModelList.get(i); + String gazeboModelName = gazeboModelNamesList.get(i); + Namespace NS = gazeboModel.getRootElement().getNamespace("xacro"); + + //Replace all $(arg ...) variables with their concrete values. + List<Element> argList = xQueryElements(gazeboModel, "//xacro:arg", NS); + for(Element arg : argList) { + String variable = "$(arg "+arg.getAttributeValue("name")+")"; + String concreteValue = arg.getAttributeValue("default"); + List<Element> occurrenceList = xQueryElements(gazeboModel, "//*[text()='"+variable+"']"); + for(Element occurrence : occurrenceList) { + occurrence.setText(concreteValue); + } + } + + //Get all existing sensors in gazebomodel. + List<Element> sensorList = xQueryElements(gazeboModel, "//sensor"); + + //Create a new sensorconfig for each of them. + for(Element sensor : sensorList) { + Element entry = sensor.getParentElement(); + if(entry.getName().equals("gazebo")) { + entry.detach(); + + Element sensorConfigRoot = new Element("configuration"); + Document sensorConfig = new Document(sensorConfigRoot); + sensorConfig.getRootElement().addContent(entry); + + sensorConfigList.add(sensorConfig); + String sensorConfigName = fixName(sensor.getAttributeValue("name"))+"___"+fixName(gazeboModelName); + sensorConfigNamesList.add(sensorConfigName); + } + else { + System.out.println("Found a <sensor> element that does not have a <gazebo> element as immediate parent. It was ignored, as this input is unexpected."); + } + } + } //############################################### //######### Output result ####################### - //saveAsXml(model, out_mPath+out_mName); + for(int i = 0; i < sensorConfigList.size(); i++) { + Document sensorConfig = sensorConfigList.get(i); + String sensorConfigName = sensorConfigNamesList.get(i); + + saveAsXml(sensorConfig, scAutoPath+sensorConfigName+SC_ENDING); + } //############################################### } catch (JDOMException | IOException e) { diff --git a/src/var/FeatureModelImplGenerator/src/XMLHelper.java b/src/var/FeatureModelImplGenerator/src/XMLHelper.java index 3a1030ba7bc31b32d8a1b0874a934e5ff6803631..588c9b03c628d00683abeb51572c6445b3676783 100644 --- a/src/var/FeatureModelImplGenerator/src/XMLHelper.java +++ b/src/var/FeatureModelImplGenerator/src/XMLHelper.java @@ -83,6 +83,80 @@ public class XMLHelper { return directoryNames; } + /** + * Check whether the given directory exists and if not, create it. + * + * @param path Path to directory as String + * @return false if directory denoted by path does not exist and could not be created; true otherwise + */ + public static boolean checkDirectory(String path) { + File directory = new File(path); + if(!directory.exists()) { + boolean created = directory.mkdir(); + if(!created) { + System.err.println("Error: Directory \'"+directory.getPath()+"\' does not exist and could not be created."); + return false; + } + } + + return true; + } + + /** + * Recursively delete a directory and its contents. + * + * @param path Path to directory as String + */ + public static void deleteDirectory(String path) { + File element = new File(path); + File[] content = element.listFiles(); + if(content != null) { + for(File file : content) { + deleteDirectory(file.getPath()); + } + } + if(!element.delete()) { + System.err.println("Error: Could not delete file/ directory: \'"+element.getPath()+"\'."); + } + } + + /** + * Finds a file by recursive search in the directory given by path. + * + * @param name Name of the file including file ending as String + * @param path Path to directory to be searched as String + * @return path to all file matches as List<String> (e.g. .../sensorconfig/other/imu.xml) + */ + public static List<String> findFile(String name, String path) { + List<String> accumulator = new ArrayList<String>(); + + return findFile(name, path, accumulator); + } + + /** + * Executes file search for findFile(String name, String path). + * + * @param name Name of the file including file ending as String + * @param path Path to directory to be searched as String + * @param result Accumulator for all file matches as List<String> + * @return path to all file matches as list<String> (e.g. .../sensorconfig/other/imu.xml) + */ + private static List<String> findFile(String name, String path, List<String> result) { + File element = new File(path); + File[] content = element.listFiles(); + if(content != null) { + for(File file : content) { + List<String> subResult = findFile(name, path+"/"+file.getName(), result); + result.addAll(subResult); + } + } + if(element.getName().equals(name)) { + result.add(element.getName()); + } + + return result; + } + /** * Executes given XPath expression for elements with JDOM Document as source. *