<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://developer.remotivelabs.com/engineering-blog</id>
    <title>RemotiveLabs Developer Blog</title>
    <updated>2026-11-04T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://developer.remotivelabs.com/engineering-blog"/>
    <subtitle>RemotiveLabs Developer Blog</subtitle>
    <icon>https://developer.remotivelabs.com/img/favicon.ico</icon>
    <entry>
        <title type="html"><![CDATA[A graph view for topologies in RemotiveStudio]]></title>
        <id>https://developer.remotivelabs.com/engineering-blog/2026/11/04/topology-graph-view</id>
        <link href="https://developer.remotivelabs.com/engineering-blog/2026/11/04/topology-graph-view"/>
        <updated>2026-11-04T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[RemotiveStudio's new graph view draws the channels and ECUs of a topology as one diagram. Select an ECU to see which ECUs it exchanges signals with.]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-it-does">What it does<a href="https://developer.remotivelabs.com/engineering-blog/2026/11/04/topology-graph-view#what-it-does" class="hash-link" aria-label="Direct link to What it does" title="Direct link to What it does">​</a></h2>
<p>RemotiveStudio has a new <strong>graph view</strong> that draws a whole topology as one diagram: one bar
per channel, with its ECUs on it. In it, you can:</p>
<ul>
<li>Click an ECU to see which ECUs it exchanges signals with, and to list its frames and
signals.</li>
<li>Search for an ECU or a channel, for example <code>ecu:GWM</code> or <code>bodycan</code>.</li>
<li>On a large platform, use the filter to draw only some channels and ECUs.</li>
<li>Export the graph as a <code>PNG</code> or <code>SVG</code> image to put it in a document or a slide.</li>
</ul>
<p>When you look at a running topology, the graph also shows the activity on each channel.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-it-looks-like">What it looks like<a href="https://developer.remotivelabs.com/engineering-blog/2026/11/04/topology-graph-view#what-it-looks-like" class="hash-link" aria-label="Direct link to What it looks like" title="Direct link to What it looks like">​</a></h2>
<video width="100%" height="auto" controls="" autoplay="" muted="" loop="" playsinline=""><source src="https://storage.googleapis.com/public-cloud-assets/docs/videos/topology-graph-view.mp4"></video>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="try-it">Try it<a href="https://developer.remotivelabs.com/engineering-blog/2026/11/04/topology-graph-view#try-it" class="hash-link" aria-label="Direct link to Try it" title="Direct link to Try it">​</a></h2>
<p>Open a topology file (an instance or platform file) or a signal database in RemotiveStudio,
or connect to a running topology. Select the graph icon next to the tree view. If you don't
have a topology, start with one of the <a href="https://developer.remotivelabs.com/docs/remotive-topology/usage/examples">RemotiveTopology examples</a>.</p>]]></content>
        <author>
            <name>Ola Nilsson</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Start RemotiveTopology with Horizon CLI]]></title>
        <id>https://developer.remotivelabs.com/engineering-blog/2026/10/26/horizon-cli</id>
        <link href="https://developer.remotivelabs.com/engineering-blog/2026/10/26/horizon-cli"/>
        <updated>2026-10-26T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Google Horizon now includes a CLI that allows you to quickly start a virtual RemotiveTopology test bench.]]></summary>
        <content type="html"><![CDATA[<p>RemotiveTopology was <a href="https://www.remotivelabs.com/blog/remotivelabs-technology-on-google-cloud" target="_blank" rel="noopener noreferrer">recently added</a> to <a href="https://github.com/googleCloudPlatform/horizon-sdv/" target="_blank" rel="noopener noreferrer">Google Horizon</a> which is an open source software development platform built by Google Cloud. Horizon is designed to help automotive manufacturers and suppliers build, test, and deploy software for Android Automotive Operating System (AAOS) more efficiently.</p>
<p>This blog post shows how easy Horizon CLI allows you to start a virtual test bench running RemotiveTopology. A virtual test bench allows you to run part of a vehicle and interactively explore it without installing anything on your local machine.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="setup">Setup<a href="https://developer.remotivelabs.com/engineering-blog/2026/10/26/horizon-cli#setup" class="hash-link" aria-label="Direct link to Setup" title="Direct link to Setup">​</a></h2>
<p>After <a href="https://github.com/GoogleCloudPlatform/horizon-sdv/blob/main/docs/deployment_guide.md" target="_blank" rel="noopener noreferrer">installing</a> Horizon in your Google Cloud Project, make sure you enable the modules <strong>workloads-common</strong> and <strong>remotive-topology</strong>. Follow the setup instructions for RemotiveTopology.</p>
<p>Setting up the Horizon CLI is very easy:</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token builtin class-name">export</span><span class="token plain"> </span><span class="token assign-left variable" style="color:#36acaa">HORIZON_DOMAIN</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">horizon.yourdomain.com</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">horizon auth login</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>In order to start a RemotiveTopology VM in your Google Cloud you must create a template that describes the type of instance that's used. To run the RemotiveCar example with Cuttlefish you should at least use <code>n2-standard-16</code> with 200 GB disk. Also make sure to enable nested virtualization which is needed for Cuttlefish. Smaller topologies can be run on smaller instances. You only need to create a template once:</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">horizon workflow submit </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token parameter variable" style="color:#36acaa">--module</span><span class="token plain"> remotive-topology </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token parameter variable" style="color:#36acaa">--template</span><span class="token plain"> remotive-instance-template </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    --params-json </span><span class="token string" style="color:#e3116c">'{"instanceName": "remotive-cf-vm", "machineType": "n2-standard-16", "bootDiskSize": "200", "enableNestedVirtualization": "true"}'</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="starting-remotivetopology">Starting RemotiveTopology<a href="https://developer.remotivelabs.com/engineering-blog/2026/10/26/horizon-cli#starting-remotivetopology" class="hash-link" aria-label="Direct link to Starting RemotiveTopology" title="Direct link to Starting RemotiveTopology">​</a></h2>
<p>Once the setup has been completed it's very simple to start a virtual test bench:</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">horizon workflow submit </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token parameter variable" style="color:#36acaa">--module</span><span class="token plain"> remotive-topology </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token parameter variable" style="color:#36acaa">--template</span><span class="token plain"> remotive-launcher </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    --params-json </span><span class="token string" style="color:#e3116c">'{"topologyName": "remotive_car", "topologyDownloadUrl": "https://files.remotivelabs.com/experimental/remotive_car-0.6.0-organicmaps.tgz", "instanceTemplateName": "instance-template-remotive-cf-vm", "runTopologyTests": "false", "keepAliveTime": "60", "mtkConnectPublic": "false"}'</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Notice:</p>
<ul>
<li><code>runTopologyTests=false</code> since the goal with this example is to create virtual test bench which you can interact and experiment with. When running in CI change this to <code>true</code> and make sure the topology includes test cases.</li>
<li><code>mtkConnectPublic=false</code> to only give yourself access to the test bench. When running in CI change this to <code>true</code> to allow anyone to investigate errors.</li>
<li><code>keepAliveTime=60</code> to keep the test bench for 60 minutes. Feel free to change this! This ensures that you don't incur unnecessary costs.</li>
<li>In this case <code>topologyDownloadUrl</code> specifies the example RemotiveCar bundled with <a href="https://organicmaps.app/" target="_blank" rel="noopener noreferrer">Organic Maps</a>. You can also using Google Cloud storage to access your private topologies.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="where-to-go-next">Where to go next<a href="https://developer.remotivelabs.com/engineering-blog/2026/10/26/horizon-cli#where-to-go-next" class="hash-link" aria-label="Direct link to Where to go next" title="Direct link to Where to go next">​</a></h2>
<ul>
<li><a href="https://developer.remotivelabs.com/docs/remotive-topology">RemotiveTopology</a>: learn more about RemotiveTopology</li>
<li><a href="https://developer.remotivelabs.com/docs/remotive-topology/usage/examples">RemotiveTopology examples</a>: the examples repository, a good place to start from a working setup.</li>
<li><a href="https://github.com/googleCloudPlatform/horizon-sdv/" target="_blank" rel="noopener noreferrer">Google Horizon</a>: source code for Horizon</li>
<li><a href="https://www.remotivelabs.com/blog/remotivelabs-technology-on-google-cloud" target="_blank" rel="noopener noreferrer">RemotiveTopology in Horizon</a>: press release about RemotiveTopology in Horizon</li>
</ul>]]></content>
        <author>
            <name>Jan Kronquist</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Integrating an FMU with Python]]></title>
        <id>https://developer.remotivelabs.com/engineering-blog/2026/10/20/fmu-integration-python</id>
        <link href="https://developer.remotivelabs.com/engineering-blog/2026/10/20/fmu-integration-python"/>
        <updated>2026-10-20T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Run a Functional Mock-up Unit (FMU) as a behavioral model in RemotiveTopology, with a few lines of Python that map bus signals to FMU inputs and outputs.]]></summary>
        <content type="html"><![CDATA[<p>If someone on your team already models a system in a simulation tool, there's a good chance
you can use that model directly with RemotiveTopology. The <code>fmu</code> module in the RemotiveTopology
Python framework lets you load the exported FMU, connect it to the signals on your virtual
buses, and run it next to everything else in the topology.</p>
<p>The code in this post is a slice of the RemotiveCar example, where the body control module
(BCM) runs as an FMU. It only maps the turn stalk signals as input and the left and right turn
lights signals as output, which keeps it small enough to reason about. For the complete,
runnable setup, with every input and output mapped, see the
<a href="https://github.com/remotivelabs/remotivelabs-topology-examples/blob/main/usecases/FMU_MODELS.md" target="_blank" rel="noopener noreferrer">FMU use case</a>
in the examples repository.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-an-fmu-is-and-when-you-would-use-one">What an FMU is and when you would use one<a href="https://developer.remotivelabs.com/engineering-blog/2026/10/20/fmu-integration-python#what-an-fmu-is-and-when-you-would-use-one" class="hash-link" aria-label="Direct link to What an FMU is and when you would use one" title="Direct link to What an FMU is and when you would use one">​</a></h2>
<p>A Functional Mock-up Unit is a packaged simulation model, following the Functional Mock-up
Interface (FMI) standard, that many modeling tools can export. It's a zip file with a model
description (the inputs, outputs, and default experiment settings) and the compiled model.</p>
<p>An FMU can represent a complete ECU or one of its software components. It can also model
physical systems affected by the ECU, such as power consumption or vehicle dynamics, to
simulate the effects of the ECU running. In either case, models react to what's on the bus
and produce realistic outputs. The RemotiveTopology Python API provides a straightforward
way to connect an FMU to RemotiveTopology.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="prerequisites">Prerequisites<a href="https://developer.remotivelabs.com/engineering-blog/2026/10/20/fmu-integration-python#prerequisites" class="hash-link" aria-label="Direct link to Prerequisites" title="Direct link to Prerequisites">​</a></h2>
<p>You need a working RemotiveTopology setup with Docker (or Podman), RemotiveCLI with an
active subscription, and Python 3.10 or later for behavioral models, as described in
<a href="https://developer.remotivelabs.com/docs/remotive-topology/install">Install</a>.</p>
<p>FMU support is an optional dependency of <code>remotivelabs-topology</code>, called <code>fmu</code>. It needs
<code>fmpy</code> and <code>numpy</code>, which are large and normally not needed, so they're only
installed when you ask for them:</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">pip </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> remotivelabs-topology</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">fmu</span><span class="token punctuation" style="color:#393A34">]</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Then the FMU itself. The framework drives the model one step at a time, so it needs to be:</p>
<ul>
<li>an FMI 2.0 or 3.0 <strong>Co-Simulation</strong> FMU,</li>
<li>configured with a fixed step size and no internal solver,</li>
<li>carrying a <code>defaultExperiment</code> in its model description (that's where the step size is read from).</li>
</ul>
<p>If the FMU doesn't support co-simulation or lacks a default experiment, loading it fails
with an error straight away, which is a nice early warning.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="loading-the-fmu-from-python">Loading the FMU from Python<a href="https://developer.remotivelabs.com/engineering-blog/2026/10/20/fmu-integration-python#loading-the-fmu-from-python" class="hash-link" aria-label="Direct link to Loading the FMU from Python" title="Direct link to Loading the FMU from Python">​</a></h2>
<p>The entry point is <code>FMUSimulation</code>. Give it a path, and it reads the model description,
instantiates the FMU and resets it to its initial state:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> pathlib </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> Path</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> remotivelabs</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">topology</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">fmu </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> FMUSimulation</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">fmu </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> FMUSimulation</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Path</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"BCM.fmu"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">fmu</span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic"># dump model information and variables</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fmu</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">step_size</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fmu</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">input_var_names</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fmu</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">output_var_names</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><code>print()</code> is a good first thing to run on a new FMU: it shows the variable names you'll need
in the next step. For the BCM, that includes the <code>turn_stalk</code> input and the
<code>left_turn_light</code> and <code>right_turn_light</code> outputs. The step size comes from the default
experiment, 50 ms for the BCM, but you can override it with
<code>FMUSimulation(path, step_size=0.01)</code> (step time given in seconds).</p>
<p>Each call to <code>await fmu.step()</code> advances the simulation by one step, applies the current
inputs and returns the outputs. You can also set an input directly with
<code>fmu.set_input_value("name", value)</code>; it sticks for all future steps, and an unknown name
raises a <code>ValueError</code>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="mapping-fmu-inputs-and-outputs-to-signals">Mapping FMU inputs and outputs to signals<a href="https://developer.remotivelabs.com/engineering-blog/2026/10/20/fmu-integration-python#mapping-fmu-inputs-and-outputs-to-signals" class="hash-link" aria-label="Direct link to Mapping FMU inputs and outputs to signals" title="Direct link to Mapping FMU inputs and outputs to signals">​</a></h2>
<p>The <code>FMUBehavioralModel</code> class connects an <code>FMUSimulation</code> to the topology. Inputs are
described with an <code>InputMapping</code>, a nested dictionary from namespace, to frame, to signal,
to FMU input name. Namespaces are named <code>&lt;ECU&gt;-&lt;Channel&gt;</code>, as described in
<a href="https://developer.remotivelabs.com/docs/remotive-topology/usage/instance/ecus#namespaces">Namespaces</a>, and signal names
include their frame, as in <code>TurnStalk.TurnSignal</code>.</p>
<p>The BCM reads the turn stalk position from the <code>TurnStalk</code> frame on DriverCan and feeds it
to the FMU's <code>turn_stalk</code> input:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> remotivelabs</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">topology</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">fmu </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> InputMapping</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">input_mapping</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> InputMapping </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"BCM-DriverCan"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"TurnStalk"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">"TurnStalk.TurnSignal"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"turn_stalk"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Whenever a <code>TurnStalk</code> frame arrives, the model writes the value of <code>TurnStalk.TurnSignal</code>
(0 for off, 1 for left, 2 for right) to <code>turn_stalk</code>. Values outside the signal's min and
max in the signal database, 0 to 2 here, are ignored, so a bad frame doesn't push the model
into nonsense.</p>
<p>Outputs go the other way. <code>FMUSimulation</code> takes an <code>on_output</code> callback that runs after
every step with a dictionary of output values. A simple way to put them on the bus is to
let a restbus send the ECU's frames and update their signals from the callback. For the
BCM, the restbus sends its frames on BodyCan, and the callback updates the turn light
signals in the <code>TurnLightControl</code> frame:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> remotivelabs</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">topology</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">namespaces </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> filters</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> remotivelabs</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">topology</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">namespaces</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">can </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> CanNamespace</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> RestbusConfig</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">body_can </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> CanNamespace</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"BCM-BodyCan"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    broker_client</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    restbus_configs</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">RestbusConfig</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">filters</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">SenderFilter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ecu_name</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"BCM"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">on_output</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">outputs</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> body_can</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">restbus</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">update_signals</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"TurnLightControl.LeftTurnLightRequest"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">int</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">outputs</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"left_turn_light"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"TurnLightControl.RightTurnLightRequest"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">int</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">outputs</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"right_turn_light"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>The output values have the Python type that matches the FMU variable's type: <code>bool</code> for
<code>Boolean</code>, <code>int</code> for <code>Int32</code> and <code>Integer</code>, <code>float</code> for <code>Float64</code> and <code>Real</code>. Signals on the
bus are numbers, so convert where the types don't line up. The turn lights are <code>Boolean</code>
outputs that drive 0/1 signals, so they're sent as <code>int(...)</code>. An output that drives a
physical value, such as the steering wheel angle in the full example, is sent as
<code>float(...)</code>.</p>
<p>Notice that the Python code doesn't blink the lights. That's the FMU's job: while the stalk
is in the left position, <code>left_turn_light</code> switches on and off by itself, with a cycle time
set by the FMU's <code>cycle_time</code> parameter.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="running-it-as-part-of-a-topology">Running it as part of a topology<a href="https://developer.remotivelabs.com/engineering-blog/2026/10/20/fmu-integration-python#running-it-as-part-of-a-topology" class="hash-link" aria-label="Direct link to Running it as part of a topology" title="Direct link to Running it as part of a topology">​</a></h2>
<p>Putting it together, the model script looks much like any other behavioral model.
<code>run_forever()</code> starts a ticker at the FMU's step size, steps the simulation on every tick
and handles inputs and control requests at the same time:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> asyncio</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> pathlib </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> Path</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> remotivelabs</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">broker </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> BrokerClient</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> remotivelabs</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">topology</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">cli</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">behavioral_model </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> BehavioralModelArgs</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> remotivelabs</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">topology</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">fmu </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> FMUBehavioralModel</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> FMUSimulation</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> remotivelabs</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">topology</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">namespaces </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> filters</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> remotivelabs</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">topology</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">namespaces</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">can </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> CanNamespace</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> RestbusConfig</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">FMU_PATH </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Path</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">__file__</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">parent </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"BCM.fmu"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">args</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> BehavioralModelArgs</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">with</span><span class="token plain"> BrokerClient</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">url</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">args</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">url</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> auth</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">args</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">auth</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> broker_client</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        driver_can </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> CanNamespace</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"BCM-DriverCan"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> broker_client</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        body_can </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> CanNamespace</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">"BCM-BodyCan"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            broker_client</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            restbus_configs</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">RestbusConfig</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">filters</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">SenderFilter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ecu_name</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"BCM"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">on_output</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">outputs</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> body_can</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">restbus</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">update_signals</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"TurnLightControl.LeftTurnLightRequest"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">int</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">outputs</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"left_turn_light"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"TurnLightControl.RightTurnLightRequest"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">int</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">outputs</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"right_turn_light"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        fmu </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> FMUSimulation</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">FMU_PATH</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> on_output</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">on_output</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">with</span><span class="token plain"> FMUBehavioralModel</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">"BCM"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            fmu</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">fmu</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            input_mapping</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token string" style="color:#e3116c">"BCM-DriverCan"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                    </span><span class="token string" style="color:#e3116c">"TurnStalk"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"TurnStalk.TurnSignal"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"turn_stalk"</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            broker_client</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">broker_client</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            namespaces</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">driver_can</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> body_can</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> bm</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> bm</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run_forever</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> __name__ </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"__main__"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    asyncio</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">BehavioralModelArgs</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">parse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>If you use the RemotiveTopology
<a href="https://developer.remotivelabs.com/apis/python/remotivelabs/topology/0.22.0/remotivelabs/topology/control.html" target="_blank" rel="noopener noreferrer">control API</a>,
<code>FMUBehavioralModel</code> listens for <code>RebootRequest</code> messages and resets the FMU to its initial
state, along with its restbuses, when one arrives. That makes it possible to start every
test case from a known state:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> remotivelabs</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">topology</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">behavioral_model </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> RebootRequest</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> remotivelabs</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">topology</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">control </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> ControlClient</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">with</span><span class="token plain"> ControlClient</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">broker_client</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> cc</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> cc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">send</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">target_ecu</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"BCM"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> request</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">RebootRequest</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>In the instance file, the model is added to its ECU like any Python behavioral model:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">ecus</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">BCM</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">models</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">bcm</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">type</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> container</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">container</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">build</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token key atrule" style="color:#00a4db">dockerfile</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ../models/bcm/Dockerfile</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">command</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> python </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">m bcm</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Running the model in a container has another benefit: you can choose the container's
platform. An FMU contains compiled binaries, often only for some platforms, and
<code>fmu.print()</code> lists which ones. If the FMU doesn't support your host, for example an Apple
Silicon Mac or an ARM CI runner, set <code>platform</code> to one it does support:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">container</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">platform</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> linux/amd64</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">build</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token key atrule" style="color:#00a4db">dockerfile</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ../models/bcm/Dockerfile</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">command</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> python </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">m bcm</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Docker then emulates that platform, which is slower than running natively.</p>
<p>The image that runs the model needs the <code>fmu</code> extra installed, so add
<code>remotivelabs-topology[fmu]</code> to the model's dependencies. Then build and start the
topology as usual:</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">remotive topology build </span><span class="token parameter variable" style="color:#36acaa">-f</span><span class="token plain"> mytopology.instance.yaml build</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">docker</span><span class="token plain"> compose </span><span class="token parameter variable" style="color:#36acaa">-f</span><span class="token plain"> build/mytopology/docker-compose.yml up</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>If the signals don't show up, check the namespace names first:</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">remotive broker signals namespaces </span><span class="token parameter variable" style="color:#36acaa">--url</span><span class="token plain"> http://localhost:50051</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="other-things-you-can-do">Other things you can do<a href="https://developer.remotivelabs.com/engineering-blog/2026/10/20/fmu-integration-python#other-things-you-can-do" class="hash-link" aria-label="Direct link to Other things you can do" title="Direct link to Other things you can do">​</a></h2>
<ul>
<li><strong>Run the FMU without a topology.</strong> <code>FMUSimulation</code> doesn't need a broker: create it and
call <code>await fmu.step()</code> in a loop, with <code>set_input_value</code> for the inputs. It's a quick
way to check that an FMU behaves as you expect before you connect it to any buses.</li>
<li><strong>Change inputs before each step</strong> with <code>before_step</code>, an async callback that gets the
inputs and returns the ones to use for the step. Use it when an input doesn't come
straight from one signal: a unit conversion, a value computed from several signals, or a
scenario that changes an input over time.</li>
<li><strong>Wait for the next step</strong> with <code>await fmu.wait_for_step()</code>, which returns that step's
outputs. Use it when code in the same process needs to act on new outputs, instead of
sleeping and hoping a step has run.</li>
<li><strong>Inspect the last step</strong> with <code>fmu.inputs</code> and <code>fmu.outputs</code>, for logging or debugging.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="where-to-go-next">Where to go next<a href="https://developer.remotivelabs.com/engineering-blog/2026/10/20/fmu-integration-python#where-to-go-next" class="hash-link" aria-label="Direct link to Where to go next" title="Direct link to Where to go next">​</a></h2>
<ul>
<li><a href="https://developer.remotivelabs.com/docs/remotive-topology/usage/fmu">FMU models</a>: a reference for everything in this post.</li>
<li><a href="https://developer.remotivelabs.com/docs/remotive-topology/usage/instance">Instantiating a topology</a>: behavioral models, mocks and Docker settings.</li>
<li><a href="https://developer.remotivelabs.com/docs/remotive-topology/usage/running">Running a topology</a>: generating, interactive mode and running tests.</li>
<li><a href="https://developer.remotivelabs.com/docs/remotive-topology/usage/apis">API and client library</a>: the full Python API reference.</li>
<li><a href="https://developer.remotivelabs.com/apis/python/remotivelabs/topology/0.22.0/remotivelabs/topology/fmu.html" target="_blank" rel="noopener noreferrer">The <code>fmu</code> module</a>: the API reference for <code>FMUSimulation</code> and <code>FMUBehavioralModel</code>.</li>
<li><a href="https://developer.remotivelabs.com/docs/remotive-topology/usage/examples">Examples</a>: the examples repository, a good place to start from a working setup.</li>
</ul>]]></content>
        <author>
            <name>Albin Theander</name>
        </author>
    </entry>
</feed>