blob: 71fa631037a825da5cd5a9cfa99505f7a6b6ec6f [file] [log] [blame]
<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>EndToEnd Test Framework &mdash; OpenPASS Documentation</title>
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../_static/css/custom.css" type="text/css" />
<link rel="stylesheet" href="../_static/tabs.css" type="text/css" />
<link rel="shortcut icon" href="../_static/openPASS.ico"/>
<!--[if lt IE 9]>
<script src="../_static/js/html5shiv.min.js"></script>
<![endif]-->
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/js/theme.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="IDE Support" href="../developer_information/10_ide_support.html" />
<link rel="prev" title="World_OSI" href="simulator/world_osi.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="../index.html" class="icon icon-home"> openPASS
<img src="../_static/openPASS.png" class="logo" alt="Logo"/>
</a>
<div class="version">
0.9.0
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption" role="heading"><span class="caption-text">Installation Guide</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../installation_guide/10_getting_started.html">Getting Started</a></li>
<li class="toctree-l1"><a class="reference internal" href="../installation_guide/20_install_prerequisites.html">Installing Prerequisites</a></li>
<li class="toctree-l1"><a class="reference internal" href="../installation_guide/30_install_openpass.html">Installing OpenPASS</a></li>
<li class="toctree-l1"><a class="reference internal" href="../installation_guide/50_further_guidance.html">Further Guidance</a></li>
<li class="toctree-l1"><a class="reference internal" href="../installation_guide/60_conan.html">Building with Conan</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">User Guides</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../user_guide/10_overview.html">Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="../user_guide/20_tutorials.html">Tutorials</a></li>
<li class="toctree-l1"><a class="reference internal" href="../user_guide/30_gui_plugins.html">GUI Plugins</a></li>
<li class="toctree-l1"><a class="reference internal" href="../user_guide/40_configs_in_depth.html">Configs in Depth</a></li>
<li class="toctree-l1"><a class="reference internal" href="../user_guide/50_outputs_in_depth.html">Outputs in Depth</a></li>
<li class="toctree-l1"><a class="reference internal" href="../user_guide/60_scenario_simulation.html">Simulator</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Advanced topics</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="20_simulator_advanced.html">Simulator</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">EndToEnd Test Framework</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#prerequisites">Prerequisites</a></li>
<li class="toctree-l2"><a class="reference internal" href="#test-configuration">Test Configuration</a></li>
<li class="toctree-l2"><a class="reference internal" href="#querying-results">Querying Results</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#basic-syntax">Basic Syntax</a></li>
<li class="toctree-l3"><a class="reference internal" href="#using-events-in-filter">Using Events in Filter</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#event-payload">Event Payload</a></li>
<li class="toctree-l4"><a class="reference internal" href="#query-example">Query Example</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#using-openscenario-events">Using openSCENARIO Events</a></li>
<li class="toctree-l3"><a class="reference internal" href="#querying-transitions">Querying Transitions</a></li>
<li class="toctree-l3"><a class="reference internal" href="#querying-spawning-time">Querying Spawning Time</a></li>
<li class="toctree-l3"><a class="reference internal" href="#explicit-datatypes">Explicit Datatypes</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#dev-notes">Dev Notes</a></li>
</ul>
</li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Developer Information</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../developer_information/10_ide_support.html">IDE Support</a></li>
<li class="toctree-l1"><a class="reference internal" href="../developer_information/20_documentation.html">Documentation Concept</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Other Information</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../other_information/10_external_dependencies.html">External Dependencies</a></li>
<li class="toctree-l1"><a class="reference internal" href="../other_information/20_glossary.html">Glossary</a></li>
<li class="toctree-l1"><a class="reference internal" href="../other_information/30_license.html">License</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../index.html">openPASS</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="../index.html" class="icon icon-home"></a> &raquo;</li>
<li>EndToEnd Test Framework</li>
<li class="wy-breadcrumbs-aside">
<a href="../_sources/advanced_topics/30_testing.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<section id="endtoend-test-framework">
<span id="testing-endtoend"></span><h1>EndToEnd Test Framework<a class="headerlink" href="#endtoend-test-framework" title="Permalink to this headline"></a></h1>
<p><strong>pyOpenPASS</strong></p>
<p>This tool acts as configurable executor for complete sets of configs for the openPASS simulation.
The test framework is located at <code class="docutils literal notranslate"><span class="pre">sim/tests/endToEndTests/pyOpenPASS</span></code>.</p>
<section id="prerequisites">
<h2>Prerequisites<a class="headerlink" href="#prerequisites" title="Permalink to this headline"></a></h2>
<p>Please refer to <a class="reference internal" href="../installation_guide/20_install_prerequisites.html#binary-packages"><span class="std std-ref">Installing the Binary Packages</span></a> for instructions on installing the prerequisites.
Execution
———</p>
<p>As pyOpenPASS is a pytest plugin (and is not yet a standalone-plugin) it will be automatically executed, when pytest finds its entry-point <code class="docutils literal notranslate"><span class="pre">conftest.py</span></code> (= local-pytest-plugin) next to files named <code class="docutils literal notranslate"><span class="pre">test_*.json</span></code>.
So test files must be copied into the pyOpenPASS directory before execution.</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>pytest
--simulation<span class="o">=</span>SIMULATION_EXE <span class="c1"># path to simulation executable, e.g. /openPASS/bin/opSimulation</span>
--mutual<span class="o">=</span>MUTUAL_RESOURCES_PATH <span class="c1"># path to mutual config files for all runs, e.g. /openPASS/bin/examples/common</span>
--resources<span class="o">=</span>RESOURCES_PATH <span class="c1"># path from where configs are retrieved - override common files if necessary</span>
--report-path<span class="o">=</span>REPORT_PATH <span class="c1"># path to where the report shall be stored</span>
TEST_FILE <span class="c1"># file under test, named `test_*.json`</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>You can use additional pytest arguments, such as <code class="docutils literal notranslate"><span class="pre">-v</span></code> for verbose output, <code class="docutils literal notranslate"><span class="pre">--collect-only</span></code> for listing the available tests and so on (see <a class="reference external" href="https://docs.pytest.org">https://docs.pytest.org</a>).</p>
</div>
<p>For each specified <code class="docutils literal notranslate"><span class="pre">test_*.json</span></code> a corresponding <code class="docutils literal notranslate"><span class="pre">test_*.html</span></code> will be generated.</p>
</section>
<section id="test-configuration">
<h2>Test Configuration<a class="headerlink" href="#test-configuration" title="Permalink to this headline"></a></h2>
<p>Test configuiration is by the test-json file, individually for each test.
Depending on the users choice, three different tests runners are executed:</p>
<ol class="arabic simple">
<li><p>Determinism: Check executability of configs + Determinism test (<em>1 x n</em> vs <em>n x 1</em> tests).</p></li>
<li><p>Parameterized: Check executability of configs using different parameters.</p></li>
<li><p>Query: Execute config and check for specific results in the output of the simulator, given one or more queries.</p></li>
</ol>
<p>In general, the test-json splits into two sections:</p>
<ol class="arabic simple">
<li><p>Definition of <code class="docutils literal notranslate"><span class="pre">Configuration</span> <span class="pre">Sets</span></code></p></li>
<li><p>Definition of <code class="docutils literal notranslate"><span class="pre">Tests</span></code> using the sets</p></li>
</ol>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Whenever possible, pyOpenPASS re-uses the results of <code class="docutils literal notranslate"><span class="pre">Configuration</span> <span class="pre">Sets</span></code> to speed up result analysis.</p>
</div>
<div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="p">{</span>
<span class="s2">&quot;config_sets&quot;</span><span class="o">:</span> <span class="p">{</span>
<span class="s2">&quot;Config_Set_1&quot;</span><span class="o">:</span> <span class="p">[</span> <span class="c1">// user defined name</span>
<span class="s2">&quot;Config_Folder_1&quot;</span><span class="p">,</span>
<span class="s2">&quot;Config_Folder_2&quot;</span>
<span class="p">],</span>
<span class="s2">&quot;Config_Set_2&quot;</span><span class="o">:</span> <span class="p">[</span>
<span class="s2">&quot;Config_Folder_2&quot;</span><span class="p">,</span>
<span class="s2">&quot;Config_Folder_3&quot;</span>
<span class="p">],</span>
<span class="s2">&quot;Config_Set_3&quot;</span><span class="o">:</span> <span class="p">[</span>
<span class="s2">&quot;Config_Folder_4&quot;</span>
<span class="p">]</span>
<span class="p">},</span>
<span class="s2">&quot;tests&quot;</span><span class="o">:</span> <span class="p">{</span>
<span class="s2">&quot;Execution and Determinism&quot;</span><span class="o">:</span> <span class="p">{</span>
<span class="s2">&quot;config_sets&quot;</span><span class="o">:</span> <span class="p">[</span>
<span class="s2">&quot;Config_Set_1&quot;</span><span class="p">,</span>
<span class="s2">&quot;Config_Set_2&quot;</span><span class="p">,</span>
<span class="s2">&quot;Config_Set_3&quot;</span>
<span class="p">],</span>
<span class="s2">&quot;determinism&quot;</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="c1">// ACTIVATES DETERMINISM</span>
<span class="s2">&quot;duration&quot;</span><span class="o">:</span> <span class="mf">30</span><span class="p">,</span> <span class="c1">// how long shall be simulated</span>
<span class="s2">&quot;invocations&quot;</span><span class="o">:</span> <span class="mf">3</span> <span class="c1">// compare 1x3 run with 3x1 runs</span>
<span class="p">},</span>
<span class="s2">&quot;Parameterization&quot;</span><span class="o">:</span> <span class="p">{</span>
<span class="s2">&quot;config_sets&quot;</span><span class="o">:</span> <span class="p">[</span>
<span class="s2">&quot;Config_Set_2&quot;</span>
<span class="p">],</span>
<span class="s2">&quot;parameterization&quot;</span><span class="o">:</span> <span class="p">{</span> <span class="c1">// ACTIVATES PARAMETERIZATION</span>
<span class="s2">&quot;file&quot;</span><span class="o">:</span> <span class="s2">&quot;systemConfigFmu.xml&quot;</span><span class="p">,</span> <span class="c1">// Name of config, which shall be parameterized</span>
<span class="s2">&quot;xpath&quot;</span><span class="o">:</span> <span class="s2">&quot;//value[../id=&#39;FmuPath&#39;]&quot;</span><span class="p">,</span> <span class="c1">// XPath, where values needs to be replaced</span>
<span class="s2">&quot;values&quot;</span><span class="o">:</span> <span class="p">[</span> <span class="c1">// Values, which shall be set</span>
<span class="s2">&quot;resources/FMU1_StaticFMU.fmu&quot;</span><span class="p">,</span>
<span class="s2">&quot;resources/FMU2_StaticFMU.fmu&quot;</span>
<span class="p">],</span>
<span class="s2">&quot;duration&quot;</span><span class="o">:</span> <span class="mf">10</span><span class="p">,</span>
<span class="s2">&quot;invocations&quot;</span><span class="o">:</span> <span class="mf">100</span>
<span class="p">},</span>
<span class="s2">&quot;Querying&quot;</span><span class="o">:</span> <span class="p">{</span>
<span class="s2">&quot;config_sets&quot;</span><span class="o">:</span> <span class="p">[</span>
<span class="s2">&quot;Config_Set_3&quot;</span>
<span class="p">],</span>
<span class="s2">&quot;queries&quot;</span><span class="o">:</span> <span class="p">[</span> <span class="c1">// ACTIVATES QUERYING</span>
<span class="s2">&quot;count(AgentId | AgentId == 0 and Timestep == 10000 and VelocityEgo &gt;= 30) == 1&quot;</span><span class="p">,</span>
<span class="s2">&quot;mean(VelocityEgo | AgentId != 0) &gt; 30&quot;</span>
<span class="p">],</span>
<span class="s2">&quot;success_rate&quot;</span><span class="o">:</span> <span class="mf">0.8</span><span class="p">,</span> <span class="c1">// 80% of 60 invocations needs to pass</span>
<span class="s2">&quot;duration&quot;</span><span class="o">:</span> <span class="mf">10</span><span class="p">,</span>
<span class="s2">&quot;invocations&quot;</span><span class="o">:</span> <span class="mf">60</span><span class="p">,</span>
<span class="s2">&quot;description&quot;</span><span class="o">:</span> <span class="s2">&quot;Optional description&quot;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</section>
<section id="querying-results">
<h2>Querying Results<a class="headerlink" href="#querying-results" title="Permalink to this headline"></a></h2>
<section id="basic-syntax">
<h3>Basic Syntax<a class="headerlink" href="#basic-syntax" title="Permalink to this headline"></a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">aggregate</span><span class="p">]([</span><span class="n">column</span><span class="p">]</span> <span class="o">|</span> <span class="p">[</span><span class="nb">filter</span><span class="p">])</span> <span class="p">[</span><span class="n">operator</span><span class="p">]</span> <span class="p">[</span><span class="n">value</span><span class="p">]</span>
</pre></div>
</div>
<ul class="simple">
<li><p>Aggregate:
Everything pandas supports on dataframes, such as <a class="reference external" href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.count.html?highlight=count#pandas.DataFrame.count">pandas.DataFrame.count</a>, min, max, mean</p></li>
<li><p>Column:
A column on which the aggregate should operate.
Columns are given by the simulation outputs cyclic columns, such as <code class="docutils literal notranslate"><span class="pre">PositionRoute</span></code>.
Additionally <code class="docutils literal notranslate"><span class="pre">AgentId</span></code> is made available.</p></li>
<li><p>Filter:
A filter based on <a class="reference external" href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.filter.html?highlight=filter#pandas.DataFrame.filter">pandas.DataFrame.filter</a> syntax using the available columns.</p></li>
<li><p>Operator:
A comparison operator from the following list: ==, &lt;=, &gt;=, &lt;, &gt;, !=, ~= (approximate).
The approximate operator allows <code class="docutils literal notranslate"><span class="pre">1*e-6</span> <span class="pre">x</span> <span class="pre">value</span></code> as maximum deviation from value.</p></li>
<li><p>Value:
A number</p></li>
</ul>
<p><strong>Example</strong></p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">count</span><span class="p">(</span><span class="n">AgentId</span> <span class="o">|</span> <span class="n">PositionRoute</span> <span class="o">&gt;=</span> <span class="mi">800</span> <span class="ow">and</span> <span class="n">Lane</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">3</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span>
</pre></div>
</div>
</section>
<section id="using-events-in-filter">
<h3>Using Events in Filter<a class="headerlink" href="#using-events-in-filter" title="Permalink to this headline"></a></h3>
<p>In order to query for a specific event, use <code class="docutils literal notranslate"><span class="pre">#(EVENT)</span></code> within the filter syntax.</p>
<p><strong>Example</strong></p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">count</span><span class="p">(</span><span class="n">AgentId</span> <span class="o">|</span> <span class="n">PositionRoute</span> <span class="o">&gt;=</span> <span class="mi">800</span> <span class="ow">and</span> <span class="c1">#(Collision) == True) == 0</span>
</pre></div>
</div>
<section id="event-payload">
<h4>Event Payload<a class="headerlink" href="#event-payload" title="Permalink to this headline"></a></h4>
<p>Each event is associated with a set of triggering entity ids, affected entity ids, and arbitrary key/value pairs (please refer to the openPASS documentation for details).
This information is transformed into a “per agent” scope.</p>
<p>In the following the <code class="docutils literal notranslate"><span class="pre">Collision</span></code> event is taken as example.</p>
<p><strong>TriggeringEntity</strong></p>
<p>All agents, flagged as triggering become <code class="docutils literal notranslate"><span class="pre">IsTriggering</span></code></p>
<p>Query: <code class="docutils literal notranslate"><span class="pre">#(Collision):IsTriggering</span> <span class="pre">==</span> <span class="pre">True</span></code></p>
<p><strong>AffectedEntity</strong></p>
<p>All agents, flagged as affected become <code class="docutils literal notranslate"><span class="pre">IsAffected</span></code></p>
<p>Query: <code class="docutils literal notranslate"><span class="pre">#(Collision):IsAffected</span> <span class="pre">==</span> <span class="pre">True</span></code></p>
<p><strong>Key/Value Pairs</strong></p>
<p>If an event publishes additional payload with the key <code class="docutils literal notranslate"><span class="pre">XYZ</span></code>, it will can be queried by <code class="docutils literal notranslate"><span class="pre">#(EVENT):XYZ</span></code>.</p>
<p>Query: <code class="docutils literal notranslate"><span class="pre">#(Collision):WithAgent</span></code></p>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>Keys carrying the event name as prefix, such as in <code class="docutils literal notranslate"><span class="pre">#(Collision):CollisionWithAgent</span></code>, will be stripped to <code class="docutils literal notranslate"><span class="pre">Collision:WithAgent</span></code></p>
</div>
</section>
<section id="query-example">
<h4>Query Example<a class="headerlink" href="#query-example" title="Permalink to this headline"></a></h4>
<div class="line-block">
<div class="line"><em>No agent should collide with agent 0:</em></div>
<div class="line"><code class="docutils literal notranslate"><span class="pre">count(AgentId</span> <span class="pre">|</span> <span class="pre">AgentId</span> <span class="pre">==</span> <span class="pre">0</span> <span class="pre">and</span> <span class="pre">#(Collision):WithAgent</span> <span class="pre">==</span> <span class="pre">1)</span> <span class="pre">==</span> <span class="pre">0</span></code></div>
</div>
</section>
</section>
<section id="using-openscenario-events">
<h3>Using openSCENARIO Events<a class="headerlink" href="#using-openscenario-events" title="Permalink to this headline"></a></h3>
<p>OpenScenario events are processed in the same manner as regular events (see above).</p>
<p>This allows to query for occurrences of openSCENARIO events with a name specified within the following xpath:
<code class="docutils literal notranslate"><span class="pre">OpenSCENARIO/Story/Act/Sequence/Maneuver/Event/&#64;name</span></code></p>
<p><strong>openSCENARIO Event Definition</strong></p>
<div class="highlight-xml notranslate"><div class="highlight"><pre><span></span><span class="nt">&lt;Story</span> <span class="na">name=</span><span class="s">&quot;TheStory&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;Act</span> <span class="na">name=</span><span class="s">&quot;TheAct&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;Sequence</span> <span class="na">name=</span><span class="s">&quot;TheSequence&quot;</span> <span class="na">numberOfExecutions=</span><span class="s">&quot;1&quot;</span><span class="nt">&gt;</span>
...
<span class="nt">&lt;Maneuver</span> <span class="na">name=</span><span class="s">&quot;TheManeuver&quot;</span><span class="nt">&gt;</span>
...
<span class="c">&lt;!-- example name &quot;ttc_event&quot;--&gt;</span>
<span class="nt">&lt;Event</span> <span class="na">name=</span><span class="s">&quot;ttc_event&quot;</span> <span class="na">priority=</span><span class="s">&quot;overwrite&quot;</span><span class="nt">&gt;</span>
...
<span class="nt">&lt;StartConditions&gt;</span>
<span class="nt">&lt;ConditionGroup&gt;</span>
<span class="nt">&lt;Condition</span> <span class="na">name=</span><span class="s">&quot;Conditional&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;ByEntity&gt;</span>
...
<span class="nt">&lt;EntityCondition&gt;</span>
<span class="nt">&lt;TimeToCollision&gt;</span>
...
<span class="nt">&lt;/TimeToCollision&gt;</span>
<span class="nt">&lt;/EntityCondition&gt;</span>
<span class="nt">&lt;/ByEntity&gt;</span>
<span class="nt">&lt;/Condition&gt;</span>
<span class="nt">&lt;/ConditionGroup&gt;</span>
<span class="nt">&lt;/StartConditions&gt;</span>
<span class="nt">&lt;/Event&gt;</span>
...
<span class="nt">&lt;/Maneuver&gt;</span>
<span class="nt">&lt;/Sequence&gt;</span>
<span class="nt">&lt;/Act&gt;</span>
<span class="nt">&lt;/Story&gt;</span>
</pre></div>
</div>
<p><strong>Example openPASS Output</strong></p>
<div class="highlight-xml notranslate"><div class="highlight"><pre><span></span><span class="nt">&lt;Event</span> <span class="na">Time=</span><span class="s">&quot;0&quot;</span> <span class="na">Source=</span><span class="s">&quot;OpenSCENARIO&quot;</span> <span class="na">Name=</span><span class="s">&quot;TheStory/TheAct/TheSequence/TheManeuver/ttc_event&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;TriggeringEntities/&gt;</span>
<span class="nt">&lt;AffectedEntities&gt;</span>
<span class="nt">&lt;Entity</span> <span class="na">Id=</span><span class="s">&quot;1&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/AffectedEntities&gt;</span>
<span class="nt">&lt;Parameters/&gt;</span>
<span class="nt">&lt;/Event&gt;</span>
</pre></div>
</div>
<p><strong>Query</strong></p>
<p><code class="docutils literal notranslate"><span class="pre">count(AgentId</span> <span class="pre">|</span> <span class="pre">#(TheStory/TheAct/TheSequence/TheManeuver/ttc_event)</span> <span class="pre">==</span> <span class="pre">True</span> <span class="pre">)</span> <span class="pre">&gt;</span> <span class="pre">0</span></code></p>
</section>
<section id="querying-transitions">
<h3>Querying Transitions<a class="headerlink" href="#querying-transitions" title="Permalink to this headline"></a></h3>
<p>Sometimes it is necessary to check, whether a transition happened, such as counting agents, passing a certain position.</p>
<p>This can be achieved by shifting individual columns by <code class="docutils literal notranslate"><span class="pre">N</span></code> time steps.</p>
<p><strong>Time Shift Syntax</strong></p>
<p><code class="docutils literal notranslate"><span class="pre">Column-Shift</span></code> =&gt; <code class="docutils literal notranslate"><span class="pre">PositionRoute-1</span></code> means PositionRoute at one time step earlier</p>
<p><strong>Example Use Case</strong></p>
<p>Counting agents passing <code class="docutils literal notranslate"><span class="pre">PositionRoute</span> <span class="pre">==</span> <span class="pre">350</span></code> on <code class="docutils literal notranslate"><span class="pre">LaneId</span> <span class="pre">==</span> <span class="pre">-1</span></code></p>
<p><strong>Query</strong></p>
<p><code class="docutils literal notranslate"><span class="pre">count(AgentId</span> <span class="pre">|</span> <span class="pre">LaneId</span> <span class="pre">==</span> <span class="pre">-1</span> <span class="pre">and</span> <span class="pre">PositionRoute-1</span> <span class="pre">&lt;</span> <span class="pre">350</span> <span class="pre">and</span> <span class="pre">PositionRoute</span> <span class="pre">&gt;=</span> <span class="pre">350</span> <span class="pre">)</span> <span class="pre">&gt;</span> <span class="pre">0</span></code></p>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>In seldom cases, a result column happens to have a name like <code class="docutils literal notranslate"><span class="pre">Name-N</span></code> where <code class="docutils literal notranslate"><span class="pre">N</span></code> is an integer.
Querying this column would automatically apply time shifting (default behavior) leading to a parsing error.
In such cases, escape the column name with single quotes (e.g. <code class="docutils literal notranslate"><span class="pre">'Name-1'</span></code>).</p>
</div>
</section>
<section id="querying-spawning-time">
<h3>Querying Spawning Time<a class="headerlink" href="#querying-spawning-time" title="Permalink to this headline"></a></h3>
<p>Queries can be restricted to the spawning time:</p>
<p><strong>Query</strong></p>
<p><code class="docutils literal notranslate"><span class="pre">count(AgentId</span> <span class="pre">|</span> <span class="pre">Timestep</span> <span class="pre">==</span> <span class="pre">{first}</span> <span class="pre">and</span> <span class="pre">Velocity</span> <span class="pre">&lt;</span> <span class="pre">30)</span> <span class="pre">==</span> <span class="pre">0</span></code></p>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p><code class="docutils literal notranslate"><span class="pre">Timestep</span> <span class="pre">==</span> <span class="pre">{first}</span></code> must be the first parameter in the filter and can only succeeded by <code class="docutils literal notranslate"><span class="pre">and</span></code>.</p>
</div>
</section>
<section id="explicit-datatypes">
<h3>Explicit Datatypes<a class="headerlink" href="#explicit-datatypes" title="Permalink to this headline"></a></h3>
<p>pyOpenPASS uses Pandas DataFrames internally.
Pandas will try to detect the datatype of the individual cyclic columns automatically.
This won’t fit the user’s intention in some cases, such as when the column holds a semicolon separated list of integers but every list contains just one element.
In such cases it is impossible to distinguish between integers and strings based on the data.</p>
<p>For this reason, datatypes can be specified explicitly along with a query:</p>
<div class="highlight-js notranslate"><div class="highlight"><pre><span></span><span class="s2">&quot;queries&quot;</span><span class="o">:</span> <span class="p">[</span> <span class="p">...</span> <span class="p">],</span>
<span class="s2">&quot;datatypes&quot;</span><span class="o">:</span> <span class="p">{</span>
<span class="s2">&quot;Sensor0_DetectedAgents&quot;</span><span class="o">:</span> <span class="s2">&quot;str&quot;</span> <span class="c1">// string with &quot;missing value&quot; support</span>
<span class="p">}</span>
</pre></div>
</div>
</section>
</section>
<section id="dev-notes">
<h2>Dev Notes<a class="headerlink" href="#dev-notes" title="Permalink to this headline"></a></h2>
<p>If you want to execute/debug pyOpenPASS in VS-Code, you can add a configuration, similar to the one shown below, to the <code class="docutils literal notranslate"><span class="pre">launch.json</span></code> after opening pyOpenPASS as VS-Code project:</p>
<div class="highlight-json notranslate"><div class="highlight"><pre><span></span>&quot;configurations&quot;: [
{
&quot;name&quot;: &quot;pytest-openpass&quot;,
&quot;type&quot;: &quot;python&quot;,
&quot;module&quot;: &quot;pytest&quot;,
&quot;args&quot;: [
&quot;--simulation=/OpenPASS/bin/core/opSimulation&quot;,
&quot;--mutual=/OpenPASS/bin/core/examples/OSS/Common/&quot;,
&quot;--resources=/OpenPASS/bin/core/examples/OSS/Configurations/&quot;,
&quot;--report-path=/OpenPASS/reports&quot;,
&quot;test_end_to_end.json&quot;,
&quot;-v&quot;],
&quot;request&quot;: &quot;launch&quot;,
&quot;console&quot;: &quot;integratedTerminal&quot;
}]
</pre></div>
</div>
</section>
</section>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="simulator/world_osi.html" class="btn btn-neutral float-left" title="World_OSI" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="../developer_information/10_ide_support.html" class="btn btn-neutral float-right" title="IDE Support" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2022 OpenPASS Working Group.</p>
</div>
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>