blob: 7a1d6b14487e33f1b86eb3e38246213332ede4d6 [file] [log] [blame]
<!DOCTYPE html><html lang="en-us" >
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="generator" content="Source Themes Academic 4.8.0">
<meta name="author" content="Fraunhofer FOKUS">
<meta name="description" content="">
<link rel="alternate" hreflang="en-us" href="https://www.eclipse.org/mosaic/docs/develop_applications/">
<meta name="theme-color" content="#68145C">
<script src="/mosaic/js/mathjax-config.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/academicons/1.8.6/css/academicons.min.css" integrity="sha512-MCWBwPSput2UWNwyznVFLbD2iUc1e5VsdD1zahsWVzkDSUzyHhMZ4kCS3wgYSRm0mU+glwD/Q9lSJrDPwbUL2A==" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.0-1/css/all.min.css" integrity="sha512-ZYg+hQvLlM0W9C3P6vTpes5LmJ66G2EsroxDNzwD6qiulckldb29eD9I672HL2X+LH5nRhY1sQqZLJGB+aUUPg==" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.css" integrity="sha512-H9jrZiiopUdsLpg94A333EfumgUBpO9MdbxStdeITo+KEIMaNfHNvwyjjDJb+ERPaRS6DpyRlKbvPUasNItRyw==" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/styles/atom-one-light.min.css" crossorigin="anonymous" title="hl-light">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/styles/atom-one-light.min.css" crossorigin="anonymous" title="hl-dark" disabled>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.1/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/lazysizes/5.2.2/lazysizes.min.js" integrity="sha512-TmDwFLhg3UA4ZG0Eb4MIyT1O1Mb+Oww5kFG0uHqXsdbyZz9DcvYQhKpGgNkamAI6h2lGGZq2X8ftOJvF/XjTUg==" crossorigin="anonymous" async></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.1.0/es5/tex-chtml.min.js" integrity="sha512-uwL1UtpYdWra2iqJlAW8Ts0s9Os6IxWLDJDF/BnWdhDmT7DEMFba3GPsFwmV3QiTNcUyl2GB5vsgycB/MOvo9g==" crossorigin="anonymous" async></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:400,400i,700,700i%7CRoboto+Mono&display=swap">
<link rel="stylesheet" href="/mosaic/css/academic.css">
<link rel="alternate" href="/mosaic/docs/develop_applications/index.xml" type="application/rss+xml" title="Eclipse MOSAIC – A Multi-Domain and Multi-Scale Simulation Framework for Connected and Automated Mobility">
<link rel="manifest" href="/mosaic/index.webmanifest">
<link rel="icon" type="image/png" href="/mosaic/images/icon_hu6bdfb97c7e23190c70e41ca0e15a9fce_30436_32x32_fill_lanczos_center_2.png">
<link rel="apple-touch-icon" type="image/png" href="/mosaic/images/icon_hu6bdfb97c7e23190c70e41ca0e15a9fce_30436_192x192_fill_lanczos_center_2.png">
<link rel="canonical" href="https://www.eclipse.org/mosaic/docs/develop_applications/">
<meta property="twitter:card" content="summary">
<meta property="og:site_name" content="Eclipse MOSAIC – A Multi-Domain and Multi-Scale Simulation Framework for Connected and Automated Mobility">
<meta property="og:url" content="https://www.eclipse.org/mosaic/docs/develop_applications/">
<meta property="og:title" content="Basics in Application Development | Eclipse MOSAIC – A Multi-Domain and Multi-Scale Simulation Framework for Connected and Automated Mobility">
<meta property="og:description" content=""><meta property="og:image" content="https://www.eclipse.org/mosaic/images/logo.svg">
<meta property="twitter:image" content="https://www.eclipse.org/mosaic/images/logo.svg"><meta property="og:locale" content="en-us">
<meta property="og:updated_time" content="2019-08-06T00:00:00&#43;00:00">
<title>Basics in Application Development | Eclipse MOSAIC – A Multi-Domain and Multi-Scale Simulation Framework for Connected and Automated Mobility</title>
</head>
<body id="top" data-spy="scroll" data-offset="70" data-target="#TableOfContents" class=" page-mosaic page-docs page-develop_applications ">
<aside class="search-results" id="search">
<div class="container">
<section class="search-header">
<div class="row no-gutters justify-content-between mb-3">
<div class="col-10 col-md-3">
<div class="logo" style="background-image: url(/mosaic/img/logos/mosaic/EclipseMOSAIC-Logo-RGB-positiv.svg)"></div>
</div>
<div class="col-2 col-md-4 col-search-close">
<a class="js-search" href="#"><i class="fas fa-times-circle text-muted" aria-hidden="true"></i></a>
</div>
</div>
<div id="search-box">
<input name="q" id="search-query" placeholder="Search..." autocapitalize="off"
autocomplete="off" autocorrect="off" spellcheck="false" type="search">
</div>
</section>
<section class="section-search-results">
<div id="search-hits">
</div>
</section>
</div>
</aside>
<nav class="navbar navbar-expand-lg navbar-light compensate-for-scrollbar" id="navbar-main">
<div class="container">
<div class="d-none d-lg-inline-flex">
<a style="visibility:visible;" class="navbar-brand" href="/mosaic/"><img src="/mosaic/images/logo.svg" alt="Eclipse MOSAIC – A Multi-Domain and Multi-Scale Simulation Framework for Connected and Automated Mobility"></a>
</div>
<button type="button" class="navbar-toggler" data-toggle="collapse"
data-target="#navbar-content" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
<span><i class="fas fa-bars"></i></span>
</button>
<div class="navbar-brand-mobile-wrapper d-inline-flex d-lg-none">
<a class="navbar-brand" href="/mosaic/"><img src="/mosaic/images/logo.svg" alt="Eclipse MOSAIC – A Multi-Domain and Multi-Scale Simulation Framework for Connected and Automated Mobility"></a>
</div>
<div class="navbar-collapse main-menu-item collapse justify-content-start" id="navbar-content">
<ul class="navbar-nav d-md-inline-flex">
<li class="nav-item">
<a class="nav-link " href="/mosaic/about"><span>About</span></a>
</li>
<li class="nav-item">
<a class="nav-link " href="/mosaic/news"><span>News</span></a>
</li>
<li class="nav-item">
<a class="nav-link active" href="/mosaic/docs"><span>Documentation</span></a>
</li>
<li class="nav-item">
<a class="nav-link " href="/mosaic/tutorials"><span>Tutorials</span></a>
</li>
<li class="nav-item">
<a class="nav-link " href="/mosaic/download"><span>Download</span></a>
</li>
<li class="nav-item">
<a class="nav-link " href="/mosaic/community"><span>Community</span></a>
</li>
</ul>
</div>
<ul class="nav-icons navbar-nav flex-row ml-auto d-flex pl-md-2">
<li class="nav-item">
<a class="nav-link js-search" href="#" aria-label="Search"><i class="fas fa-search" aria-hidden="true"></i></a>
</li>
<li class="nav-item ">
<a href="https://github.com/eclipse/mosaic" target="blank">
<i class="fab fa-github" aria-hidden="true"></i>
</a>
</li>
</ul>
</div>
</nav>
<div class="docs container">
<div class="row flex-xl-nowrap">
<div class="docs-sidebar col-12 col-md-3 col-xl-3">
<form class="docs-search d-flex align-items-center">
<button class="btn docs-toggle d-md-none p-0 mr-3" type="button" data-toggle="collapse" data-target="#docs-nav" aria-controls="docs-nav" aria-expanded="false" aria-label="Toggle section navigation">
<span><i class="fas fa-bars"></i></span>
</button>
<input name="q" type="search" class="form-control" placeholder="Search..." autocomplete="off">
</form>
<nav class="collapse docs-links" id="docs-nav">
<div class="docs-toc-item">
<a class="docs-toc-link" href="/mosaic/docs/getting_started">Getting Started</a>
<ul class="nav docs-sidenav">
<li >
<a href="/mosaic/docs/getting_started/">Download</a>
</li>
<li >
<a href="/mosaic/docs/getting_started/run_mosaic/">Run Eclipse MOSAIC</a>
</li>
<li >
<a href="/mosaic/docs/getting_started/results/">Simulation Results</a>
</li>
</ul>
</div>
<div class="docs-toc-item">
<a class="docs-toc-link" href="/mosaic/docs/visualization">Visualization</a>
<ul class="nav docs-sidenav">
<li >
<a href="/mosaic/docs/visualization/">WebSocket Visualizer</a>
</li>
<li >
<a href="/mosaic/docs/visualization/filevis/">File Output</a>
</li>
<li >
<a href="/mosaic/docs/visualization/statistics/">Statistics Output</a>
</li>
<li >
<a href="/mosaic/docs/visualization/itef/">ITEF</a>
</li>
<li >
<a href="/mosaic/docs/visualization/phabmap/">PHABMap</a>
</li>
</ul>
</div>
<div class="docs-toc-item">
<a class="docs-toc-link" href="/mosaic/docs/simulators">Simulators</a>
<ul class="nav docs-sidenav">
<li >
<a href="/mosaic/docs/simulators/">Overview</a>
</li>
<li >
<a href="/mosaic/docs/simulators/application_simulator/">Application Simulator</a>
</li>
<li >
<a href="/mosaic/docs/simulators/traffic_simulator_sumo/">Traffic - Eclipse SUMO</a>
</li>
<li >
<a href="/mosaic/docs/simulators/network_simulator_omnetpp/">Network - OMNeT&#43;&#43;</a>
</li>
<li >
<a href="/mosaic/docs/simulators/network_simulator_ns3/">Network - ns-3</a>
</li>
<li >
<a href="/mosaic/docs/simulators/network_simulator_sns/">Network - SNS</a>
</li>
<li >
<a href="/mosaic/docs/simulators/network_simulator_cell/">Network - Cell</a>
</li>
<li >
<a href="/mosaic/docs/simulators/environment_simulator/">Environment Simulator</a>
</li>
<li >
<a href="/mosaic/docs/simulators/battery_simulator/">Battery Simulator</a>
</li>
</ul>
</div>
<div class="docs-toc-item">
<a class="docs-toc-link" href="/mosaic/docs/building_scenarios">Building Scenarios</a>
<ul class="nav docs-sidenav">
<li >
<a href="/mosaic/docs/building_scenarios/">Simulation Scenarios</a>
</li>
<li >
<a href="/mosaic/docs/building_scenarios/scenario_convert/">Scenario Convert</a>
</li>
<li >
<a href="/mosaic/docs/building_scenarios/scenario_configuration/">Additional Scenario Configuration</a>
</li>
</ul>
</div>
<div class="docs-toc-item">
<a class="docs-toc-link" href="/mosaic/docs/develop_applications">Create Applications</a>
<ul class="nav docs-sidenav">
<li class="active">
<a href="/mosaic/docs/develop_applications/">Basics</a>
</li>
<li >
<a href="/mosaic/docs/develop_applications/communication/">V2X Communication</a>
</li>
<li >
<a href="/mosaic/docs/develop_applications/event_scheduler/">Event Scheduling</a>
</li>
<li >
<a href="/mosaic/docs/develop_applications/road_traffic/">Scenario Database</a>
</li>
</ul>
</div>
<div class="docs-toc-item">
<a class="docs-toc-link" href="/mosaic/docs/extending_mosaic">Extending Eclipse MOSAIC</a>
<ul class="nav docs-sidenav">
<li >
<a href="/mosaic/docs/extending_mosaic/">Core Concepts</a>
</li>
<li >
<a href="/mosaic/docs/extending_mosaic/simulator_coupling/">Simulator Coupling</a>
</li>
<li >
<a href="/mosaic/docs/extending_mosaic/interactions/">Interactions</a>
</li>
<li >
<a href="/mosaic/docs/extending_mosaic/application_ambassador_details/">Application Ambassador</a>
</li>
<li >
<a href="/mosaic/docs/extending_mosaic/sumo_ambassador_details/">Sumo Ambassador</a>
</li>
<li >
<a href="/mosaic/docs/extending_mosaic/omnetpp_details/">OMNeT&#43;&#43; Federate</a>
</li>
<li >
<a href="/mosaic/docs/extending_mosaic/delay_models/">Delay Models</a>
</li>
</ul>
</div>
<div class="docs-toc-item">
<a class="docs-toc-link" href="/mosaic/docs/api_docs/">API Documentation</a>
<ul class="nav docs-sidenav">
<li >
<a href="/mosaic/docs/api_docs/">Javadoc</a>
</li>
</ul>
</div>
</nav>
</div>
<div class="docs-toc d-none d-xl-block col-xl-2">
<ul class="nav toc-top">
<li><a href="#" id="back_to_top" class="docs-toc-title">Contents</a></li>
</ul>
<nav id="TableOfContents">
<ul>
<li><a href="#developing-applications">Developing Applications</a></li>
<li><a href="#create-a-hello-world-application-based-on-maven">Create a ’Hello world’ application based on Maven</a></li>
<li><a href="#application-interfaces">Application Interfaces</a></li>
<li><a href="#basic-functions-and-concepts-for-applications">Basic Functions and Concepts for Applications</a>
<ul>
<li><a href="#event-hooks">Event hooks</a></li>
<li><a href="#trigger-own-events">Trigger own Events</a></li>
<li><a href="#using-the-operating-system">Using the Operating System</a></li>
<li><a href="#navigation">Navigation</a></li>
<li><a href="#access-sumo-traci-from-applications">Access SUMO TraCI from applications</a></li>
</ul>
</li>
<li><a href="#debugging-of-applications">Debugging of applications</a></li>
</ul>
</nav>
</div>
<style>
@media (min-width:1140px) {
.docs-sidebar {
flex: 0 1 320px;
}
.docs-toc {
flex: 0 1 280px;
}
main.docs-content.no-docs-toc {
padding-bottom: 0 !important;
max-width: calc(100% - 320px) !important;
flex: 0 1 calc(100% - 320px);
width: 100%;
}
main.docs-content {
padding-bottom: 0 !important;
max-width: calc(100% - 600px) !important;
flex: 0 1 calc(100% - 600px);
width: 100%;
}
}
@media (max-width: 770px) {
main.docs-content {
max-width: 100% !important;
width: 100%;
}
}
@media (min-width: 771px) and(max-width: 1139px) {
main.docs-content.no-docs-toc {
padding-bottom: 0 !important;
max-width: calc(100% - 320px) !important;
width: 100%;
}
}
</style>
<main class="docs-content col-12 col-md-9 col-xl-auto py-md-3 pl-md-4" role="main">
<article class="article">
<div class="docs-article-container">
<h1>Basics in Application Development</h1>
<div class="article-style">
<p>Applications in Eclipse MOSAIC are simulated by the
<a href="https://www.eclipse.org/mosaic/docs/simulators/application_simulator/">Application Simulator</a>. Such
an application is programmed in Java and follows an event-based execution flow. Thereby, certain methods of the application are called by
the Application Simulator upon corresponding events (the application &ldquo;reacts&rdquo;). To actively gain execution at some later point in time, an
application can also schedule a generic event itself. When the application is executing, it has access to a set of methods, allowing to
trigger actions like sensing messages or controlling the vehicle, influencing the current simulation (the application &ldquo;acts&rdquo;).</p>
<h2 id="developing-applications">Developing Applications</h2>
<p>Developing custom applications in Eclipse MOSAIC is rather easy. The best way to learn it is by looking at the
source code of actual applications. For this purpose, we provide the source code of all tutorial applications
and further examples.</p>
<p>For an easy understanding of the application API, the following questions and their answers should
help:</p>
<ul>
<li>
<p>What is required to get my own application to run in Eclipse MOSAIC?
In Eclipse MOSAIC it is very easy to build your own application. First, it needs to inherit from the <code>AbstractApplication</code>
class (see following section). Secondly, the application must be mapped to
a vehicle (or RSU, or traffic light, &hellip;) via the mapping configuration (see section
<a href="https://www.eclipse.org/mosaic/docs/building_scenarios/#applications-and-mapping">mapping</a>). Finally,
the application must be compiled as a Jar-File and placed into the application directory of your
scenario.</p>
</li>
<li>
<p>How can I access vehicle functions from within the application, such as sending V2X messages?
Every applications has access to the <code>OperatingSystem</code> of the underlying unit which allows to
change its state or to initiate actions, such as sending messages to other vehicles.</p>
</li>
<li>
<p>How can I react to events during the simulation, such as receiving V2X messages?
For each application you decide, which events the application should listen to. For example,
if your application needs to react upon incoming V2X messages, it simply implements the <code>CommunicationApplication</code>
interface. In the following section you can find all available interfaces
applications can implement.</p>
</li>
</ul>
<h2 id="create-a-hello-world-application-based-on-maven">Create a ’Hello world’ application based on Maven</h2>
<p>For this example you need to install
<a href="https://maven.apache.org/download.cgi" target="_blank" rel="noopener">Maven</a> which is used
to resolve required MOSAIC dependencies and to compile your application Java code into a Jar file.
Follow the steps to build an example application:</p>
<ol>
<li>Create a new folder <code>HelloWorldApp</code>:
<pre><code class="language-FOLDER">└─ HelloWorldApp
├─ src
| └─ main
| └─ java
| └─ HelloWorldApp.java
└─ pom.xml
</code></pre>
</li>
<li>Place a <code>pom.xml</code> with the following content:
<pre><code class="language-xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&quot;&gt;
&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
&lt;groupId&gt;org.eclipse.mosaic.app&lt;/groupId&gt;
&lt;artifactId&gt;HelloWorldApp&lt;/artifactId&gt;
&lt;version&gt;0.0.1&lt;/version&gt;
&lt;packaging&gt;jar&lt;/packaging&gt;
&lt;dependencies&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.eclipse.mosaic&lt;/groupId&gt;
&lt;artifactId&gt;mosaic-application&lt;/artifactId&gt;
&lt;version&gt;20.0&lt;/version&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;/project&gt;
</code></pre>
</li>
<li>Create a new application in <code>src/main/java/HelloWorldApp.java</code>:
<pre><code class="language-java">import org.eclipse.mosaic.fed.application.app.AbstractApplication;
import org.eclipse.mosaic.fed.application.app.api.VehicleApplication;
import org.eclipse.mosaic.fed.application.app.api.os.VehicleOperatingSystem;
import org.eclipse.mosaic.lib.objects.vehicle.VehicleData;
import org.eclipse.mosaic.lib.util.scheduling.Event;
public class HelloWorldApp extends AbstractApplication&lt;VehicleOperatingSystem&gt; implements VehicleApplication {
@Override
public void onStartup() {
getLog().info(&quot;Hello World!&quot;);
}
@Override
public void onVehicleUpdated(VehicleData previousVehicleData, VehicleData updatedVehicleData) {
getLog().info(&quot;Driving {} m/s.&quot;, updatedVehicleData.getSpeed());
}
@Override
public void onShutdown() {
getLog().info(&quot;Good bye!&quot;);
}
@Override
public void processEvent(Event event) {
// ...
}
}
</code></pre>
</li>
<li>Build the application using maven:
<pre><code class="language-shell">mvn clean install
</code></pre>
</li>
<li>Copy the JAR file from <code>target/HelloWorldApp-0.0.1.jar</code> to the <code>application</code> directory of your simulation scenario.</li>
<li>Use the fully qualified name <code>HelloWorldApp</code> in the <code>mapping_config.json</code> to load the application onto vehicles.</li>
</ol>
<h2 id="application-interfaces">Application Interfaces</h2>
<p>You may have noticed that the <code>HellowWorldApp</code> extends from the class <code>[...].AbstractApplication&lt;OS&gt;</code>.
In order to define the type of unit your application can run on, you need to speficy the operating system by choosing one of the following:</p>
<ul>
<li><code>VehicleOperatingSystem</code> - for applications mapped to normal vehicles.</li>
<li><code>ElectricVehicleOperatingSystem</code> - for applications for vehicles with electro mobility features.</li>
<li><code>RoadSideUnitOperatingSystem</code> - for applications mapped to RSUs.</li>
<li><code>TrafficLightOperatingSystem</code> - for applications mapped to traffic lights.</li>
<li><code>TrafficManagementCenterOperatingSystem</code> - for applications mapped to TMCs.</li>
<li><code>ChargingStationOperatingSystem</code> - for applications mapped to charging stations.</li>
</ul>
<p><em>See package:</em> <code>org.eclipse.mosaic.fed.application.app.api.os.*</code></p>
<p>Furthermore, your application can implement the following 7 interfaces in order to get informed on specific events:</p>
<ul>
<li><code>VehicleApplication</code> - get informed when information about the vehicles state is updated.</li>
<li><code>ElectricVehicleApplication</code> - get informed on electric vehicle specific events.</li>
<li><code>CommunicationApplication</code> - react on incoming V2X messages.</li>
<li><code>MosaicApplication</code> - get informed on Eclipse MOSAIC internal events.</li>
<li><code>TrafficLightApplication</code> - get noticed when the traffic light program is changed.</li>
<li><code>ChargingStationApplication</code> - react on state changes of the charging station.</li>
<li><code>TrafficManagementCenterApplicatio</code>n - get informed on state changes of road infrastructure.</li>
</ul>
<p><em>See package:</em> <code>org.eclipse.mosaic.fed.application.app.api.*</code></p>
<hr>
<h2 id="basic-functions-and-concepts-for-applications">Basic Functions and Concepts for Applications</h2>
<p>The following section describes how applications are implemented.</p>
<h3 id="event-hooks">Event hooks</h3>
<p>Applications are implemented by reacting to specific events. Those events are, amongst others:</p>
<ul>
<li>The simulation has started: All static units (e.g. road side units) are set up (<code>onStartup()</code> is called)</li>
<li>Once a vehicle has been added to the simulation, all its configured applications are initialized (<code>onStartup()</code> is called)</li>
<li>The data of the vehicle has changed, e.g. after the traffic simulator has finished one simulationstep (<code>onVehicleUpdated()</code> is called).</li>
<li>A unit has received a V2X message from another entity (<code>onMessageReceived</code> is called).</li>
<li>A unit which has send a V2X message via a ITS-G5 topocast receives an acknowledgement (<code>onAcknowledgementReceived()</code> is called).</li>
</ul>
<p>Another example:</p>
<div class="svg-wrap mt-1 mb-4">
<div class="inner">
<svg id="mermaid-1603209753374" width="100%" xmlns="http://www.w3.org/2000/svg" height="929" style="max-width: 923px;" viewBox="-50 -10 923 929"><style>#mermaid-1603209753374{font-family:"trebuchet ms",verdana,arial;font-size:16px;fill:#333;}#mermaid-1603209753374 .error-icon{fill:#552222;}#mermaid-1603209753374 .error-text{fill:#552222;stroke:#552222;}#mermaid-1603209753374 .edge-thickness-normal{stroke-width:2px;}#mermaid-1603209753374 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-1603209753374 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-1603209753374 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-1603209753374 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-1603209753374 .marker{fill:#333333;}#mermaid-1603209753374 .marker.cross{stroke:#333333;}#mermaid-1603209753374 svg{font-family:"trebuchet ms",verdana,arial;font-size:16px;}#mermaid-1603209753374 .actor{stroke:hsl(259.6261682243,59.7765363128%,87.9019607843%);fill:#ECECFF;}#mermaid-1603209753374 text.actor &gt; tspan{fill:black;stroke:none;}#mermaid-1603209753374 .actor-line{stroke:grey;}#mermaid-1603209753374 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-1603209753374 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-1603209753374 #arrowhead path{fill:#333;stroke:#333;}#mermaid-1603209753374 .sequenceNumber{fill:white;}#mermaid-1603209753374 #sequencenumber{fill:#333;}#mermaid-1603209753374 #crosshead path{fill:#333;stroke:#333;}#mermaid-1603209753374 .messageText{fill:#333;stroke:#333;}#mermaid-1603209753374 .labelBox{stroke:hsl(259.6261682243,59.7765363128%,87.9019607843%);fill:#ECECFF;}#mermaid-1603209753374 .labelText,#mermaid-1603209753374 .labelText &gt; tspan{fill:black;stroke:none;}#mermaid-1603209753374 .loopText,#mermaid-1603209753374 .loopText &gt; tspan{fill:black;stroke:none;}#mermaid-1603209753374 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243,59.7765363128%,87.9019607843%);fill:hsl(259.6261682243,59.7765363128%,87.9019607843%);}#mermaid-1603209753374 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-1603209753374 .noteText,#mermaid-1603209753374 .noteText &gt; tspan{fill:black;stroke:none;}#mermaid-1603209753374 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-1603209753374 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-1603209753374 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-1603209753374:root{--mermaid-font-family:"trebuchet ms",verdana,arial;}#mermaid-1603209753374 sequence{fill:apa;}</style><g></g><g><line id="actor0" x1="75" y1="5" x2="75" y2="918" class="actor-line" stroke-width="0.5px" stroke="#999"></line><rect x="0" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" rx="3" ry="3" class="actor"></rect><text x="75" y="32.5" dominant-baseline="central" alignment-baseline="central" class="actor" style="text-anchor: middle; font-size: 14px; font-weight: 400; font-family: Open-Sans, sans-serif;"><tspan x="75" dy="0">RTI</tspan></text></g><g><line id="actor1" x1="326" y1="5" x2="326" y2="918" class="actor-line" stroke-width="0.5px" stroke="#999"></line><rect x="251" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" rx="3" ry="3" class="actor"></rect><text x="326" y="32.5" dominant-baseline="central" alignment-baseline="central" class="actor" style="text-anchor: middle; font-size: 14px; font-weight: 400; font-family: Open-Sans, sans-serif;"><tspan x="326" dy="0">ApplicationSimulator</tspan></text></g><g><line id="actor2" x1="548" y1="5" x2="548" y2="918" class="actor-line" stroke-width="0.5px" stroke="#999"></line><rect x="473" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" rx="3" ry="3" class="actor"></rect><text x="548" y="32.5" dominant-baseline="central" alignment-baseline="central" class="actor" style="text-anchor: middle; font-size: 14px; font-weight: 400; font-family: Open-Sans, sans-serif;"><tspan x="548" dy="0">Application1</tspan></text></g><g><line id="actor3" x1="748" y1="5" x2="748" y2="918" class="actor-line" stroke-width="0.5px" stroke="#999"></line><rect x="673" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" rx="3" ry="3" class="actor"></rect><text x="748" y="32.5" dominant-baseline="central" alignment-baseline="central" class="actor" style="text-anchor: middle; font-size: 14px; font-weight: 400; font-family: Open-Sans, sans-serif;"><tspan x="748" dy="0">Application2</tspan></text></g><defs><marker id="arrowhead" refX="5" refY="2" markerWidth="6" markerHeight="4" orient="auto"><path d="M 0,0 V 4 L6,2 Z"></path></marker></defs><defs><marker id="crosshead" markerWidth="15" markerHeight="8" orient="auto" refX="16" refY="4"><path fill="black" stroke="#000000" stroke-width="1px" d="M 9,2 V 6 L16,4 Z" style="stroke-dasharray: 0, 0;"></path><path fill="none" stroke="#000000" stroke-width="1px" d="M 0,1 L 6,7 M 6,1 L 0,7" style="stroke-dasharray: 0, 0;"></path></marker></defs><defs><marker id="sequencenumber" refX="15" refY="15" markerWidth="60" markerHeight="40" orient="auto"><circle cx="15" cy="15" r="6"></circle></marker></defs><g></g><g></g><text x="201" y="80" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-family: &quot;trebuchet ms&quot;, verdana, arial; font-size: 16px; font-weight: 400;">VehicleRegistration</text><line x1="80" y1="113" x2="321" y2="113" class="messageLine0" stroke-width="2" stroke="none" marker-end="url(#arrowhead)" style="fill: none;"></line><text x="440" y="128" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-family: &quot;trebuchet ms&quot;, verdana, arial; font-size: 16px; font-weight: 400;">onStartup()</text><line x1="331" y1="161" x2="548" y2="161" class="messageLine0" stroke-width="2" stroke="none" marker-end="url(#arrowhead)" style="fill: none;"></line><g><rect x="543" y="163" fill="#EDF2AE" stroke="#666" width="10" height="622" rx="0" ry="0" class="activation0"></rect></g><text x="540" y="176" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-family: &quot;trebuchet ms&quot;, verdana, arial; font-size: 16px; font-weight: 400;">onStartup()</text><line x1="331" y1="209" x2="748" y2="209" class="messageLine0" stroke-width="2" stroke="none" marker-end="url(#arrowhead)" style="fill: none;"></line><g><rect x="743" y="211" fill="#EDF2AE" stroke="#666" width="10" height="622" rx="0" ry="0" class="activation0"></rect></g><text x="201" y="224" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-family: &quot;trebuchet ms&quot;, verdana, arial; font-size: 16px; font-weight: 400;">VehicleUpdates</text><line x1="80" y1="257" x2="321" y2="257" class="messageLine0" stroke-width="2" stroke="none" marker-end="url(#arrowhead)" style="fill: none;"></line><text x="437" y="272" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-family: &quot;trebuchet ms&quot;, verdana, arial; font-size: 16px; font-weight: 400;">onVehicleUpdated()</text><line x1="331" y1="305" x2="543" y2="305" class="messageLine0" stroke-width="2" stroke="none" marker-end="url(#arrowhead)" style="fill: none;"></line><text x="537" y="320" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-family: &quot;trebuchet ms&quot;, verdana, arial; font-size: 16px; font-weight: 400;">onVehicleUpdated()</text><line x1="331" y1="353" x2="743" y2="353" class="messageLine0" stroke-width="2" stroke="none" marker-end="url(#arrowhead)" style="fill: none;"></line><text x="201" y="368" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-family: &quot;trebuchet ms&quot;, verdana, arial; font-size: 16px; font-weight: 400;">VehicleUpdates</text><line x1="80" y1="401" x2="321" y2="401" class="messageLine0" stroke-width="2" stroke="none" marker-end="url(#arrowhead)" style="fill: none;"></line><text x="437" y="416" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-family: &quot;trebuchet ms&quot;, verdana, arial; font-size: 16px; font-weight: 400;">onVehicleUpdated()</text><line x1="331" y1="449" x2="543" y2="449" class="messageLine0" stroke-width="2" stroke="none" marker-end="url(#arrowhead)" style="fill: none;"></line><text x="537" y="464" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-family: &quot;trebuchet ms&quot;, verdana, arial; font-size: 16px; font-weight: 400;">onVehicleUpdated()</text><line x1="331" y1="497" x2="743" y2="497" class="messageLine0" stroke-width="2" stroke="none" marker-end="url(#arrowhead)" style="fill: none;"></line><text x="537" y="512" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-family: &quot;trebuchet ms&quot;, verdana, arial; font-size: 16px; font-weight: 400;">sendV2xMessage()</text><line x1="743" y1="545" x2="331" y2="545" class="messageLine0" stroke-width="2" stroke="none" marker-end="url(#arrowhead)" style="fill: none;"></line><text x="201" y="560" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-family: &quot;trebuchet ms&quot;, verdana, arial; font-size: 16px; font-weight: 400;">V2xMessageTransmission</text><line x1="321" y1="593" x2="80" y2="593" class="messageLine0" stroke-width="2" stroke="none" marker-end="url(#arrowhead)" style="fill: none;"></line><text x="201" y="608" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-family: &quot;trebuchet ms&quot;, verdana, arial; font-size: 16px; font-weight: 400;">V2xMessageReceiption</text><line x1="80" y1="641" x2="321" y2="641" class="messageLine0" stroke-width="2" stroke="none" marker-end="url(#arrowhead)" style="fill: none;"></line><text x="437" y="656" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-family: &quot;trebuchet ms&quot;, verdana, arial; font-size: 16px; font-weight: 400;">onMessageReceived()</text><line x1="331" y1="689" x2="543" y2="689" class="messageLine0" stroke-width="2" stroke="none" marker-end="url(#arrowhead)" style="fill: none;"></line><text x="201" y="704" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-family: &quot;trebuchet ms&quot;, verdana, arial; font-size: 16px; font-weight: 400;">VehicleUpdates (remove)</text><line x1="80" y1="737" x2="321" y2="737" class="messageLine0" stroke-width="2" stroke="none" marker-end="url(#arrowhead)" style="fill: none;"></line><text x="437" y="752" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-family: &quot;trebuchet ms&quot;, verdana, arial; font-size: 16px; font-weight: 400;">onShutdown()</text><line x1="331" y1="785" x2="543" y2="785" class="messageLine0" stroke-width="2" stroke="none" marker-end="url(#arrowhead)" style="fill: none;"></line><text x="537" y="800" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-family: &quot;trebuchet ms&quot;, verdana, arial; font-size: 16px; font-weight: 400;">onShutdown()</text><line x1="331" y1="833" x2="743" y2="833" class="messageLine0" stroke-width="2" stroke="none" marker-end="url(#arrowhead)" style="fill: none;"></line><g><rect x="0" y="853" fill="#eaeaea" stroke="#666" width="150" height="65" rx="3" ry="3" class="actor"></rect><text x="75" y="885.5" dominant-baseline="central" alignment-baseline="central" class="actor" style="text-anchor: middle; font-size: 14px; font-weight: 400; font-family: Open-Sans, sans-serif;"><tspan x="75" dy="0">RTI</tspan></text></g><g><rect x="251" y="853" fill="#eaeaea" stroke="#666" width="150" height="65" rx="3" ry="3" class="actor"></rect><text x="326" y="885.5" dominant-baseline="central" alignment-baseline="central" class="actor" style="text-anchor: middle; font-size: 14px; font-weight: 400; font-family: Open-Sans, sans-serif;"><tspan x="326" dy="0">ApplicationSimulator</tspan></text></g><g><rect x="473" y="853" fill="#eaeaea" stroke="#666" width="150" height="65" rx="3" ry="3" class="actor"></rect><text x="548" y="885.5" dominant-baseline="central" alignment-baseline="central" class="actor" style="text-anchor: middle; font-size: 14px; font-weight: 400; font-family: Open-Sans, sans-serif;"><tspan x="548" dy="0">Application1</tspan></text></g><g><rect x="673" y="853" fill="#eaeaea" stroke="#666" width="150" height="65" rx="3" ry="3" class="actor"></rect><text x="748" y="885.5" dominant-baseline="central" alignment-baseline="central" class="actor" style="text-anchor: middle; font-size: 14px; font-weight: 400; font-family: Open-Sans, sans-serif;"><tspan x="748" dy="0">Application2</tspan></text></g></svg>
</div>
</div>
<p><em>Example sequence of onStartup, onUpdate, onMessageReceived and onShutdown of two applications.</em></p>
<p>A <code>onStartup()</code> method, which enables the ITS-G5 communication module of the unit, could be implemented the following:</p>
<pre><code class="language-java">@Override
public void onStartup() {
getOs().getAdHocModule().enable(new AdHocModuleConfiguration()
.addRadio().channel(AdHocChannel.CCH).power(50).create()
);
}
</code></pre>
<p>A <code>onMessageReceived()</code> method, which reacts upon a <strong>DENM</strong> message, could be implemented as:</p>
<pre><code class="language-java">@Override
public void onMessageReceived(ReceivedV2xMessage receivedV2xMessage) {
final V2xMessage msg = receivedV2xMessage.getMessage();
if (msg instanceof Denm) {
Denm denm = (Denm)msg;
GeoPoint eventLocation = denm.getEventLocation();
//TODO you can add further implementation here
}
}
</code></pre>
<h3 id="trigger-own-events">Trigger own Events</h3>
<p>It is possible to trigger own events at specific times within the application. For this purpose, the application has access to an own event manager. Each event requires a
simulation timestamp when it should be called, and an event processor.</p>
<p>The following code triggers an event in 10 seconds after the application has been initialied:</p>
<pre><code class="language-java">@Override
public void onStartup() {
Event event = new Event(getOs().getSimulationTime() + 10 * TIME.SECOND, this);
getOs().getEventManager().addEvent(event);
}
@Override
public void processEvent(Event event) {
getLog().info(&quot;Event has been triggered&quot;);
// TODO
}
</code></pre>
<p>To address a specific method to process the event, Java lambda expressions could be used:</p>
<pre><code class="language-java">@Override
public void onStartup() {
Event event = new Event(getOs().getSimulationTime() + 10 * TIME.SECOND, this::mySpecificMethod);
getOs().getEventManager().addEvent(event);
}
public void mySpecificMethod(Event event) {
getLog().info(&quot;Event has been triggered&quot;);
// TODO
}
</code></pre>
<h3 id="using-the-operating-system">Using the Operating System</h3>
<p>Each application has access to the operating system of its unit. Depending on the type of unit, the operating system provides different methods. For example,
an application which is mapped on vehicles, has access to the <code>VehicleOperatingSystem</code> by calling <code>this.getOperatingSystem()</code> (or <code>this.getOs()</code> to keep it short). The following examples show a bit
of the capabilities the <code>VehicleOperatingSystem</code> provides:</p>
<p>Get the current simulation time (in nanoseconds):</p>
<pre><code class="language-java">long time = this.getOs().getSimulationTime();
</code></pre>
<p>Return the name of the unit (e.g. &ldquo;veh_0&rdquo;):</p>
<pre><code class="language-java">String nameOfUnit = this.getOs().getId();
</code></pre>
<p>Get access to vehicle data, such as speed, position, heading, and the like:</p>
<pre><code class="language-java">double speed = this.getOs().getVehicleData().getSpeed();
GeoPoint position = this.getOs().getVehicleData().getPosition();
</code></pre>
<p>Change parameters of the vehicle during the simulation, such as its maximum speed:</p>
<pre><code class="language-java">this.getOs().requestVehicleParametersUpdate()
.changeMaxSpeed(10) // m/s
.changeMaxAcceleration(2.4)
.apply();
</code></pre>
<p>Get the current lane index of the vehicle and change lane to left (within 5000 ms):</p>
<pre><code class="language-java">int laneIndex = this.getOs().getRoadPosition().getLaneIndex();
int newLaneIndex = Math.max(0, laneIndex - 1);
this.getOs().changeLane(newLaneIndex, 5000);
</code></pre>
<p>Sending a V2X message via ITS-G5 singlehop broadcast:</p>
<pre><code class="language-java">MessageRouting routing = this.getOs().getAdHocModule().createMessageRouting().topoBroadCast();
V2xMessage message = new MyV2xMessage(routing);
this.getOs().getAdHocModule().sendV2xMessage(message);
</code></pre>
<p>Park the vehicle in 200 meters at the right side of the road for 3 minutes:</p>
<pre><code class="language-java">double distance = 200;
double duration = 3 * 60 * 1000;
IRoadPosition stopPosition = RoadPositionFactory.createAlongRoute(
getOs().getNavigationModule().getRoadPosition(),
getOs().getNavigationModule().getCurrentRoute(),
0,
distance
);
this.getOs().stop(distance, duration, Stop.StopMode.PARK);
</code></pre>
<h3 id="navigation">Navigation</h3>
<p>The navigation of vehicles (i.e. calculation of routes) is handled completely by the
<a href="https://www.eclipse.org/mosaic/docs/simulators/application_simulator/#eclipse-mosaic-application-simulator">Application Simulator</a>. Each vehicle is equipped
with a navigation system which provides all required information and functions for navigational purposes:</p>
<ul>
<li>Retrieve the current position and heading of the vehicle.</li>
<li>Get the target of the vehicle.</li>
<li>Calculate various routes from the current position to an arbitrary target.</li>
<li>Choose a suitable route out of existing ones from the current position to an arbitrary target.</li>
<li>Switch onto a specific route.</li>
</ul>
<p>In order to provide routing functionality, a map model based on Open Street Map data is used, which
needs to be transformed before the simulation using scenario-convert. The map data including initial
routes for vehicles is provided with the database file which needs to be located in
<code>mosaic/scenarios/&lt;scenario_name&gt;/application/&lt;scenario_name&gt;.db</code></p>
<h4 id="configuration">Configuration</h4>
<p>If the database needs to be located somewhere else, the path can be specified in
<code>mosaic/scenarios/&lt;scenario_name&gt;/application/application_config.json</code>:</p>
<pre><code class="language-json">{
...
&quot;navigationConfiguration&quot;: {
&quot;databaseFile&quot;: &quot;path/to/scenario.db&quot;
}
}
</code></pre>
<p>The following snippet show, how the navigation system can be used within an application:</p>
<pre><code class="language-java">//get navigation module
INavigationModule navigationModule = getOs().getNavigationModule();
//choose current target as target position
RoutingPosition targetPosition = new RoutingPosition(navigationModule.getTargetPosition());
//set routing parameters to fastest route search
RoutingParameters params = new RoutingParameters().costFunction(IRoutingCostFunction.Fastest);
//calculate routes
RoutingResponse response = navigationModule.calculateRoutes(targetPosition, params);
//switch to best route
if (response.getBestRoute() != null) {
boolean routeSwitched = navigationModule.switchRoute(response.getBestRoute());
...
}
</code></pre>
<h3 id="access-sumo-traci-from-applications">Access SUMO TraCI from applications</h3>
<p>If SUMO is used as a traffic simulator and a special functionality is required, the <code>sendSumoTraciRequest</code>
function in the <code>OperatingSystem</code> can be used.</p>
<p>The function expects a string (a unique identifier which will be assigned to the response) and a byte array
(representing the complete Traffic Control Interface (TraCI) request including the header). The message
identifier can be an empty string.</p>
<p>In all cases the command will trigger a response. The application can receive the response from the
method <code>onSumoTraciResult</code>. This method will receive a <code>SumoTraciResult</code>
object. This response contains the specified identifier. The application must handle the
identification process of the response itself.</p>
<div class="alert alert-note">
<div>
<p>Be careful when using this interface and the TraCI commands. The
commands are delivered to TraCI without any prior checks.</p>
</div>
</div>
<div class="alert alert-note">
<div>
<p>You can find the example application SumoTraciInteractionApp
in the additional examples bundle on the <a href="https://www.dcaiti.tu-berlin.de/research/simulation/download/" target="_blank">DCAITI website</a>.</p>
</div>
</div>
<hr>
<h2 id="debugging-of-applications">Debugging of applications</h2>
<p>To debug an application, remote debugging needs to be used. The following steps need to be performed
in order to debug the application:</p>
<ol>
<li>Open the application in your IDE.</li>
<li>Modify your <code>mosaic.sh</code> or <code>mosaic.bat</code> by adding debug parameters to the java call:<br>
<code>java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=4100 ...</code></li>
<li>Add a new debug profile in your IDE for remote debugging. Make sure to correctly configure port <code>4100</code> (or whichever port you provided in step 2).</li>
<li>Launch Eclipse MOSAIC with the argument <code>-w 0</code> to disable the watchdog timer otherwise it will interfere with debugging.</li>
<li>Connect your debugger in your IDE with the running simulation.</li>
</ol>
</div>
<div class="article-widget">
<div class="post-nav row col-12">
</div>
</div>
</div>
<footer class="site-footer">
<div class="row">
<div class="col-sm-4 mb-3 mb-md-0">
<b>Eclipse MOSAIC</b>
<ul>
<li>
<a href="/mosaic/download/" title="Download Eclipse MOSAIC" >
Download Eclipse MOSAIC
</a>
</li>
<li>
<a href="/mosaic/docs" title="Documentation" >
Documentation
</a>
</li>
<li>
<a href="/mosaic/tutorials" title="Tutorials" >
Tutorials
</a>
</li>
<li>
<a href="/mosaic/community/#projects" title="Projects" >
Projects
</a>
</li>
<li>
<a href="/mosaic/publications" title="Publications" >
Publications
</a>
</li>
</ul>
</div>
<div class="col-sm-4 mb-3 mb-md-0">
<b>Community</b>
<ul>
<li>
<a href="/mosaic/community" title="Eclipse MOSAIC Community" >
Eclipse MOSAIC Community
</a>
</li>
<li>
<a href="/mosaic/contribution" title="How to contribute" >
How to contribute
</a>
</li>
<li>
<a href="https://github.com/eclipse/mosaic" title="Github" target="_blank" rel="noopener">
Github
</a>
</li>
<li>
<a href="/mosaic/get_in_contact" title="Contact &amp; Mailing list" >
Contact & Mailing list
</a>
</li>
</ul>
</div>
<div class="col-sm-4 mb-3 mb-md-0">
<b>Eclipse Foundation</b>
<ul>
<li>
<a href="https://www.eclipse.org/" title="About Eclipse Foundation" target="_blank" rel="noopener">
About Eclipse Foundation
</a>
</li>
<li>
<a href="https://www.eclipse.org/legal/privacy.php" title="Privacy Policy" target="_blank" rel="noopener">
Privacy Policy
</a>
</li>
<li>
<a href="https://www.eclipse.org/legal/termsofuse.php" title="Website terms of use" target="_blank" rel="noopener">
Website terms of use
</a>
</li>
<li>
<a href="https://www.eclipse.org/legal/copyright.php" title="Copyright" target="_blank" rel="noopener">
Copyright
</a>
</li>
<li>
<a href="https://www.eclipse.org/legal" title="Legal" target="_blank" rel="noopener">
Legal
</a>
</li>
</ul>
</div>
</div>
<div class="row justify-content-center mt-3 position-relative">
<p class="powered-by text-center font-italic mb-0 pb-0">
Powered by the
<a href="https://sourcethemes.com/academic/" target="_blank" rel="noopener">Academic theme</a> for
<a href="https://gohugo.io" target="_blank" rel="noopener">Hugo</a>.
<br>
Header image &#169; fanjianhua/ iStock
</p>
</div>
</footer>
</article>
</main>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha384-vk5WoKIaW/vJyUAd9n/wmopsmNhiy+L2Z+SBxGYnUkunIxVxAv/UtMOhba/xskxh" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.imagesloaded/4.1.4/imagesloaded.pkgd.min.js" integrity="sha512-S5PZ9GxJZO16tT9r3WJp/Safn31eu8uWrzglMahDT4dsmgqWonRY9grk3j+3tfuPr9WJNsfooOR7Gi7HL5W2jw==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.isotope/3.0.6/isotope.pkgd.min.js" integrity="sha512-Zq2BOxyhvnRFXu0+WE6ojpZLOU2jdnqbrM1hmVdGzyeCa1DgM3X5Q4A/Is9xA1IkbUeDd7755dNNI/PzSf2Pew==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.js" integrity="sha512-uURl+ZXMBrF4AwGaWmEetzrd+J5/8NRkWAvJx5sbPSSuOb0bZLqf+tOzniObO00BjHa/dD7gub9oCGMLPQHtQA==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/8.4.8/mermaid.min.js" integrity="sha512-1tS1YUns336Mtxl+vkaLcADPwE1CPNVy3WEf7nrI7DGMMb6/FAVBgL2IzAWVBkB6vVuK94s2zVoiXcw1QZ9S1g==" crossorigin="anonymous" title="mermaid"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/highlight.min.js" integrity="sha512-1LdB3V708w6G4QRl7NsVdTr7MDibyRXr9stQZ+EGjEE0ZPMZkA//ir7kCWmFyxdAJNIRXdR/ZeJmCV0boyiCXw==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/languages/java.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/languages/json.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/languages/xml.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/languages/shell.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/languages/dos.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.1/leaflet.js" integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og==" crossorigin="anonymous"></script>
<script>const code_highlighting = true;</script>
<script>const isSiteThemeDark = false;</script>
<script>
const search_config = {"indexURI":"/mosaic/index.json","minLength":1,"threshold":0.3};
const i18n = {"no_results":"No results found","placeholder":"Search...","results":"results found"};
const content_type = {
'post': "Posts",
'project': "Projects",
'publication' : "Publications",
'talk' : "Talks"
};
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/anchor-js/4.1.1/anchor.min.js" integrity="sha512-aZotBPy6dqn8yVaLJwSrkJ+QxuxV695A4dgodAMvTU5JyNi5mhrr+LeaD3GSS+lx1SMFKNs0tu5ZMJEgNZQP2Q==" crossorigin="anonymous"></script>
<script>
anchors.add();
</script>
<script id="search-hit-fuse-template" type="text/x-template">
<div class="search-hit" id="summary-{{key}}">
<div class="search-hit-content">
<div class="search-hit-name">
<a href="{{relpermalink}}">{{title}}</a>
<div class="article-metadata search-hit-type">{{type}}</div>
<p class="search-hit-description">{{snippet}}</p>
</div>
</div>
</div>
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/3.2.1/fuse.min.js" integrity="sha512-o38bmzBGX+hD3JHWUFCDA09btWaqrNmoJ3RXLlrysA7PP01Kgs4UlE4MhelE1v5dJR3+cxlR4qQlotsW7jKsnw==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/jquery.mark.min.js" integrity="sha512-mhbv5DqBMgrWL+32MmsDOt/OAvqr/cHimk6B8y/bx/xS88MVkYGPiVv2ixKVrkywF2qHplNRUvFsAHUdxZ3Krg==" crossorigin="anonymous"></script>
<script type="application/javascript" src="/mosaic/js/academic.min.1824b36a85a484362f116f1e24481eb9.js"></script>
<script type="application/javascript" src="/mosaic/js/mosaic-wg-cards.js"></script>
<div id="modal" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Cite</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<pre><code class="tex hljs"></code></pre>
</div>
<div class="modal-footer">
<a class="btn btn-outline-primary my-1 js-copy-cite" href="#" target="_blank">
<i class="fas fa-copy"></i> Copy
</a>
<a class="btn btn-outline-primary my-1 js-download-cite" href="#" target="_blank">
<i class="fas fa-download"></i> Download
</a>
<div id="modal-error"></div>
</div>
</div>
</div>
</div>
</body>
</html>