Starting from 2021-07-01, all LRZ GitLab users will be required to explicitly accept the GitLab Terms of Service. Please see the detailed information at https://doku.lrz.de/display/PUBLIC/GitLab and make sure that your projects conform to the requirements.

Commit 949e9d45 authored by Stefan Schuhbaeck's avatar Stefan Schuhbaeck
Browse files

add sub command support to VadereConsole

The VadereConsole command line tool is know able to migrate old
scenario files to a new version. All old capabilities were moved
to the subcommands project-run and suq. See usage below

usage: Vadere [-h] COMMAND ...

Runs the VADERE pedestrian simulator.

optional arguments:
  -h, --help             show this help message and exit

subcommands:
  valid subcommands

  COMMAND
    project-run          This command uses a Vadere Project and runs selected scenario.
    suq                  Run a single scenario file to specify to  fully controll folder structure for input and output.
    migrate              Run migration assistant on single sceanrio file
parent 943f0e87
package org.vadere.simulator.entrypoints;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.Namespace;
import org.apache.log4j.Logger;
import org.vadere.simulator.projects.migration.MigrationAssistant;
import org.vadere.simulator.projects.migration.MigrationOptions;
import org.vadere.util.io.IOUtils;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
public class MigrationSubCommand implements SubCommandRunner{
private final static Logger logger = Logger.getLogger(MigrationSubCommand.class);
@Override
public void run(Namespace ns, ArgumentParser parser) {
Path scenarioFile = Paths.get(ns.getString("scenario-file"));
if (!scenarioFile.toFile().exists() || !scenarioFile.toFile().isFile()){
logger.error("scenario-file does not exist, is not a regular file or you do not have read permissions:" +
scenarioFile.toFile().toString());
System.exit(-1);
}
String outputPathString = ns.getString("output-file");
Version targetVersion = Version.fromString(ns.getString("target-version"));
MigrationAssistant ma = MigrationAssistant.getNewInstance(MigrationOptions.defaultOptions());
String out;
try{
logger.info("Scenario file" + scenarioFile.getFileName().toString());
logger.info("Try to migrate to version " + targetVersion);
out = ma.convertFile(scenarioFile, targetVersion);
if (outputPathString == null){
//overwrite inptu
Files.copy(scenarioFile, addSuffix(scenarioFile, "." + IOUtils.LEGACY_DIR), StandardCopyOption.REPLACE_EXISTING);
logger.info("write new verison to " + scenarioFile.toString());
IOUtils.writeTextFile(scenarioFile.toString(), out);
} else {
logger.info("write new version to " + outputPathString);
IOUtils.writeTextFile(outputPathString, out);
}
} catch (Exception e) {
logger.error("Migration failed", e);
}
}
private Path addSuffix(Path p, String suffix){
Path abs = p.toAbsolutePath();
String filename = abs.getFileName().toString() + suffix;
return abs.getParent().resolve(filename);
}
}
package org.vadere.simulator.entrypoints;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.Namespace;
import org.apache.log4j.Logger;
import org.vadere.simulator.projects.Scenario;
import org.vadere.simulator.projects.ScenarioRun;
import org.vadere.util.io.IOUtils;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Locale;
public class ProjectRunSubCommand implements SubCommandRunner {
private final static Logger logger = Logger.getLogger(ProjectRunSubCommand.class);
@Override
public void run(Namespace ns, ArgumentParser parser) {
Locale.setDefault(Locale.ENGLISH);
String projectPath = ns.getString("project-dir");
String scenarioFile = ns.getString("scenario-file");
Path projectDirectory = Paths.get(projectPath);
Path scenarioFilePath = projectDirectory.resolve(IOUtils.SCENARIO_DIR).resolve(scenarioFile);
if(!Files.exists(projectDirectory)) {
logger.error("The file " + projectDirectory.toFile().toString() + " does not exist");
System.exit(-1);
}
if(!Files.exists(scenarioFilePath)) {
logger.error("The file " + scenarioFilePath.toFile().toString() + " does not exist");
System.exit(-1);
}
logger.info(String.format("Running VADERE on %s...", scenarioFilePath));
try {
Scenario scenario = ScenarioFactory.createVadereWithProjectDirectory(
projectDirectory.toFile().toString(),scenarioFile);
new ScenarioRun(scenario, null).run();
} catch (Exception e) {
logger.error(e);
System.exit(-1);
}
}
}
package org.vadere.simulator.entrypoints;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.Namespace;
/**
* run a sub command from the {@link VadereConsole}. All arguments will be accessible
* throw the Namespace object
*/
public interface SubCommandRunner {
void run(Namespace ns, ArgumentParser parser);
}
package org.vadere.simulator.entrypoints;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.Namespace;
import org.apache.log4j.Logger;
import org.vadere.simulator.projects.Scenario;
import org.vadere.simulator.projects.ScenarioRun;
import java.nio.file.Path;
import java.nio.file.Paths;
public class SuqSubCommand implements SubCommandRunner{
private final static Logger logger = Logger.getLogger(SuqSubCommand.class);
@Override
public void run(Namespace ns, ArgumentParser parser) {
Path outputDir = Paths.get(ns.getString("output-dir"));
if (!outputDir.toFile().exists()){
if ( ! outputDir.toFile().mkdirs() ) {
logger.error("Could not create all necessary directories: " + outputDir.toFile().toString());
System.exit(-1);
} else {
logger.info("Created output directory: " + outputDir.toAbsolutePath().toFile().toString());
}
} else {
logger.info("Use output directory: " + outputDir.toAbsolutePath().toFile().toString());
}
Path scenarioFile = Paths.get(ns.getString("scenario-file"));
if (!scenarioFile.toFile().exists() || !scenarioFile.toFile().isFile()){
logger.error("scenario-file does not exist, is not a regular file or you do not have read permissions: "
+ scenarioFile.toFile().toString());
System.exit(-1);
}
try {
Scenario scenario = ScenarioFactory.createScenarioWithScenarioFilePath(scenarioFile);
new ScenarioRun(scenario, outputDir.toFile().toString(), true, null).run();
} catch (Exception e){
logger.error(e);
System.exit(-1);
}
}
}
package org.vadere.simulator.entrypoints;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Locale;
import org.apache.log4j.Logger;
import org.vadere.simulator.projects.Scenario;
import org.vadere.simulator.projects.ScenarioRun;
import org.vadere.util.io.IOUtils;
import org.vadere.simulator.projects.migration.incidents.VersionBumpIncident;
import net.sourceforge.argparse4j.ArgumentParsers;
import net.sourceforge.argparse4j.impl.Arguments;
import net.sourceforge.argparse4j.inf.ArgumentGroup;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import net.sourceforge.argparse4j.inf.MutuallyExclusiveGroup;
import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
import net.sourceforge.argparse4j.inf.Subparsers;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Locale;
import org.vadere.simulator.entrypoints.Version;
/**
* Provides the possibility to start VADERE in console mode.
*
......@@ -29,60 +27,95 @@ public class VadereConsole {
/**
* @param args
*/
public static void main(String[] args) {
public static void main(String[] args) throws ArgumentParserException {
ArgumentParser parser = createArgumentParser();
Namespace ns = null;
// args = new String[]{"migrate", "-f", "/home/lphex/hm.d/vadere/VadereSimulator/testResources/data/simpleProject/output/test_postvis_2018-01-17_16-56-37.307/test_postvis.scenario"};
try {
ns = parser.parseArgs(args);
Namespace ns = parser.parseArgs(args);
SubCommandRunner sRunner = (SubCommandRunner) ns.get("func");
sRunner.run(ns, parser);
} catch (ArgumentParserException e) {
parser.handleError(e);
System.exit(1);
}
Locale.setDefault(Locale.ENGLISH);
String pathToScenarioFile = ns.getString("scenario-file");
String outputDir = ns.get("output-dir");
if (pathToScenarioFile == null) {
System.err.println("Too few arguments. Exiting.");
parser.printHelp();
System.exit(1);
}
String scenarioFilePath = Paths.get(pathToScenarioFile).toString();
String scenarioFile = Paths.get(pathToScenarioFile).getFileName().toString();
String projectDirectory = Paths.get(ns.getString("scenario-file")).getParent().toString();
if(!Files.exists(Paths.get(projectDirectory, scenarioFile))) {
System.err.println("The file " + Paths.get(projectDirectory, scenarioFile) + " does not exist");
}
logger.info(String.format("Running VADERE on %s...", scenarioFilePath));
try {
Scenario scenario = ScenarioFactory.createVadereWithProjectDirectory(projectDirectory,scenarioFile);
if(outputDir != null) {
new ScenarioRun(scenario, outputDir,null).run();
}
else {
new ScenarioRun(scenario, null).run();
}
} catch (Exception e) {
logger.error(e);
System.exit(-1);
}
}
private static ArgumentParser createArgumentParser() {
ArgumentParser parser = ArgumentParsers.newArgumentParser("Vadere")
.defaultHelp(true)
.description("Runs the VADERE pedestrian simulator.");
parser.addArgument("scenario-file").required(true)
.help("Path to the scenario file.");
parser.addArgument("output-dir").required(false)
.help("Path to the directory of the output. By default this is ./output of the directory of the executable.");
Subparsers subparsers = parser.addSubparsers()
.title("subcommands")
.description("valid subcommands")
.metavar("COMMAND");
// Run Project
Subparser projectRun = subparsers
.addParser("project-run")
.help("This command uses a Vadere Project and runs selected scenario.")
.setDefault("func", new ProjectRunSubCommand());
projectRun.addArgument("--project-dir", "-p")
.required(true)
.type(String.class)
.dest("project-dir")
.help("Path to project directory");
projectRun.addArgument("--scenario-file", "-f")
.required(true)
.type(String.class)
.dest("scenario-file")
.help("Name of Scenario file");
// Run SUQ
Subparser suqRun = subparsers
.addParser("suq")
.help("Run a single scenario file to specify to fully controll folder structure for input and output.")
.setDefault("func", new SuqSubCommand());
suqRun.addArgument("--output-dir", "-o")
.required(false)
.setDefault("output")
.dest("output-dir") // set name in namespace
.type(String.class)
.help("Supply differernt output directory path to use.");
suqRun.addArgument("--scenario-file", "-f")
.required(true)
.type(String.class)
.dest("scenario-file")
.help("List of scenario files to run");
// Run Migration Assistant
Subparser migrationAssistant = subparsers
.addParser("migrate")
.help("Run migration assistant on single sceanrio file")
.setDefault("func", new MigrationSubCommand());
migrationAssistant.addArgument("--scenario-file", "-f")
.required(true)
.type(String.class)
.dest("scenario-file")
.help("The scenario file which should be migrated to new version");
String[] versions = Version.stringValues(Version.NOT_A_RELEASE);
migrationAssistant.addArgument("--target-version", "-V")
.required(false)
.type(String.class)
.dest("target-version")
.choices(versions)
.setDefault(Version.latest().label())
.help("use one of the shown version strings to indicate the target version. If not specified the last version is used");
migrationAssistant.addArgument("--output-file", "-o")
.required(false)
.type(String.class)
.dest("output-file")
.choices(versions)
.help("Write new version to this file. If not specified backup input file and overwrite it.");
return parser;
}
......
......@@ -3,7 +3,9 @@ package org.vadere.simulator.entrypoints;
import org.jetbrains.annotations.NotNull;
import org.vadere.simulator.projects.migration.incidents.VersionBumpIncident;
import java.util.Arrays;
import java.util.Optional;
import java.util.stream.Collectors;
/** Versions in strict order from oldest to newest. */
public enum Version {
......@@ -11,7 +13,8 @@ public enum Version {
UNDEFINED("undefined"),
NOT_A_RELEASE("not a release"),
V0_1("0.1"),
V0_2("0.2");
V0_2("0.2"),
V0_3("0.3");
private String label;
......@@ -28,6 +31,7 @@ public enum Version {
}
public static Version fromString(String versionStr) {
versionStr = versionStr.replace('_', ' ');
for (Version v : values()) {
if (v.label.equals(versionStr))
return v;
......@@ -45,6 +49,15 @@ public enum Version {
throw new IllegalArgumentException("Value not in Version Enumeration " + curr.toString());
}
public static String[] stringValues(){
return Arrays.stream(values()).map(v -> v.label().replace(' ', '_')).toArray(String[]::new);
}
public static String[] stringValues(Version startFrom){
int min = startFrom.ordinal();
return Arrays.stream(values()).filter(v -> v.ordinal() >= min).map(v -> v.label().replace(' ', '_')).toArray(String[]::new);
}
public Version nextVersion(){
int nextId = versionId(this) == (values().length -1) ? versionId(this) : versionId(this) + 1;
return values()[nextId];
......
......@@ -15,6 +15,7 @@ import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.MDC;
import org.jetbrains.annotations.Nullable;
import org.lwjgl.system.CallbackI;
import org.vadere.simulator.control.PassiveCallback;
import org.vadere.simulator.control.Simulation;
import org.vadere.simulator.models.MainModel;
......@@ -55,13 +56,19 @@ public class ScenarioRun implements Runnable {
}
public ScenarioRun(final Scenario scenario, final String outputDir, final RunnableFinishedListener scenarioFinishedListener) {
this(scenario, IOUtils.OUTPUT_DIR, false, scenarioFinishedListener);
}
// if overwriteTimestampSetting is true do note use timestamp in output directory
public ScenarioRun(final Scenario scenario, final String outputDir, boolean overwriteTimestampSetting, final RunnableFinishedListener scenarioFinishedListener) {
this.scenario = scenario;
this.scenarioStore = scenario.getScenarioStore();
this.dataProcessingJsonManager = scenario.getDataProcessingJsonManager();
this.setOutputPaths(Paths.get(outputDir)); // TODO [priority=high] [task=bugfix] [Error?] this is a relative path. If you start the application via eclipse this will be VadereParent/output
this.setOutputPaths(Paths.get(outputDir), overwriteTimestampSetting); // TODO [priority=high] [task=bugfix] [Error?] this is a relative path. If you start the application via eclipse this will be VadereParent/output
this.finishedListener = scenarioFinishedListener;
}
/**
* This method runs a simulation. It must not catch any exceptions! The
* caller (i.e. the calling thread) should catch exceptions and call
......@@ -135,6 +142,14 @@ public class ScenarioRun implements Runnable {
passiveCallbacks.add(pc);
}
public void setOutputPaths(final Path outputPath, boolean overwriteTimestampSetting){
if (overwriteTimestampSetting){
this.outputPath = outputPath;
} else {
setOutputPaths(outputPath);
}
}
public void setOutputPaths(final Path outputPath) {
if (dataProcessingJsonManager.isTimestamped()) {
String dateString = new SimpleDateFormat(IOUtils.DATE_FORMAT).format(new Date());
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment