Commit dd62dfb7 authored by Benedikt Zoennchen's avatar Benedikt Zoennchen
Browse files

Merge branch 'master' of https://gitlab.lrz.de/vadere/vadere

parents 96414568 d4ec9665
......@@ -44,6 +44,7 @@ VadereModelCalibration/**/output
VadereModelTests/**/legacy
VadereUtils/output/**
VadereModelTests/*_private
**/current_commit_hash.txt
# Operating system files
.DS_Store
......@@ -53,3 +54,7 @@ VadereModelTests/*_private
**/output/
**/legacy/
**/*_private/
# Vadere Cache
**/__cache__
**/vadere-server-output
\ No newline at end of file
......@@ -25,6 +25,7 @@ variables:
VADERE_DEPLOYMENT_BASE_URL: "http://www.vadere.org/builds"
VADERE_PACKAGE_NAME_BRANCHES: "vadere.${CI_COMMIT_REF_NAME}.${CI_RUNNER_TAGS}.zip"
VADERE_PACKAGE_NAME_RELEASES: "vadere.${CI_COMMIT_TAG}.${CI_RUNNER_TAGS}.zip"
EIKMESH_PACKAGE_NAME_BRANCHES: "eikmesh.${CI_COMMIT_REF_NAME}.${CI_RUNNER_TAGS}.zip"
# Stage Definitions
# Watch out: integration tests and the seed tests run after deployment, because
......@@ -81,6 +82,8 @@ stages:
- mvn -Dmaven.test.skip=true package
- python3 -m zipfile -c ${VADERE_PACKAGE_NAME_BRANCHES} CHANGELOG.md README.md VadereModelTests/ VadereGui/target/vadere-gui.jar VadereSimulator/target/vadere-console.jar
- scp ${VADERE_PACKAGE_NAME_BRANCHES} di49mur@webdev-mwn.lrz.de:~/webserver/htdocs/builds/master/${VADERE_PACKAGE_NAME_BRANCHES}
- python3 -m zipfile -c ${EIKMESH_PACKAGE_NAME_BRANCHES} VadereMeshing/README.md VadereMeshing/target/meshing-0.1-SNAPSHOT.jar
- scp ${EIKMESH_PACKAGE_NAME_BRANCHES} di49mur@webdev-mwn.lrz.de:~/webserver/htdocs/builds/master/eikmesh/${EIKMESH_PACKAGE_NAME_BRANCHES}
only:
refs:
- master
......
......@@ -6,15 +6,46 @@
### Added
- single step mode in GUI: Allows the user to step through the simulation one
### Changed
## v1.2 (2019-07-13)
### Added
- VadereServer:
- Introducing TraCI server implementation for Vadere to allow remote control
of Vaderes simulation loop.
- VadereManager/target/vadere-server.jar will open a TCP socket and waits
for connection request.
- FloorField Caching:
- CellGrid based floorfields can be loaded from a persisted cache file.
- Added attributes:
- `cacheType: [NO_CACHE|TXT_CACHE|BIN_CACHE]`
- `cacheDir: ""` relative path
- Cache files will be saved in a `__cache__` directory beside (sibling) the
scenario file. With `cacheDir` it is possible to create some structure within
the cache directory. Important: If `cacheDir` is an absolute path the cache
file will not be placed in `__cache__`.
- A TXT_CACHE type will save the CellGrid in a human readable form (CSV) and
BIN_CACHE will use a simple binary format for better performance and space
reasons.
- TikzGenerator:
- add configuration to show all traces of pedestrians, even if they
left the simulation. Config: PostVis -> `Show all Trajectories on Snapshot`
- add named coordinate for each scenario element. The coordinate represents the
centroid point of the polygon and can be used as a point for relative placement
of labels.
- introduced id for reference: Source `src_XXX`, Target `trg_XXX`, AbsorbingArea `absorb_XXX`
Obstacels `obs_XXX`, Stairs `str_XXX`, MeasurementArea `mrmtA_XXX`
- single step mode in GUI: Allows the user to step through the simulation one
step at a time to identify bugs.
- simplify obstacles (with undo support): Merge multiple obstacles based on the
- simplify obstacles (with undo support): Merge multiple obstacles based on the
convex hull their points create. The merge can be undon
- add features to open street map (osm) importer:
- add features to open street map (osm) importer:
- import 'open' paths as polygons with a specified width. With this it is
possible to create walls or subway entrance
- add option to include osm ids into each obstacle created
`PostVis` added functionalities:
- the PostVis works now on the basis of simulation time instead of time steps. Agents' position will be interpolated.
- the user can jump to a specific simulation time
......@@ -24,6 +55,11 @@
### Changed
- version migration ensures that new attributes in the scenario file will be added
with default values if no specific actions are defined in a Transformation class.
- TikzGenerator: style information for pedestrians are moved to dedicated style
classes to simplify changes in generated tikz files.
## v1.0 (2019-06-13)
### Added
......@@ -56,7 +92,7 @@
- `VadereConsole`: Add option `--logname <filename>` to specify the name for the log file.
Please note that the log file `log.out` is always written (because this file is configured
in the `log4j.properties` of each Vadere module (i.e., "gui", "meshing", ...). (c61a3946: Simulator)
- New outputprocessors
- New outputprocessors
* mainly for the BHM: QueueWidthProcessor (to evaluate queueWidth) and PedestrianBehaviorProcessor (evaluate behavior: step / tangential step / sideways step / wait)
* solely for the OSM: PedestrianFootStepProcessor (logs every step instead of the positions at each time step )
......@@ -84,7 +120,7 @@
- `GUI`:
- improved coloring
- `OutputFile`: Distinguish between indices (rows) and headers (columns), in code and with a new checkbox that when enables allow to write meta-data into output files. Furthermore, resolve naming conflicts (if they occur) in headers of output files (see #201).
- `OutputFile`: Distinguish between indices (rows) and headers (columns), in code and with a new checkbox that when enables allow to write meta-data into output files. Furthermore, resolve naming conflicts (if they occur) in headers of output files (see #201).
### Changed
......@@ -95,7 +131,7 @@
- Header in output file have now the following form "[NAME]-PID[ID]". This avoids name conflicts and makes mapping to the relevant processor easy and fast.
- Migration to Java 11 (OpenJDK).
- Removed directory `Documentation/version-control` which contained the Git hooks. The Git hooks are not required anymore. Instead, added `git rev-parse HEAD` to file `VadereSimulator/pom.xml` to create `VadereSimulator/resources/current_commit_hash.txt` during each build via `mvn compile`.
**Note:** The file `current_commit_hash.txt` is created during Maven's validation phase, i.e., before the actual build.
**Note:** The file `current_commit_hash.txt` is created during Maven's validation phase, i.e., before the actual build.
## v0.6 (2018-09-07)
......
package org.vadere.annotation.traci.client;
import com.google.auto.service.AutoService;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.MirroredTypeException;
import javax.tools.JavaFileObject;
@SupportedAnnotationTypes("org.vadere.annotation.traci.client.TraCIApi")
@SupportedSourceVersion(SourceVersion.RELEASE_11)
@AutoService(Processor.class)
public class ClientAnnotationProcessor extends AbstractProcessor {
private StringBuilder apiMembers;
private StringBuilder apiInit;
private StringBuilder apiMapping;
private StringBuilder apiAbstract;
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
apiMembers = new StringBuilder();
apiInit = new StringBuilder();
apiMapping = new StringBuilder();
apiAbstract = new StringBuilder();
// see SupportedAnnotationTypes (here only TraCIApi)
for (TypeElement annotation : annotations) {
Set<? extends Element> annotatedElements =
roundEnv.getElementsAnnotatedWith(annotation)
.stream()
.filter(e -> e.getKind().isClass()
&& !e.getKind().equals(ElementKind.ENUM)
&& !e.getModifiers().contains(Modifier.ABSTRACT)
)
.collect(Collectors.toSet());
if (annotatedElements.isEmpty())
continue;
for (Element annotatedElement : annotatedElements) {
try {
writeApiClass(annotatedElement);
} catch (IOException e) {
e.printStackTrace();
}
}
}
try {
TypeElement element = processingEnv.getElementUtils().
getTypeElement("org.vadere.manager.client.AbstractTestClient");
if (element == null)
writeAbstractTestClient();
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
protected void writeAbstractTestClient() throws IOException {
JavaFileObject jFile = processingEnv.getFiler().createSourceFile("AbstractTestClient");
try (PrintWriter writer = new PrintWriter(jFile.openWriter())){
writer.append("package org.vadere.manager.client; ").println();
writer.println();
writer.append("import org.vadere.manager.TraCISocket;").println();
writer.append("import org.vadere.manager.client.ConsoleReader;").println();
writer.append("import java.io.IOException;").println();
writer.println();
writer.append("public abstract class AbstractTestClient {").println();
writer.append(apiMembers.toString()).println();
writer.append("\tpublic AbstractTestClient() { }").println();
writer.println();
writer.append("\tpublic void init(TraCISocket socket, ConsoleReader consoleReader){").println();
writer.append(apiInit.toString());
writer.println();
writer.append(apiMapping.toString());
writer.append("\t}").println();
writer.println();
writer.append(apiAbstract.toString());
writer.println();
writer.append("}").println();
}
}
protected void writeApiClass(Element apiClass) throws IOException {
TraCiApiWrapper traCIApi = new TraCiApiWrapper(apiClass);
JavaFileObject jFile = processingEnv.getFiler().createSourceFile(traCIApi.name);
apiMembers.append(String.format("\tprotected %s.%s %s;\n", traCIApi.packageName, traCIApi.name, traCIApi.name.toLowerCase()));
apiInit.append(String.format("\t\t%s = new %s.%s(socket);\n", traCIApi.name.toLowerCase(), traCIApi.packageName, traCIApi.name));
try (PrintWriter writer = new PrintWriter(jFile.openWriter())){
writer.append("package ").append(traCIApi.packageName).append(";").println();
writer.println();
for (String anImport : traCIApi.imports) {
writer.append("import ").append(anImport).append(";").println();
}
writer.append("import ").append(traCIApi.cmdEnum).append(";").println();
writer.append("import ").append(traCIApi.varEnum).append(";").println();
writer.println();
// start API class
writer.append("public class ").append(traCIApi.name).append(" extends ")
.append(traCIApi.extendedClassName).append(" {").println();
// constructor
writer.append("\tpublic ").append(traCIApi.name).append("(TraCISocket socket) {").println();
writer.append("\t\tsuper(socket, \"").append(traCIApi.name).append("\");").println();
writer.append("\t}").println();
writer.println();
for (Element element : apiClass.getEnclosedElements()) {
List<? extends AnnotationMirror> anMirrors = element.getAnnotationMirrors();
if (anMirrors != null){
for (AnnotationMirror anMirror : anMirrors) {
String anName = anMirror.getAnnotationType().asElement().getSimpleName().toString();
String singeAn = traCIApi.singleAnnotation
.substring(traCIApi.singleAnnotation.lastIndexOf(".") + 1).trim();
if (anName.equals(singeAn)){
ApiHandler apiHandler = new ApiHandler(traCIApi, element, anMirror);
apiMapping.append(String.format("\t\tconsoleReader.addCommand(\"%s.%s\", \"\", this::%s_%s);\n", traCIApi.name.toLowerCase(), apiHandler.name, traCIApi.name.toLowerCase(), apiHandler.name));
apiAbstract.append(String.format("\t\tabstract public void %s_%s (String args[]) throws IOException;\n",traCIApi.name.toLowerCase(), apiHandler.name));
switch (apiHandler.apiType){
case "GET":
writeGET(writer, apiHandler);
break;
case "SET":
writeSET(writer, apiHandler);
break;
}
}
}
}
}
writer.append("}").println(); // end API class
}
}
protected void writeGET(PrintWriter writer, ApiHandler apiHandler){
if (apiHandler.ignoreElementId){
writer.append("\tpublic TraCIGetResponse ").append(apiHandler.name).append("() throws IOException {").println();
writer.append("\t\tTraCIPacket p = TraCIGetCommand.build(").append(apiHandler.cmd).append(", ").append(apiHandler.varId).append(", \"-1\");").println();
}
else {
writer.append("\tpublic TraCIGetResponse ").append(apiHandler.name).append("(String elementID) throws IOException {").println();
writer.append("\t\tTraCIPacket p = TraCIGetCommand.build(").append(apiHandler.cmd).append(", ").append(apiHandler.varId).append(", elementID);").println();
}
writer.append("\n\t\tsocket.sendExact(p);\n").println();
writer.append("\t\treturn (TraCIGetResponse) socket.receiveResponse();").println();
writer.append("\t}").println();
writer.println();
}
protected void writeSET(PrintWriter writer, ApiHandler apiHandler){
writer.append("\tpublic TraCIResponse ").append(apiHandler.name).append("(String elementId, ").append(apiHandler.dataTypeStr).append(" data) throws IOException {").println();
writer.append("\t\tTraCIPacket p = TraCISetCommand.build(")
.append(apiHandler.cmd).append(", elementId, ").append(apiHandler.varId).append(", ").append(apiHandler.varType).append(", data);").println();
writer.append("\n\t\tsocket.sendExact(p);\n").println();
writer.append("\t\treturn socket.receiveResponse();").println();
writer.append("\t}").println();
writer.println();
}
class TraCiApiWrapper {
String name;
String singleAnnotation;
String multipleAnnotation;
String cmdEnum;
String varEnum;
String packageName;
String[] imports;
String extendedClassName;
TraCiApiWrapper(Element apiClass){
TraCIApi traCIApi = apiClass.getAnnotation(TraCIApi.class);
name = traCIApi.name();
packageName = traCIApi.packageName();
imports = traCIApi.imports();
extendedClassName = traCIApi.extendedClassName();
try {
singleAnnotation = traCIApi.singleAnnotation().getCanonicalName();
} catch (MirroredTypeException e){
singleAnnotation = e.getTypeMirror().toString();
}
try {
multipleAnnotation = traCIApi.multipleAnnotation().getCanonicalName();
} catch (MirroredTypeException e){
multipleAnnotation = e.getTypeMirror().toString();
}
try {
cmdEnum = traCIApi.cmdEnum().getCanonicalName();
} catch (MirroredTypeException e){
cmdEnum = e.getTypeMirror().toString();
}
try {
varEnum = traCIApi.varEnum().getCanonicalName();
} catch (MirroredTypeException e){
varEnum = e.getTypeMirror().toString();
}
}
}
class ApiHandler {
String cmd;
String varId;
String varType;
String name;
String dataTypeStr;
boolean ignoreElementId;
String apiType; //SET, GET, SUB
public ApiHandler(TraCiApiWrapper traCIApi, Element method, AnnotationMirror annotationMirror){
ignoreElementId = false; //default
dataTypeStr = "";
String cmdPrefix = traCIApi.cmdEnum;
cmdPrefix = cmdPrefix.substring(cmdPrefix.lastIndexOf('.') + 1).trim();
String varPrefix = traCIApi.varEnum;
varPrefix = varPrefix.substring(varPrefix.lastIndexOf('.') + 1).trim();
Map<? extends ExecutableElement, ? extends AnnotationValue> valueMap = annotationMirror.getElementValues();
for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : valueMap.entrySet()) {
String key = entry.getKey().getSimpleName().toString();
Object value = entry.getValue().getValue();
switch (key){
case "cmd":
this.cmd = cmdPrefix+ "." + value.toString();
this.apiType = value.toString().substring(0, 3);
break;
case "var":
this.varId = varPrefix + "." + value.toString() + ".id";
this.varType = varPrefix + "." + value.toString() + ".type";
break;
case "name":
this.name = (String) value;
break;
case "ignoreElementId":
this.ignoreElementId = (boolean) value;
break;
case "dataTypeStr":
this.dataTypeStr = value.toString();
}
}
}
@Override
public String toString() {
return "ApiHandler{" +
"cmd='" + cmd + '\'' +
", varId='" + varId + '\'' +
", varType='" + varType + '\'' +
", name='" + name + '\'' +
", ignoreElementId=" + ignoreElementId +
", apiType='" + apiType + '\'' +
'}';
}
}
}
package org.vadere.annotation.traci.client;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface TraCIApi {
String packageName() default "org.vadere.manager.client.traci";
String[] imports() default {
"org.vadere.manager.client.traci.TraCIClientApi",
"org.vadere.manager.TraCISocket",
"org.vadere.manager.traci.commands.TraCIGetCommand",
"org.vadere.manager.traci.commands.TraCISetCommand",
"org.vadere.manager.traci.respons.TraCIGetResponse",
"org.vadere.manager.traci.writer.TraCIPacket",
"org.vadere.manager.traci.respons.TraCIResponse",
"java.io.IOException",
"java.util.ArrayList"
};
String extendedClassName() default "TraCIClientApi";
String name();
Class singleAnnotation();
Class multipleAnnotation();
Class cmdEnum();
Class varEnum();
}
......@@ -81,7 +81,7 @@ public class ScenarioElementView extends JPanel implements ISelectScenarioElemen
Theme syntaxTheme = Theme.load(in);
syntaxTheme.apply(textAreaLocal);
} catch (IOException e) {
logger.error("could not load theme" + e.getMessage());
logger.error("could not loadFromFilesystem theme" + e.getMessage());
}
txtrTextfiletextarea = textAreaLocal;
......
......@@ -47,7 +47,7 @@ public abstract class ActionAbstractAddScenario extends AbstractAction {
return;
addScenario(vadere);
} catch (IOException e) {
logger.error(String.format("topographyError during output load: '%s'", e.getLocalizedMessage()));
logger.error(String.format("topographyError during output loadFromFilesystem: '%s'", e.getLocalizedMessage()));
}
} else {
IOUtils.errorBox(Messages.getString("renameErrorDialog.text"),
......
......@@ -4,15 +4,19 @@ package org.vadere.gui.projectview.control;
import org.vadere.gui.components.utils.Messages;
import org.vadere.gui.projectview.model.ProjectViewModel;
import org.vadere.gui.projectview.view.ProjectView;
import org.vadere.gui.projectview.view.VDialogManager;
import org.vadere.simulator.projects.VadereProject;
import org.vadere.util.logging.Logger;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import javax.swing.*;
import static org.vadere.gui.projectview.control.ActionAbstractSaveProject.saveProjectUnlessUserCancels;
public class ActionCreateProject extends AbstractAction {
private static final long serialVersionUID = 1L;
......@@ -40,10 +44,16 @@ public class ActionCreateProject extends AbstractAction {
if (newProjectName == null || newProjectName.trim().length() == 0) {
logger.info("invalid project name");
} else {
VadereProject project = new VadereProject(newProjectName, new ArrayList<>());
model.setCurrentProjectPath(null);
final String projectDirectory= VDialogManager.saveProjectDialog();
if(projectDirectory == null)
return; // do not create project without saving it first.
VadereProject project = new VadereProject(newProjectName, new ArrayList<>(), Paths.get(projectDirectory));
model.setProject(project);
model.refreshOutputTable();
saveProjectUnlessUserCancels(model);
ProjectView.getMainWindow().setProjectSpecificActionsEnabled(true);
logger.info("create project: " + newProjectName);
}
......
......@@ -70,17 +70,17 @@ public class ActionLoadProject extends AbstractAction {
else {
migrationOptions = MigrationOptions.reapplyFromVersion((Version)option);
}
// 3. load project
// 3. loadFromFilesystem project
loadProjectByPath(model, projectFilePath, migrationOptions);
} else {
// 3. load project
// 3. loadFromFilesystem project
loadProjectByPath(model, projectFilePath);
}
} else {
logger.info(String.format("user canceled load project."));
logger.info(String.format("user canceled loadFromFilesystem project."));
}
} catch (IOException e1) {
e1.printStackTrace();
......@@ -109,13 +109,12 @@ public class ActionLoadProject extends AbstractAction {
public static void loadProjectByPath(ProjectViewModel projectViewModel, String projectFilePath, MigrationOptions options) {
try {
VadereProject project = IOVadere.readProjectJson(projectFilePath, options);
projectViewModel.setCurrentProjectPath(projectFilePath);
projectViewModel.setProject(project);
projectViewModel.refreshOutputTable();
logger.info("refreshed output table - 2");
// select and load first scenario from list
// select and loadFromFilesystem first scenario from list
projectViewModel.setSelectedRowIndexInScenarioTable(0);
logger.info("selected the first scenario");
......@@ -170,7 +169,7 @@ public class ActionLoadProject extends AbstractAction {
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e.getMessage(), "JoltMigrationAssistant assistant",
JOptionPane.ERROR_MESSAGE);
logger.error("could not load project: " + e.getMessage());
logger.error("could not loadFromFilesystem project: " + e.getMessage());
e.printStackTrace();
}
}
......
package org.vadere.gui.projectview.control;
import javax.swing.*;
import org.vadere.gui.projectview.model.ProjectViewModel;
import org.vadere.gui.projectview.view.VTable;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class ActionRunSelectedScenarios extends AbstractAction {
private final ProjectViewModel model;
......
package org.vadere.gui.projectview.model;
import org.jetbrains.annotations.NotNull;
import org.vadere.gui.components.utils.Messages;
import org.vadere.gui.projectview.control.IOutputFileRefreshListener;
import org.vadere.gui.projectview.control.IProjectChangeListener;
......@@ -16,6 +17,12 @@ import org.vadere.util.logging.Logger;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.*;
import java.util.concurrent.ExecutorService;