<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Alessandro Stefanini</title>
  
  
  <link href="http://example.com/atom.xml" rel="self"/>
  
  <link href="http://example.com/"/>
  <updated>2026-07-01T00:00:46.494Z</updated>
  <id>http://example.com/</id>
  
  <author>
    <name>Alessandro Stefanini</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Code sandbox for Semantic Kernel</title>
    <link href="http://example.com/2024/12/08/semantic-kernel-code-runner/"/>
    <id>http://example.com/2024/12/08/semantic-kernel-code-runner/</id>
    <published>2024-12-08T08:58:34.000Z</published>
    <updated>2026-07-01T00:00:46.494Z</updated>
    
    <content type="html"><![CDATA[<p>This article outlines the implementation of a <a href="https://aka.ms/semantic-kernel">Semantic Kernel</a> plugin, which leverages Wasmtime to execute Python code generated from an LLM. The plugin facilitates running Python scripts securely and efficiently, adhering to the sandboxing principles of Wasmtime.</p><h2 id="Wasmtime">Wasmtime</h2><p><a href="https://wasmtime.dev/">Wasmtime</a> is a high-performance WebAssembly runtime for applications written in C, C++, Rust, and other system programming languages. It provides a safe and efficient way to execute code in a sandboxed environment, making it ideal for running untrusted code like user-provided or LLM-generated scripts.</p><p>In the context of the plugin, Wasmtime is used to run Python scripts. The plugin defines the necessary Wasi configuration to provide a Python environment for the scripts to execute in.</p><h2 id="Requirements">Requirements</h2><p>The plugin will require the following packages for C#: <code>Microsoft.SemanticKernel</code> and <code>Wasmtime</code>.<br>To run a Python CLI in WebAssembly, a <a href="https://github.com/brettcannon/cpython-wasi-build">Wasi implementation is needed</a>. The directory structure could look like the following:</p><figure class="highlight plaintext"><div><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">Project</span><br><span class="line">├───Plugin.cs</span><br><span class="line">├───Project.csproj</span><br><span class="line">└───Resources</span><br><span class="line">    └───Python</span><br><span class="line">        ├───lib</span><br><span class="line">        │   └───python3.13</span><br><span class="line">        │       ├───asyncio</span><br><span class="line">        │       ├───collections</span><br><span class="line">        │       └───...</span><br><span class="line">        └───python3.13.wasm</span><br></pre></td></tr></table></div></figure><p>In this case, the folder <code>Resources</code> is copied to the output directory.</p><h2 id="Plugin-Implementation">Plugin Implementation</h2><p>The plugin can be organized in two separate functions: <code>RunScriptAsync</code> and <code>RunCodeAsync</code>. The former takes care of running a single script file in the Python interpreter running on Wasmtime and the latter is a Semantic Kernel function that receives the code from the LLM plan.</p><figure class="highlight csharp"><figcaption><span>Plugin.cs</span></figcaption><div><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">async</span> Task&lt;<span class="built_in">string</span>&gt; <span class="title">RunScriptAsync</span>(<span class="params"><span class="built_in">string</span> dir, <span class="built_in">string</span> file, <span class="built_in">string</span> stdout</span>)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">using</span> <span class="keyword">var</span> engine = <span class="keyword">new</span> Engine();</span><br><span class="line">    <span class="keyword">using</span> <span class="keyword">var</span> store = <span class="keyword">new</span> Store(engine);</span><br><span class="line">    <span class="keyword">using</span> <span class="keyword">var</span> linker = <span class="keyword">new</span> Linker(engine);</span><br><span class="line">    linker.DefineWasi();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">using</span> <span class="keyword">var</span> module = Module.FromFile(engine, <span class="string">&quot;Resources\\Python\\python3.13.wasm&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">var</span> wasiConfig = <span class="keyword">new</span> WasiConfiguration()</span><br><span class="line">        .WithArgs(<span class="string">&quot;-c&quot;</span>, <span class="string">&quot;/scripts/&quot;</span> + file)</span><br><span class="line">        .WithPreopenedDirectory(<span class="string">&quot;Resources/Python/lib&quot;</span>, <span class="string">&quot;/usr/local/lib&quot;</span>)</span><br><span class="line">        .WithPreopenedDirectory(dir, <span class="string">&quot;/scripts&quot;</span>)</span><br><span class="line">        .WithInheritedStandardError()</span><br><span class="line">        .WithStandardOutput(stdout);</span><br><span class="line">    store.SetWasiConfiguration(wasiConfig);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">var</span> instance = linker.Instantiate(store, module);</span><br><span class="line">    instance.GetFunction(<span class="string">&quot;_start&quot;</span>)!.Invoke();</span><br><span class="line">    <span class="keyword">return</span> stdout;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><ol><li><p><strong>RunScriptAsync</strong>: This method handles the execution of a Python script using Wasmtime. It takes the script’s directory, file name, and the desired standard output file as input. The method performs the following steps:</p><ul><li>Initializes a Wasmtime engine, store, and linker.</li><li>Defines the Wasi environment for the script to run in.</li><li>Loads the Python WebAssembly module (python3.13.wasm).</li><li>Configures the Wasi environment with the script’s directory, Python library paths, and standard output.</li><li>Instantiates the WebAssembly module and invokes the <code>_start</code> function to execute the script.</li><li>Returns the standard output of the script.</li></ul></li></ol><figure class="highlight csharp"><figcaption><span>Plugin.cs</span></figcaption><div><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">[<span class="meta">KernelFunction(<span class="string">&quot;run_code&quot;</span>)</span>]</span><br><span class="line">[<span class="meta">Description(<span class="string">&quot;Runs a script in Python language and returns the standard output&quot;</span>)</span>]</span><br><span class="line">[<span class="meta">return: Description(<span class="string">&quot;The standard output of the script execution&quot;</span>)</span>]</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">async</span> Task&lt;<span class="built_in">string</span>&gt; <span class="title">RunCodeAsync</span>(<span class="params"></span></span></span><br><span class="line"><span class="params"><span class="function">    [Description(<span class="string">&quot;The code in Python language to be executed&quot;</span></span>)]</span></span><br><span class="line"><span class="function">    <span class="built_in">string</span> code,</span></span><br><span class="line"><span class="function">    CancellationToken cancellationToken)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">var</span> temp = Path.GetTempFileName();</span><br><span class="line">    <span class="keyword">var</span> lines = code.Replace(<span class="string">&quot;\&quot;&quot;</span>, <span class="string">&quot;&#x27;&quot;</span>).Split(<span class="string">&quot;\\n&quot;</span>);</span><br><span class="line">    <span class="keyword">await</span> File.WriteAllLinesAsync(temp, lines, cancellationToken);</span><br><span class="line">    <span class="keyword">var</span> tempDir = Path.GetDirectoryName(temp) ?? <span class="built_in">string</span>.Empty;</span><br><span class="line">    <span class="keyword">var</span> tempFile = Path.GetFileName(temp);</span><br><span class="line">    <span class="keyword">var</span> outFile = Path.GetTempFileName();</span><br><span class="line">    <span class="keyword">var</span> fileOut = <span class="keyword">await</span> RunScript(tempDir, tempFile, outFile);</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">await</span> File.ReadAllTextAsync(fileOut, cancellationToken);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><ol start="2"><li><p><strong>RunCodeAsync</strong>: This method is the entry point for the Semantic Kernel plugin. It takes a string of Python code as input, writes it to a temporary file, and then calls <code>RunScriptAsync</code> to execute the script. The method performs the following steps:</p><ul><li>Replaces any double quotes in the input Python code with single quotes for safe file writing.</li><li>Splits the code into lines and writes it to a temporary file.</li><li>Retrieves the temporary file’s directory and name.</li><li>Calls <code>RunScriptAsync</code> to execute the script, passing the temporary directory, file name, and another temporary file for standard output.</li><li>Reads the standard output from the temporary file and returns it.</li></ul></li></ol><h2 id="Result">Result</h2><p>Example output from a console application:</p><figure class="highlight plaintext"><div><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">User &gt;</span><br><span class="line">What is the 10th number of the Fibonacci sequence? You can write and execute a Python script for the answer</span><br><span class="line">Microsoft.SemanticKernel.KernelFunction: Information: Function Code-run_code invoking.</span><br><span class="line">info: Microsoft.SemanticKernel.KernelFunction[0]</span><br><span class="line">      Function Code-run_code invoking.</span><br><span class="line">trce: Microsoft.SemanticKernel.KernelFunction[0]</span><br><span class="line">      Function Code-run_code arguments: &#123;&quot;code&quot;:&quot;def fib(n):\n    a, b = 0, 1\n    for _ in range(n):\n        a, b = b, a \u002B b\n    return a\n\nprint(fib(10))&quot;&#125;</span><br><span class="line">Microsoft.SemanticKernel.KernelFunction: Trace: Function Code-run_code arguments: &#123;&quot;code&quot;:&quot;def fib(n):\n    a, b = 0, 1\n    for _ in range(n):\n        a, b = b, a \u002B b\n    return a\n\nprint(fib(10))&quot;&#125;</span><br><span class="line">Microsoft.SemanticKernel.KernelFunction: Information: Function Code-run_code succeeded.</span><br><span class="line">info: Microsoft.SemanticKernel.KernelFunction[0]</span><br><span class="line">      Function Code-run_code succeeded.</span><br><span class="line">Microsoft.SemanticKernel.KernelFunction: Trace: Function Code-run_code result: 55</span><br><span class="line">trce: Microsoft.SemanticKernel.KernelFunction[0]</span><br><span class="line">      Function Code-run_code result: 55</span><br><span class="line">info: Microsoft.SemanticKernel.KernelFunction[0]</span><br><span class="line">      Function Code-run_code completed. Duration: 6.6005792s</span><br><span class="line">Microsoft.SemanticKernel.KernelFunction: Information: Function Code-run_code completed. Duration: 6.6005792s</span><br><span class="line">Assistant &gt; The 10th number in the Fibonacci sequence is 55.</span><br></pre></td></tr></table></div></figure><h2 id="Conclusion">Conclusion</h2><p>The plugin demonstrates how to use Wasmtime to execute Python code within a sandboxed environment as a Semantic Kernel plugin in C#. By leveraging Wasmtime’s WebAssembly support and Wasi configuration, the plugin enables secure and efficient execution of user-provided Python scripts, adhering to the principles of sandboxing and code isolation.</p><h2 id="Next-steps">Next steps</h2><ul><li>Avoid using files to communicate with the Python interpreter</li><li>Have proper socket support in the Python interpreter on WebAssembly</li><li>Create an agent that can use the plugin to iterate on code to fit the user request</li><li>Consider using interpreters other than Python</li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;This article outlines the implementation of a &lt;a href=&quot;https://aka.ms/semantic-kernel&quot;&gt;Semantic Kernel&lt;/a&gt; plugin, which leverages Wasmti</summary>
      
    
    
    
    
  </entry>
  
  <entry>
    <title>Serverless email stack</title>
    <link href="http://example.com/2024/10/13/serverless-email-stack/"/>
    <id>http://example.com/2024/10/13/serverless-email-stack/</id>
    <published>2024-10-13T08:00:00.000Z</published>
    <updated>2026-07-01T00:00:46.495Z</updated>
    
    <content type="html"><![CDATA[<p>In the realm of cloud computing, serverless architectures are gaining prominence for their cost-effectiveness, scalability, and straightforward maintenance. These characteristics make such architectures particularly suitable for developing and sustaining personal projects. Presented here is an open-source project that leverages serverless platforms to establish a comprehensive email system. Utilizing Cloudflare Workers in combination with KV storage and Resend as the email sending service, this project offers an innovative approach to handling emails in the cloud.</p><h2 id="Overview">Overview</h2><p>The primary objective of this project is to create an efficient, low-cost, and easily manageable solution for sending and receiving emails. The project aims to leverage the capabilities of serverless platforms to bypass the intricate infrastructures traditionally associated with email servers, thus providing benefits to both developers and end-users.</p><h2 id="Architecture">Architecture</h2><p>The following sections detail the essential components that enable the functionality of this serverless email stack.</p><h3 id="Cloudflare-Workers">Cloudflare Workers</h3><p>Cloudflare Workers provide a serverless environment capable of running JavaScript code close to the end-user, allowing email-related functions to execute swiftly without the need for traditional server hosting. A major advantage of Cloudflare Workers is their seamless integration with KV Storage, a key-value database well-suited for storing small amounts of metadata related to emails.</p><ul><li><strong>Receiving Emails:</strong><ul><li>Incoming emails are processed through Cloudflare Workers, using Email Routes.</li><li>Metadata associated with these emails is stored in Cloudflare KV, enabling quick categorization and retrieval.</li></ul></li><li><strong>Authentication:</strong><ul><li>JWT based autentication with Azure Active Directory, integrated as middleware in <a href="https://hono.dev/">Hono</a>.</li></ul></li></ul><h3 id="Resend">Resend</h3><p>Resend is integrated to handle outbound emails, acting as a robust SMTP service that ensures reliable email delivery. This service manages the complexities of SMTP, deliverability, and compliance, making it an ideal choice for this serverless email stack.</p><ul><li><strong>Sending Emails:</strong><ul><li>Cloudflare Workers trigger the Resend service to send emails.</li><li>Resend takes care of delivering emails to recipients’ inboxes.</li></ul></li></ul><h2 id="JMAP-Standard">JMAP Standard</h2><p>A notable feature of this project is its compatibility with the <a href="https://jmap.io/index.html">JMAP (JSON Meta Application Protocol)</a> standard. JMAP is a modern protocol that offers a more efficient and simpler approach to managing emails in comparison to traditional protocols like IMAP and SMTP.</p><ul><li><strong>Advantages of JMAP:</strong><ul><li><strong>Simplified API:</strong> Interaction with emails is made straightforward through JSON-based API calls.</li><li><strong>Efficiency:</strong> Designed to minimize data transfer, making it ideal for serverless environments where performance and cost efficiency are prioritized.</li><li><strong>Compatibility:</strong> Widespread support for JMAP across various email clients ensures broader accessibility.</li></ul></li></ul><h2 id="Webmail-client">Webmail client</h2><p>To enhance the project’s usability, a simple email client was developed, specifically designed to integrate seamlessly with this email stack. This client demonstrates the ease with which developers and users can engage with the system, offering a familiar and intuitive interface.</p><ul><li><strong>Client Features:</strong><ul><li><strong>User-Friendly Interface:</strong> Facilitates the simple sending and receiving of emails.</li><li><strong>Security Measures:</strong> Incorporates authentication mechanisms to protect user data.</li></ul></li></ul><h2 id="Acknowledgments">Acknowledgments</h2><p>The project draws inspiration from another open-source project known as <a href="https://github.com/elasticinbox/elasticinbox-cloudflare">elasticinbox-cloudflare</a>, which explores similar concepts in leveraging Cloudflare for email functionalities.<br>It also leverages <a href="https://github.com/htunnicliff/jmap-jam">Jam</a> as a strongly typed contract for both backend and frontend.</p><h2 id="Conclusion">Conclusion</h2><p>This serverless email stack exemplifies the transformative potential of modern cloud technologies in rethinking traditional services.</p><p>All the code is available in the <a href="https://github.com/alessandroste/mercury">repository</a>.</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;In the realm of cloud computing, serverless architectures are gaining prominence for their cost-effectiveness, scalability, and straightf</summary>
      
    
    
    
    
  </entry>
  
  <entry>
    <title>Native Android with VS Code and .NET6</title>
    <link href="http://example.com/2022/03/03/android-net6-vscode/"/>
    <id>http://example.com/2022/03/03/android-net6-vscode/</id>
    <published>2022-03-03T22:32:47.000Z</published>
    <updated>2026-07-01T00:00:46.460Z</updated>
    
    <content type="html"><![CDATA[<p>The .NET 6 team has done another step in the direction of uniforming the processes and tools of writing code for different platforms. Now it is possible to install the stack to compile applications for Android and work with it only via dotnet cli.</p><video height=350px autoplay loop controls><source src='recording.webm' type=video/webm> Your browser does not support the webm tag.</video><h1>Why</h1><p>Developing cross-platform mobile apps can be done with a large variety of frameworks and tools, but, for native applications (or close-to-native performance), the selection is limited. Xamarin is one of the frameworks that is considered native, and it has evolved a lot over time to stay updated with the latest improvements and features of the mobile OSes.</p><p>Up until recently, Xamarin could only be developed with ease in the Visual Studio IDE. The downside is that someone might consider it limiting when it comes to license. On the other hand, VS Code is more widely used by a large group of developers.</p><p>The latest version of .NET 6 brought Xamarin inside the dotnet tooling in the form of workload and it’s now possible to get a fully functional development environment, that requires only the dotnet SDK.</p><h1>What changes</h1><p>Now it is possible to target Android in a C# project file using the standard SDK project. Here is an example file:</p><figure class="highlight plaintext"><div><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&lt;Project Sdk=&quot;Microsoft.NET.Sdk&quot;&gt;</span><br><span class="line">  &lt;PropertyGroup&gt;</span><br><span class="line">    &lt;TargetFramework&gt;net6.0-android&lt;/TargetFramework&gt;</span><br><span class="line">    &lt;OutputType&gt;Exe&lt;/OutputType&gt;</span><br><span class="line">  &lt;/PropertyGroup&gt;</span><br><span class="line">  &lt;ItemGroup&gt;</span><br><span class="line">    &lt;PackageReference Include=&quot;Xamarin.AndroidX.Arch.Core.Runtime&quot; Version=&quot;2.1.0.12&quot; /&gt;</span><br><span class="line">  &lt;/ItemGroup&gt;</span><br><span class="line">&lt;/Project&gt;</span><br></pre></td></tr></table></div></figure><h1>VS Code setup</h1><ol><li>Have VS Code ready</li><li>Install <a href="https://dotnet.microsoft.com/en-us/download/dotnet/6.0">dotnet SDK</a></li><li>Add dotnet workload for Android <figure class="highlight plaintext"><div><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dotnet workload install android-aot</span><br></pre></td></tr></table></div></figure></li><li>Open the <a href="https://github.com/alessandroste/net6-android-starter">sample project</a></li><li>Install the extensions</li><li>Start the emulator from the task</li></ol><h1>Running</h1><ol><li>Start the build task</li><li>Select the target <code>Run</code></li><li>Wait until the emulator is loaded with the app and it’s showing a white screen</li><li>Attach the debugger to start the application</li></ol><h1>And more</h1><p>Another area with huge improvements is binding libraries. Just change <code>&lt;OutputType&gt;Library&lt;/OutputType&gt;</code> and add the <code>jar</code> or <code>aar</code>. Add <code>Metadata.xml</code> if needed. That’s it.<br>For more information, have a look <a href="https://github.com/xamarin/xamarin-android/blob/main/Documentation/guides/OneDotNetBindingProjects.md">here</a>.</p><h1>References</h1><ul><li><a href="https://github.com/xamarin/xamarin-android/blob/main/Documentation/guides/OneDotNet.md">Xamarin in .NET 6 Presentation</a></li></ul>]]></content>
    
    
    <summary type="html">A short introduction on how to start writing native Android apps with .NET 6 and VS Code</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>Animated knots in Three JS</title>
    <link href="http://example.com/2021/12/24/knots-three-js/"/>
    <id>http://example.com/2021/12/24/knots-three-js/</id>
    <published>2021-12-24T17:32:17.000Z</published>
    <updated>2026-07-01T00:00:46.474Z</updated>
    
    <content type="html"><![CDATA[<p>I wanted to have some fun with <a href="https://threejs.org/">Three JS</a> so I started playing with the idea of having a way to animate ropes to demostrate how to tie knots.</p><h2 id="Basics-of-Three">Basics of Three</h2><p>Three JS is an interface library to WebGL and allows to render scenes defined in JS. Three allows to control the data structures down to the level of the buffer that is sent to WebGL. Geometries abstract the definition of the shapes in the space by the means of coordinates of the vertices. Other than the vertices, it is necessary to define the edges and the faces that together make the mesh. A vertex is a point in space and is composed by three spatial coordinates, and three points define a face.</p><p>The flexibility of Three allows to use many different common shapes or build geometries from scratch, by defining vertices, faces and so on.</p><h2 id="Simple-rope-with-built-in-classes">Simple rope with built-in classes</h2><p>To draw a rope, it is possible to use the <a href="https://threejs.org/docs/index.html?q=tube#api/en/geometries/TubeGeometry">TubeGeometry</a>. This kind of geometry builds a tube along a curve in the 3D space. It is easy and straightforward to create a shape from a curve, but the main limitation is that there is no easy way to animate the curve without instantiating a new geometry.</p><div id="scene1" style="width: 100%; height: 250px"></div><script type="module" src="scene1.js"></script><p>Allocation of new objects is expensive and the execution will stutter.</p><h2 id="Performant-geometry-for-updates">Performant geometry for updates</h2><p>To address the performance problem with the out-of-the box geometry, it is possible to define a new type of geometry that operates in the same way as the <code>TubeGeometry</code>, with a difference: this new geometry should allow to be updated if the path changes, without having to be reinstantiated.</p><p>Introducing the <code>AnimatedTubeGeometry</code>: this geometry exposes a method <code>updatePath</code> that recalculates the vertices’ positions. In the naive implementation, the geometry computation logic is repeated every time the update method is called. The performance is still far from satisfactory, mostly because the vertex math makes use of dynamic arrays, that are very expensive in terms of resources. The issue can be tackled by using buffers, and the class <code>BufferedAnimatedTubeGeometry</code> does just that. The vertices’ update logic does not use dynamic memory in order to be performant, and we can instantiate the arrays (buffers) that contain the geometry information once in the constructor and update the elements afterwards. In fact, the number of the vertices and faces is defined by the inital call to the constructor of the geometry, and, afterwards, only the position will change. Moreover, between all the attributes that define the geometry, only vertices and normals will be affected by a curve update, whereas UVs and indices (face definitions) stay the same.</p><p>The following scene shows the comparison in terms of performance between the “naive” <code>AnimatedTubeGeometry</code> and <code>BufferedAnimatedTubeGeometry</code>. Click the button to switch geometry and see the difference in the rendering time.</p><div id="scene2" style="width: 100%; height: 250px; position: relative">  <span id="stats2" style="position: absolute; text-align: right; right: 0px; bottom: 0px;"></span>  <input id="button2" class="button" style="position: absolute;" type="submit" value="switch"/></div><script type="module" src="scene2.js"></script><p>One last details is to make sure to update the path in an optimized way. It does not make sense to redraw the path if the changes are not rendered. So the guidance would be to call <code>updatePath</code> only after the curve changes, but not more than once between two different visible frames.</p><h2 id="Animating">Animating</h2><p>Having prepared the framework for animated tubes in Three, we can then leverage <a href="https://www.theatrejs.com/">Theatre JS</a> to set up an animation studio in the browser. Theatre allows to build transitions of properties, and also set up a sequence with interpolations, easings and so on. The rope is build on top of the class <code>CatmullRomCurve3</code>, that interpolates a list of positions in the space to build a curve. Each one of this position is shown as a ball in the studio, and we can connect the spheres’ positions to properties of a Theatre JS object.</p><figure class="highlight js"><figcaption><span>theatre.js props definition</span></figcaption><div><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> props = sheet.<span class="title function_">object</span>(name, &#123;</span><br><span class="line">  <span class="attr">posX</span>: i,</span><br><span class="line">  <span class="attr">posY</span>: <span class="number">1</span>,</span><br><span class="line">  <span class="attr">posZ</span>: <span class="number">0</span>,</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></div></figure><p>We can use <code>OrbitControls</code> and <code>TransformControls</code> to interact with the objects in the scene. The following is the relevant part of the code that stores the positions in Theatre JS when they the objects are moved manually.</p><figure class="highlight js"><figcaption><span>setting up interaction</span></figcaption><div><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> orbitControls = <span class="keyword">new</span> <span class="title class_">OrbitControls</span>(camera, renderer.<span class="property">domElement</span>);</span><br><span class="line"><span class="keyword">const</span> transformControls = <span class="keyword">new</span> <span class="title class_">TransformControls</span>(camera, renderer.<span class="property">domElement</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// We store an object name for each sphere so we can easily look up in a hash table</span></span><br><span class="line">transformControls.<span class="title function_">addEventListener</span>(<span class="string">&#x27;objectChange&#x27;</span>, <span class="function"><span class="params">listener</span> =&gt;</span> &#123;</span><br><span class="line">  <span class="keyword">const</span> scrub = studio.<span class="title function_">debouncedScrub</span>(<span class="number">1000</span>);</span><br><span class="line">  <span class="keyword">const</span> objName = listener.<span class="property">target</span>.<span class="property">userData</span>.<span class="property">selected</span>;</span><br><span class="line">  <span class="keyword">if</span> (nodes[objName] === <span class="literal">undefined</span>)</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">  <span class="keyword">const</span> &#123; props, mesh &#125; = nodes[objName];</span><br><span class="line">  scrub.<span class="title function_">capture</span>(<span class="function">(<span class="params">&#123; set &#125;</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="title function_">set</span>(props.<span class="property">props</span>, &#123;</span><br><span class="line">      <span class="attr">posX</span>: mesh.<span class="property">position</span>.<span class="property">x</span>,</span><br><span class="line">      <span class="attr">posY</span>: mesh.<span class="property">position</span>.<span class="property">y</span>,</span><br><span class="line">      <span class="attr">posZ</span>: mesh.<span class="property">position</span>.<span class="property">z</span></span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// This is used in the rendering method to call the updatePath on the geometry</span></span><br><span class="line">  sceneState.<span class="property">geometryNeedsUpdate</span> = <span class="literal">true</span>;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">transformControls.<span class="title function_">addEventListener</span>(<span class="string">&#x27;dragging-changed&#x27;</span>, <span class="function"><span class="params">event</span> =&gt;</span> &#123;</span><br><span class="line">  orbitControls.<span class="property">enabled</span> = !event.<span class="property">value</span>;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="title class_">Object</span>.<span class="title function_">entries</span>(nodes).<span class="title function_">map</span>(<span class="function">(<span class="params">[, value]</span>) =&gt;</span> &#123;</span><br><span class="line">  value.<span class="property">props</span>.<span class="title function_">onValuesChange</span>(<span class="function"><span class="params">newValues</span> =&gt;</span> &#123;</span><br><span class="line">    value.<span class="property">mesh</span>.<span class="property">position</span>.<span class="title function_">set</span>(newValues.<span class="property">posX</span>, newValues.<span class="property">posY</span>, newValues.<span class="property">posZ</span>);</span><br><span class="line">    sceneState.<span class="property">geometryNeedsUpdate</span> = <span class="literal">true</span>;</span><br><span class="line">  &#125;);</span><br><span class="line">  scene.<span class="title function_">add</span>(value.<span class="property">mesh</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></div></figure><h2 id="Final-result">Final result</h2><p>Here is the final result: use the button to toggle the animation.</p><div id="scene3" style="width: 100%; height: 250px">  <input id="button3" class="button" style="position: absolute" type="submit" value="play"/></div><script type="module" src="scene3.js"></script>]]></content>
    
    
    <summary type="html">How to create an animated knot in Three JS: combining an optimized geometry with an animation library to achieve a smooth, hand-crafted presentation.</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>Serverless Telegram bot on Azure</title>
    <link href="http://example.com/2021/04/25/azure-telegram-bot/"/>
    <id>http://example.com/2021/04/25/azure-telegram-bot/</id>
    <published>2021-04-25T10:16:00.000Z</published>
    <updated>2026-07-01T00:00:46.469Z</updated>
    
    <content type="html"><![CDATA[<p>Started as a part of a different personal project, this code base has been expanded to offer a starting point to build a serverless Telegram bot that runs on Azure Functions. One of the reasons for this choice is the generous free <a href="https://azure.microsoft.com/en-us/pricing/details/functions/">consumption plan</a> offered at the time of writing, that allows to run a simple bot with minor costs, mostly due to the storage, key vault and optionally, the Log Analytics.</p><p>The state of the conversations can be saved on the blob storage. Another Azure Function could be triggered and send messages to the conversations.</p><h1>Quickstart</h1><p>All the guidance to use it is in the <a href="https://github.com/alessandroste/az-serverless-bot#readme">README</a>.</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;Started as a part of a different personal project, this code base has been expanded to offer a starting point to build a serverless Teleg</summary>
      
    
    
    
    
  </entry>
  
  <entry>
    <title>Unicode 9 emoticons on Xperia</title>
    <link href="http://example.com/2016/09/20/unicode-9-xperia/"/>
    <id>http://example.com/2016/09/20/unicode-9-xperia/</id>
    <published>2016-09-20T15:24:09.000Z</published>
    <updated>2026-07-01T00:00:46.496Z</updated>
    
    <content type="html"><![CDATA[<p>Unicode is the standard regulation of graphic characters used in all the digital text. Each character or sign is encoded with a number in an unique way. Unicode Consortium is the organization that maintains all the rules: many symbols are added regularly, so there exist many versions of Unicode standards. Also emoticons are part of this standard and with each revision, the Consortium inserts new symbols in the encoding rules.<br>The latest version has been released on June 21, 2016, and many emoticons <a href="http://emojipedia.org/unicode-9.0/">have been added</a>. The update then has to be received by the producers of software: new graphics are created to match the symbols described by the Consortium. Rarely, the process is inverted and the Consortium adds symbols which are already introduced by big software houses. In this project, the freely provided emoticons by <a href="https://github.com/twitter/twemoji">Twitter</a> are used to build a font for Android, then the Xperia keyboard is modified to allow the insertion of the new emoticons in the text areas.<div class="tip"><br>This process requires root privileges for at least one reason: the font used for emoticons is located in a system folder, thus is impossible to replace without root permissions. Another possible reason is that the custom Xperia Keyboard cannot be installed on a stock Xperia system (unrooted) because the package has to be replaced with one having a different signature. Moreover, it is necessary to specify that the keyboard will not fully support the Unicode standard as the Fitzpatrick modifiers are not yet implemented (more work has to be done).</div><img src="kb_nature.jpg" alt="kb_nature"></p><h1>The font</h1><p>To embed the new emoticons in the system, a specific font file, <strong>NotoColorEmoji.ttf</strong>, has to be replaced (under /system/fonts). Many choices are available: for example it is possible to use a font derived from Apple’s emoji font or the Android N font (actually, it is the latest version of NotoColorEmoji.ttf), which includes all the Unicode 9 emoticons. For this project a new font has been built from the <a href="https://github.com/googlei18n/noto-emoji">sources of Noto emoji font</a>.</p><h2 id="Building">Building</h2><p>The main passages of the process are the following:</p><ol><li><p>Set up the folder where the project has to be compiled, download the sources of noto-emoji from the previous link and install all the dependencies</p></li><li><p>Download the Twemoji project from the link provided above</p></li><li><p>Export the emoticons in PNG format from the svg folder. For example, the following code will export a SVG file to a PNG file with a width of 128px, which is enough for to make the font (play with bash to automate the process):</p></li></ol><figure class="highlight plaintext"><div><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">rsvg-convert -w 128 -a inputfile.svg -o outputfile.png</span><br></pre></td></tr></table></div></figure><ol start="4"><li>Copy all the PNG files into a directory in the noto-emoji project folder and rename accordingly to noto-emoji PNGs in the folder png/128</li><li>Change the makefile to exclude the generation of the flags (<a href="Makefile">example</a>).</li></ol><h2 id="Installing">Installing</h2><p>The build process generates a file named <strong>NotoColorEmoji.ttf</strong> (<a href="NotoColorEmoji.ttf">here it is my compiled font</a>), which has to be copied in the Android system in the folder /system/fonts. Root privileges are required to do so and system partition should be remounted as r/w-able. It is necessary that the permissions of the files are rw-r–r-- (644). This allows Android to use Twemoji instead of original Google emoticons system-wide.</p><h1>The keyboard</h1><p>Xperia system includes a good keyboard, but the emoticons coverage depends on the version of the system. By analyzing the apk, it can be found that there are many XML files (under res/xml) responsible for the emoticon list. The modification of these files leads to show the new emoticons in the keyboard.</p><h2 id="Decompiling">Decompiling</h2><p>The APK file can be found on many mirrors (<a href="http://www.apkmirror.com/apk/sony-mobile-communications/xperia-keyboard/">for example here</a>). The process of decompilation requires the use of <a href="https://ibotpeaches.github.io/Apktool/">apktool</a>, which has to be set up: it is required to install the Xperia framework files <em>framework-res.apk</em> (from /system/framework) and <em>SemcGenericUxpRes.apk</em> (from /system/framework/SemcGenericUxpRes/). These files can be exported from an existing Xperia device with Marshmallow version (API 23), because the keyboard application had been compiled with such libraries. Here it is an example with ADB:</p><figure class="highlight plaintext"><div><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">adb pull /system/framework/framework-res.apk</span><br><span class="line">adb pull /system/framework/SemcGenericUxpRes/SemcGenericUxpRes.apk</span><br></pre></td></tr></table></div></figure><p>Libraries can be installed in apktool with the commands <code>apktool if framework-res.apk -t sony_m</code> and <code>apktool if SemcGenericUxpRes.apk -t sony_m</code>. Then, the decompilation takes place:</p><figure class="highlight plaintext"><div><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">apktool d xperia-keyboard.apk -t sony_m -o xperia-keyboard</span><br></pre></td></tr></table></div></figure><h2 id="Tweaking">Tweaking</h2><p>The decompilation produces a folder (xperia-keyboard) containing all the resources of the original application. XML files of emoticons panels are res/xml/page_emoji*. Each emoticon is defined by a <strong>Cell</strong> tag such as the following one:</p><figure class="highlight xml"><div><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">Cell</span> <span class="attr">semc:label</span>=<span class="string">&quot;\\U+1f600;&quot;</span> /&gt;</span></span><br></pre></td></tr></table></div></figure><p>It is only necessary to add the rows of the new emoticons. The list of codepoints (e.g. U+1f600) can be obtained through <a href="http://emojipedia.org/unicode-9.0/">Emojipedia</a>. In this case a web crawler can be written to build a TXT file with all the new codes. This is one written in Python (requires BeautifulSoup):</p><figure class="highlight python"><figcaption><span>uni9_crawler.py</span></figcaption><div><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> BeautifulSoup</span><br><span class="line"><span class="keyword">import</span> urllib2</span><br><span class="line"><span class="keyword">import</span> Queue</span><br><span class="line"><span class="keyword">import</span> threading</span><br><span class="line">categories = [<span class="string">&#x27;unicode-9.0&#x27;</span>]</span><br><span class="line">before = <span class="string">&#x27;&lt;Cell semc:label=&quot;&#x27;</span></span><br><span class="line">after = <span class="string">&#x27;&quot; /&gt;&#x27;</span></span><br><span class="line">baseurl = <span class="string">&#x27;http://emojipedia.org&#x27;</span></span><br><span class="line">hdr = &#123;<span class="string">&#x27;User-Agent&#x27;</span>:<span class="string">&#x27;Mozilla/5.0&#x27;</span>&#125;</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">worker</span>():</span><br><span class="line">  <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">    item = q.get()</span><br><span class="line">    req = urllib2.Request(baseurl+item,headers=hdr)</span><br><span class="line">    l.append(&#123;<span class="string">&#x27;name&#x27;</span>:item, <span class="string">&#x27;source&#x27;</span>:urllib2.urlopen(req).read()&#125;)</span><br><span class="line">    q.task_done()</span><br><span class="line">    <span class="built_in">print</span> <span class="string">&#x27;done &#x27;</span>+item[<span class="number">1</span>:-<span class="number">1</span>]</span><br><span class="line"><span class="keyword">for</span> k <span class="keyword">in</span> categories:</span><br><span class="line">  <span class="built_in">print</span> k</span><br><span class="line">  f = <span class="built_in">open</span>(k+<span class="string">&#x27;.txt&#x27;</span>,<span class="string">&#x27;w&#x27;</span>)</span><br><span class="line">  url = baseurl+<span class="string">&#x27;/&#x27;</span>+k</span><br><span class="line">  req = urllib2.Request(url,headers=hdr)</span><br><span class="line">  get = urllib2.urlopen(req).read()</span><br><span class="line">  dom = BeautifulSoup.BeautifulSoup(get)</span><br><span class="line">  data = dom.find(<span class="string">&#x27;div&#x27;</span>,&#123;<span class="string">&#x27;class&#x27;</span>:<span class="string">&#x27;content&#x27;</span>&#125;).findAll(<span class="string">&#x27;ul&#x27;</span>)</span><br><span class="line">  emojis = data[<span class="number">1</span>].findAll(<span class="string">&#x27;a&#x27;</span>);</span><br><span class="line">  q = Queue.Queue()</span><br><span class="line">  l = []</span><br><span class="line">  <span class="keyword">for</span> e <span class="keyword">in</span> emojis:</span><br><span class="line">    q.put(e[<span class="string">&#x27;href&#x27;</span>])</span><br><span class="line">  <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">6</span>):</span><br><span class="line">    t = threading.Thread(target=worker)</span><br><span class="line">    t.daemon = <span class="literal">True</span></span><br><span class="line">    t. start()</span><br><span class="line">  q.join()</span><br><span class="line">  <span class="built_in">print</span> <span class="string">&#x27;writing file&#x27;</span></span><br><span class="line">  <span class="keyword">for</span> p <span class="keyword">in</span> l:</span><br><span class="line">    dom = BeautifulSoup.BeautifulSoup(p[<span class="string">&#x27;source&#x27;</span>])</span><br><span class="line">    h2 = dom.find(text=<span class="string">&quot;Codepoints&quot;</span>)</span><br><span class="line">    ul = h2.parent.findNextSibling(<span class="string">&#x27;ul&#x27;</span>)</span><br><span class="line">    codes = ul.findAll(<span class="string">&#x27;li&#x27;</span>)</span><br><span class="line">    f.write(<span class="string">&#x27;&lt;!--&#x27;</span>+p[<span class="string">&#x27;name&#x27;</span>][<span class="number">1</span>:-<span class="number">1</span>]+<span class="string">&#x27;--&gt;\n&#x27;</span>)</span><br><span class="line">    complete = before</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> codes:</span><br><span class="line">      complete += <span class="string">&#x27;\\\\&#x27;</span></span><br><span class="line">      c = i.find(<span class="string">&#x27;a&#x27;</span>).text.split(<span class="string">&#x27; &#x27;</span>)[<span class="number">1</span>]</span><br><span class="line">      complete += c</span><br><span class="line">      complete += <span class="string">&#x27;;&#x27;</span></span><br><span class="line">    complete += after</span><br><span class="line">    <span class="built_in">print</span> complete</span><br><span class="line">    f.write(complete+<span class="string">&#x27;\n&#x27;</span>)</span><br><span class="line">  f.close()</span><br></pre></td></tr></table></div></figure><p>With some work of copy-pasting these codes can be embedded in original XML files.</p><h2 id="Recompiling">Recompiling</h2><p>Recompilation takes place with apktool:</p><figure class="highlight plaintext"><div><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">apktool b xperia-keyboard -t sony_m -o xperia-keyboard-uni9.apk</span><br></pre></td></tr></table></div></figure><p>The package can not be installed yet because it lacks the signature, neverthless for personal and debugging purposes it is very easy to produce a certificate and sign the APK. Here follow the commands necessary to do so:</p><figure class="highlight plaintext"><div><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">keytool -genkey -v -keystore my-release-key.keystore -alias mykey -keyalg RSA -keysize 2048 -validity 10000</span><br><span class="line">jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore xperia-keyboard-uni9.apk mykey</span><br></pre></td></tr></table></div></figure><h2 id="Installing-2">Installing</h2><p>Once the APK is signed it can be installed through ADB (<code>adb install -r xperia-keyboard-uni9.apk</code>) or copied to the device and then installed through Android’s package manager GUI.<br>The process will work only if the original package is not installed, otherwise the different signature will prevent the replacement of the application.<br><img src="kb_faces.jpg" alt="kb_faces"></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;Unicode is the standard regulation of graphic characters used in all the digital text. Each character or sign is encoded with a number in</summary>
      
    
    
    
    
  </entry>
  
  <entry>
    <title>ISO 26262 compliant EBA electronic system</title>
    <link href="http://example.com/2016/08/29/eba-system/"/>
    <id>http://example.com/2016/08/29/eba-system/</id>
    <published>2016-08-29T17:11:19.000Z</published>
    <updated>2026-07-01T00:00:46.471Z</updated>
    
    <content type="html"><![CDATA[<p>This is a project developed for an university assignment. The task was to develop an Emergency Braking Assist system for a generic city car, also it had to be compliant with ISO 26262 standard.</p><h2 id="ISO-26262-documentation">ISO 26262 documentation</h2><p>Given the current vehicle speed V, and the distance D of the vehicle from the preceding vehicle, if <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><msup><mi>V</mi><mn>2</mn></msup><mn>100</mn></mfrac><mo>&gt;</mo><mo>=</mo><mi>D</mi></mrow><annotation encoding="application/x-tex">\frac{V^2}{100}&gt;=D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.3629em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0179em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">100</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.22222em;">V</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913em;"><span style="top:-2.931em;margin-right:0.0714em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&gt;=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span></span> then the EBA activates the brake request and keeps braking the vehicle until <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><msup><mi>V</mi><mn>2</mn></msup><mn>100</mn></mfrac><mo>&lt;</mo><mi>D</mi></mrow><annotation encoding="application/x-tex">\frac{V^2}{100}&lt;D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.3629em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0179em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">100</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.22222em;">V</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913em;"><span style="top:-2.931em;margin-right:0.0714em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span></span> The brake request is either 0 (indicating no brake is needed) or 1 (indicating that bake is needed). The EBA receives the vehicle speed V and the distance D every 100 msec, and decides whether a brake is needed or not.</p><h3 id="Elements-of-the-item">Elements of the item</h3><p>Microcontroller (CPU + embedded memory + CAN interface), radar.</p><h3 id="Interaction-of-the-items-with-other-items">Interaction of the items with other items</h3><p>The item interacts with the Body Computer through the CAN for receiving the vehicle speed and for providing the brake signal.</p><h3 id="Identification-of-provided-functionalities-to-other-items">Identification of provided functionalities to other items</h3><p>The item provides the brake signal to the Body Computer through the CAN.</p><h3 id="Identification-of-required-functionalities-from-other-items">Identification of required functionalities from other items</h3><p>The item requires the vehicle speed from the Body Computer through the CAN.</p><h3 id="Identification-of-hazards">Identification of hazards</h3><p>To identify correctly the hazards, we can firstly perform the FMEA (Failure Mode &amp; Effect Analysis)</p><ul><li><strong>FM1</strong>: radar breaks → distance is not correctly measured. Note that this failure can lead to different situations: distance measured is smaller than the real one or distance measured is higher than the real one. Anyway the main point is that the measure is not correct anymore due to the failure.</li><li><strong>FM2</strong>: microcontroller breaks → break signal is not reliable. Also for this failure we can have different situations, but the key point is that the microcontroller is not able to correctly perform the algorithm and as a consequence the brake signal is not correct.</li><li><strong>FM3</strong>: CAN interface breaks → information is not correctly exchanged with the CAN.</li></ul><p>All these failures lead to two main hazards that we have to take into account for the Hazard Analysis and Risk Assessment of the item:</p><ul><li><strong>H1</strong>: the item sends the brake signal when is not required (i.e.  V<sup>2</sup>/100≥D).</li><li><strong>H2</strong>: the item does not send the brake signal when is required (i.e.  V<sup>2</sup>/100&lt;D).</li></ul><h3 id="Identification-of-operational-situations">Identification of operational situations</h3><p>The key point in the identification of the operational situations is that we have to consider also the eventual presence of a following car. Hence we call:</p><ul><li>d1 the distance between the car under analysis and the following one</li><li>d2 the distance between the car under analysis and the preceding one<br>As a consequence, we can discriminate the operational situations by considering:</li><li>Distance that can be higher or smaller with respect to safety distance (safey distance = V<sup>2</sup>/100).</li><li>Speed that can be higher or smaller than a threshold value, we will consider 30 km/h as threshold (the speed will distinguish different degrees of severity).</li></ul><p>Therefore, the operational situations are the following:</p><ul><li><strong>OS1</strong>: V &lt; 30 km/h, d1 &lt; safety distance, d2 &gt; safety distance;</li><li><strong>OS2</strong>: V &gt; 30 km/h, d1 &lt; safety distance, d2 &gt; safety distance;</li><li><strong>OS3</strong>: V &lt; 30 km/h, d1 &gt; safety distance, d2 &lt; safety distance;</li><li><strong>OS4</strong>: V &gt; 30 km/h, d1 &gt; safety distance, d2 &lt; safety distance;</li><li><strong>OS5</strong>: V &lt; 30 km/h, d1 &lt; safety distance, d2 &lt; safety distance;</li><li><strong>OS6</strong>: V &gt; 30 km/h, d1 &lt; safety distance, d2 &lt; safety distance;</li><li><strong>OS7</strong>: vehicle moving and a pedestrian or a cycle crosses the road.<br>Note that it is useless to consider the operational situations in which:</li><li><em>OS8</em>: V &lt; 30 km/h, d1 &gt; safety distance, d2 &gt; safety distance;</li><li><em>OS9</em>: V &gt; 30 km/h, d1 &gt; safety distance, d2 &gt; safety distance;<br>In fact, in both of them, the distance is limit is respected and there is no risk.</li></ul><h3 id="ASIL-determination">ASIL determination</h3><table><thead><tr><th>Operational situation</th><th>H1</th><th>ASIL</th><th>H2</th><th>ASIL</th><th>Notes</th></tr></thead><tbody><tr><td>OS1</td><td>S=1,E=4,C=2</td><td>A</td><td></td><td></td><td>H2 cannot take place in OS1 since d2 &gt; safety distance</td></tr><tr><td>OS2</td><td>S=2,E=4,C=3</td><td>C</td><td></td><td></td><td>H2 cannot take place in OS2 since d2 &gt; safety distance</td></tr><tr><td>OS3</td><td>S=1,E=4,C=2</td><td>A</td><td>S=1,E=4,C=1</td><td>QM</td><td></td></tr><tr><td>OS4</td><td>S=2,E=4,C=3</td><td>C</td><td>S=2,E=4,C=2</td><td>B</td><td></td></tr><tr><td>OS5</td><td>S=2,E=4,C=2</td><td>B</td><td>S=2,E=4,C=1</td><td>A</td><td></td></tr><tr><td>OS6</td><td>S=3,E=4,C=3</td><td>D</td><td>S=3,E=4,C=2</td><td>C</td><td></td></tr><tr><td>OS7</td><td>S=3,E=3,C=3</td><td>C</td><td>S=3,E=3,C=2</td><td>B</td><td></td></tr></tbody></table><h3 id="General-notes">General notes</h3><ul><li>The exposure is always 4 for the OS 1-6, in fact it is a common condition (&gt; 10% of the driving time) to be driving either at low speed (V &lt; 30 km/h) or at high speed (V &gt; 30 km/h).</li><li>The controllability has been set according to the following rules:<ul><li>H1 is considered less controllable than H2 since the driver does not expect that behaviour and he cannot control it by breaking or accelerating. Hence:<ul><li>If V &lt; 30 km/h → C = 2;</li><li>If V &gt; 30 km/h → C = 3;</li></ul></li><li>H2 is considered more controllable than H1 since the driver needs only to brake to avoid dangerous situations. Then:<ul><li>If V &lt; 30 km/h → C = 1;</li><li>If V &gt; 30 km/h → C = 2;</li></ul></li></ul></li><li>The severity has been set according to the following rules:<ul><li>If V &lt; 30 km/h, then:<ul><li>If only one of the two distances is not respected → S = 1;</li><li>If both the distances are not respected → S = 2;</li></ul></li><li>If V &gt; 30 km/h, then:<ul><li>If only one of the two distances is not respected → S = 2;</li><li>If both the distances are not respected → S = 3;</li></ul></li></ul></li><li>For what concerns OS7:<ul><li>The exposure is set to 3 since we consider an urban scenario, then it is medium probable (1% - 10% of driving time) to have a pedestrian or a cycle crossing the road.</li><li>The severity is always set to 3.</li><li>The controllability depends on the hazard.</li></ul></li></ul><h3 id="Definition-of-Safety-goals">Definition of Safety goals</h3><p>The item shall measure correctly the distance of the preceding vehicle and shall send the brake request only if the condition V<sup>2</sup>/100&lt;D is verified.</p><h3 id="Definition-of-Functional-Safety-Concepts">Definition of Functional Safety Concepts</h3><p>Since an ASIL D combination came out during the analysis, a lot of resources have to be spent in the functional safety concepts definition.</p><ul><li><strong>FSC1</strong>: An ASIL D compatible microprocessor has to be used.</li><li><strong>FSC2</strong>: the item shall perform self-test in order to check the correct behaviour of all the components. If any misbehaviour is detected, then the item shall transit to safe state.</li><li><strong>FSC3</strong>: redundancy is crucial in case of ASIL D. Hence two radars shall be used to compare the different measurements and eventually two microcontrollers in master-slave configuration.</li><li><strong>FSC4</strong>: a bypass circuit which receives V and D and combines them through some logical ports shall be implemented.</li><li><strong>FSC5</strong>: an external check of the ECU correct working condition shall be implemented.</li></ul><h3 id="Definition-of-the-Safe-State">Definition of the Safe State</h3><ul><li>If only one of the microcontrollers is working, then the other is disabled and the driver is informed.</li><li>If both the microcontrollers are not working, the item is disabled and the driver is informed of the malfunction (e.g. through a led in the dashboard).</li></ul><h3 id="Implementation-of-redundancy">Implementation of redundancy</h3><img src="/2016/08/29/eba-system/circuit.jpg" class="" title="Circuit"><p>In this configuration two boards work in parallel to measure the distance independently and issue brake request. One board is the master and the other is the slave. Only the master can issue brake request. In case of malfunction of the master the slave becomes able to issue brake requests.</p><h2 id="Critical-safety-application-programming">Critical safety application programming</h2><p>As the ISO 26262 specifies, it is necessary to satisfy some software and hardware rules to operate in a critical safety environment. For this reason, part of the software is produced by automation tools such as Simulink. The hardware platform for the ECUs is Freedom K64F, connected to an ultrasonic sensor HC-04 for distance measurement. Furthermore, an Arduino Nano Pro is used as an external ECU which manages and coordinates the two sensoring ECUs.<br>The code of the K64F boards is composed by a discrete state part built in Stateflow, then exported in C code and included in the MBED project.</p><img src="/2016/08/29/eba-system/stateflow.jpg" class="" title="State diagram"><h3 id="K64F-code">K64F code</h3><p>The program is based on the source code exported from the Stateflow chart: the main code manages the inputs and the outputs depending on the ECU working state and tries to catch internal errors.<br>The following are possibile sources of errors:</p><ul><li><strong>No signal from Arduino</strong>: the ECU can not operate because the connection with the manager is broken.</li><li><strong>No signal from body computer (simulated on PC)</strong>: the ECU can not operate without speed value.</li><li><strong>Board error</strong>: in this case the ECU is not able to do a self check of this type, thus this error is recognized by the Arduino and notified to the ECU through serial communication.</li></ul><p>Both the network checks (Arduino and body computer connections) are performed through a timer which is stopped and reset only when the signal is good. After a specific timeout, if no good signal is received, then the board put itself in error state.</p><figure class="highlight cpp"><figcaption><span>reading from body computer</span></figcaption><div><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">read_bc</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">  <span class="comment">// read speed from body computer (ASCII encoding)</span></span><br><span class="line">  <span class="comment">// - if malfunction set state to ERROR</span></span><br><span class="line">  <span class="keyword">if</span> (pc.<span class="built_in">readable</span>())</span><br><span class="line">  &#123;</span><br><span class="line">    <span class="type">bool</span> malfunc = <span class="literal">false</span>;</span><br><span class="line">    <span class="type">int</span> i = <span class="number">0</span>;</span><br><span class="line">    <span class="type">char</span> buf[<span class="number">10</span>];</span><br><span class="line">    <span class="keyword">while</span> (pc.<span class="built_in">readable</span>() &amp;&amp; i&lt;<span class="number">10</span>) &#123;</span><br><span class="line">      buf[i] = pc.<span class="built_in">getc</span>();</span><br><span class="line">      <span class="keyword">if</span> (buf[i] == <span class="string">&#x27;\r&#x27;</span>) <span class="keyword">break</span>;</span><br><span class="line">      <span class="keyword">else</span> <span class="keyword">if</span> (!<span class="built_in">isdigit</span>(buf[i])) malfunc = <span class="literal">true</span>;</span><br><span class="line">      i++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">fflush</span>(pc);</span><br><span class="line">    <span class="keyword">if</span> (!malfunc) &#123;</span><br><span class="line">      <span class="comment">// the communication is working as expected then</span></span><br><span class="line">      <span class="comment">// the value is stored and the timer of network fault</span></span><br><span class="line">      <span class="comment">// check is reset</span></span><br><span class="line">      buf[i] = <span class="string">&#x27;\0&#x27;</span>;</span><br><span class="line">      controller_U.speed = <span class="built_in">atoi</span>(buf);</span><br><span class="line">      <span class="type">bc_t</span>.<span class="built_in">reset</span>();</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>The timer check is executed asynchronously to the main code using a scheduled routine.</p><figure class="highlight cpp"><figcaption><span>network timer check</span></figcaption><div><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">netcheck</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">  <span class="type">bc_t</span>.<span class="built_in">stop</span>();</span><br><span class="line">  <span class="keyword">if</span> (<span class="type">bc_t</span>.<span class="built_in">read_ms</span>() &gt; TIMEOUT) &#123;</span><br><span class="line">    <span class="comment">// network error</span></span><br><span class="line">    state = ERROR;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="type">bc_t</span>.<span class="built_in">start</span>();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>The routine that checks Arduino connection is implemented in a similar way.</p><h3 id="Arduino-code">Arduino code</h3><p>Arduino is responsible for the detection of boards’ errors, as they are not completely able to detect a malfunction themself. The following checks are performed on each ECU port (connected to a K64F board):</p><ul><li><strong>Presence of signal</strong>: if a port does not receive any signal in a defined number of cycles, then it means that the ECU is not working or that the communication cannot take place. After a certain amount of time the ECU is considered faulty.</li><li><strong>Coherence of signal</strong>: the signal coming from a port is analyzed for errors in the structure of information, in particular two checks are executed: the first three characters should represent the distance measured, hence they have to be digits, second, the last two characters should represent respectively the state and the role of ECU. If they are not consistent with what declared before or if the message has an unexpectd total lenght then the ECU could be faulty. However, some disturbs can occur along the transmission line, thus a reasonable number of errors in the stream has to occur in order to consider the ECU faulty.</li><li><strong>Coherence of measure</strong>: the distances measured by the ECUs are compared, and if the difference is higher than a certain threshold, then a malfunction could have happened in one ECU. In this case there is not any other way to check which is the correctly working ECU. Hence, we decided to assume that the master has a better hardware so the slave will be considered faulty after a certain amount of wrong measurements.</li><li><strong>Self check on ECU</strong>: the ECUs inform the manager about their state, because they can detect a malfunction also on their own (for example absence of signal from body computer which should provide vehicle current speed, as stated previously). If the master ECU notifies the manager that it is not working correctly, then the manager promotes the slave by sending a promote signal, so that it can issue brake requests to the vehicle.</li></ul><p>The software implementation relies on SoftwareSerial library, which allows to build virtual serial ports, overcoming the limit imposed by a single UART connected only to pins 0 and 1. With SoftwareSerial, two software ports are created, but they share the same hardware infrastructure (buffer, clock, etc…) so they need to use the resources alternatively. During the main loop of Arduino code, the control over the serial port is swapped between the two software serial connections.<br>The message sent from each K64F board to the Arduino is composed as follows:</p><table><thead><tr><th>Block</th><th>Size</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>0</td><td>3</td><td>text encoding</td><td>Distance measured</td></tr><tr><td>1</td><td>1</td><td>text encoding</td><td>Current state of ECU</td></tr><tr><td>2</td><td>1</td><td>text encoding</td><td>Current role of ECU</td></tr></tbody></table><p>For each port, the following code is executed:</p><figure class="highlight c"><figcaption><span>port reading</span></figcaption><div><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Listening for signals from ECU at port one</span></span><br><span class="line">  i = <span class="number">0</span>;</span><br><span class="line">  f = <span class="literal">false</span>;</span><br><span class="line">  p_one.listen();</span><br><span class="line">  delay(WAITFORDATA);</span><br><span class="line">  <span class="keyword">if</span> (p_one.available())&#123;</span><br><span class="line">    <span class="comment">// A signal is received from ECU at port one</span></span><br><span class="line">    <span class="keyword">while</span>(p_one.available() &amp;&amp; i &lt; <span class="number">5</span>)&#123;</span><br><span class="line">      <span class="keyword">if</span> (i &lt; <span class="number">3</span>)&#123;</span><br><span class="line">        <span class="comment">// First three characters should be digits</span></span><br><span class="line">        buff_n[i] = p_one.read();</span><br><span class="line">        <span class="comment">// If character is not digit there is an error in the stream</span></span><br><span class="line">        <span class="keyword">if</span> (!isDigit(buff_n[i])) f = <span class="literal">true</span>;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="comment">// Other two alphabetic characters for state and role</span></span><br><span class="line">        buff[i<span class="number">-3</span>] = p_one.read();</span><br><span class="line">        <span class="comment">// First is state and should be E (error) or N (normal)</span></span><br><span class="line">        <span class="keyword">if</span> ((i == <span class="number">3</span>) &amp;&amp; !((buff[i<span class="number">-3</span>] == <span class="string">&#x27;E&#x27;</span>) || (buff[i<span class="number">-3</span>] == <span class="string">&#x27;N&#x27;</span>))) f = <span class="literal">true</span>;</span><br><span class="line">        <span class="comment">// Second is role and should be S (slave) or M (master)</span></span><br><span class="line">        <span class="keyword">if</span> ((i == <span class="number">4</span>) &amp;&amp; !((buff[i<span class="number">-3</span>] == <span class="string">&#x27;S&#x27;</span>) || (buff[i<span class="number">-3</span>] == <span class="string">&#x27;M&#x27;</span>))) f = <span class="literal">true</span>;</span><br><span class="line">      &#125;</span><br><span class="line">      i++;</span><br><span class="line">      delay(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// If the message lenght is not the one expected or there is a structure error</span></span><br><span class="line">    <span class="comment">// in the stream then the count of errors at port one is incremented</span></span><br><span class="line">    <span class="keyword">if</span> ((i != <span class="number">5</span>) || f ) &#123; </span><br><span class="line">      p_one_errors++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="comment">// If the message is good the count of errors is reset</span></span><br><span class="line">      p_one_errors = <span class="number">0</span>;</span><br><span class="line">      <span class="comment">// The conversion of distance from characters to integer takes place</span></span><br><span class="line">      <span class="comment">// through the function atoi which accepts a string so the last character</span></span><br><span class="line">      <span class="comment">// has to be a null character</span></span><br><span class="line">      buff_n[<span class="number">3</span>] = <span class="string">&#x27;\0&#x27;</span>;</span><br><span class="line">      dist_one = atoi(buff_n);</span><br><span class="line">      <span class="comment">// If the ECU is already in fault (due to previous communication from manager</span></span><br><span class="line">      <span class="comment">// or failed self check) then it is considered</span></span><br><span class="line">      state_one = buff[<span class="number">0</span>];</span><br><span class="line">      <span class="keyword">if</span> (buff[<span class="number">0</span>] == <span class="string">&#x27;E&#x27;</span>) fault_one = <span class="literal">true</span>;</span><br><span class="line">      <span class="comment">// The role of ECU at port one is saved</span></span><br><span class="line">      <span class="keyword">if</span> (buff[<span class="number">1</span>] == <span class="string">&#x27;M&#x27;</span>)</span><br><span class="line">        role_one = <span class="number">0</span>;</span><br><span class="line">      <span class="keyword">else</span></span><br><span class="line">        role_one = <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// A message has arrived, then the counter of steps without message has to be</span></span><br><span class="line">    <span class="comment">// reset</span></span><br><span class="line">    wait_one = <span class="number">0</span>;</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="comment">// No message received, then the counter of steps without message has to be</span></span><br><span class="line">    <span class="comment">// incremented</span></span><br><span class="line">    wait_one++;  </span><br><span class="line">  &#125;</span><br></pre></td></tr></table></div></figure><p>After the reading of the second serial port, all the checks are performed, and response is sent to the boards:</p><figure class="highlight c"><figcaption><span>error check</span></figcaption><div><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// If the distances are too much different the counter of measurement</span></span><br><span class="line">  <span class="comment">// errors is incremented, otherwise is reset</span></span><br><span class="line">  <span class="keyword">if</span> (THRESHOLD &lt; <span class="built_in">abs</span>(dist_two - dist_one))&#123;</span><br><span class="line">    dist_errors++;</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    dist_errors = <span class="number">0</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// If the measurements differ for too long time the slave board if marked</span></span><br><span class="line">  <span class="comment">// as faulty if the master is not faulty</span></span><br><span class="line">  <span class="keyword">if</span> (dist_errors &gt; MAXDISTER) &#123;</span><br><span class="line">    <span class="keyword">if</span> ((role_one == <span class="number">0</span>) &amp;&amp; !fault_one) fault_two = <span class="literal">true</span>;</span><br><span class="line">    <span class="keyword">if</span> ((role_two == <span class="number">0</span>) &amp;&amp; !fault_two) fault_one = <span class="literal">true</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// If the stream from an ECU is not coherent or is not present at all</span></span><br><span class="line">  <span class="comment">// for some time, the the ECU is marked as faulty</span></span><br><span class="line">  <span class="keyword">if</span> (p_one_errors &gt; MAXERRORS || wait_one &gt; MAXWAIT) fault_one = <span class="literal">true</span>;</span><br><span class="line">  <span class="keyword">if</span> (p_two_errors &gt; MAXERRORS || wait_two &gt; MAXWAIT) fault_two = <span class="literal">true</span>;</span><br><span class="line">  <span class="comment">// Messages to the ECUs are sent on the base of their state:</span></span><br><span class="line">  <span class="comment">// - E stands for error: if an ECU receives E it put itself in error</span></span><br><span class="line">  <span class="comment">//   state if is not already in that state</span></span><br><span class="line">  <span class="comment">// - P stands for promote: if an ECU receives P it put its role in</span></span><br><span class="line">  <span class="comment">//   master state if is not alreay in master state (i.e. able to issue</span></span><br><span class="line">  <span class="comment">//   brake requests)</span></span><br><span class="line">  <span class="keyword">if</span> (fault_one &amp;&amp; !fault_two)&#123;</span><br><span class="line">    p_one.print(<span class="string">&quot;E&quot;</span>);</span><br><span class="line">    <span class="keyword">if</span> (role_two == <span class="number">1</span>)</span><br><span class="line">      p_two.print(<span class="string">&quot;P&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">if</span> (!fault_one &amp;&amp; fault_two)&#123;</span><br><span class="line">    <span class="keyword">if</span> (role_one == <span class="number">1</span>)</span><br><span class="line">      p_one.print(<span class="string">&quot;P&quot;</span>);</span><br><span class="line">    p_two.print(<span class="string">&quot;E&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">if</span> (fault_one &amp;&amp; fault_two)&#123;</span><br><span class="line">    Serial.println(<span class="string">&quot;No ECUs available. System is deactivated.&quot;</span>);</span><br><span class="line">    <span class="comment">// An infinite delay means that the component is deactivated</span></span><br><span class="line">    <span class="comment">// Error message is transmitted continuously to be sure that the boards</span></span><br><span class="line">    <span class="comment">// receive it</span></span><br><span class="line">    <span class="keyword">while</span>(<span class="literal">true</span>)&#123;</span><br><span class="line">      p_one.print(<span class="string">&quot;E&quot;</span>);</span><br><span class="line">      delay(<span class="number">1</span>);</span><br><span class="line">      p_two.print(<span class="string">&quot;E&quot;</span>);</span><br><span class="line">      delay(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// Moreover a visual indicator, like a LED can be lighted in this</span></span><br><span class="line">    <span class="comment">// case by the manager through a DigitalWrite command and a suitable circuit.</span></span><br><span class="line">  &#125;</span><br></pre></td></tr></table></div></figure><p>To improve the system, a bypass communicaton between master and slave can be added, because in case of manager fault the system is not able to work at all. Anyway, in this study, the manager is considered always working properly.</p><h3 id="Source-code">Source code</h3><p>The code is available at the following <a href="https://github.com/alessandroste/EBA-electronic-system-FRDM-K64F">location</a>.</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;This is a project developed for an university assignment. The task was to develop an Emergency Braking Assist system for a generic city c</summary>
      
    
    
    
    
  </entry>
  
  <entry>
    <title>Wrecking Madness</title>
    <link href="http://example.com/2016/08/29/wrecking-madness/"/>
    <id>http://example.com/2016/08/29/wrecking-madness/</id>
    <published>2016-08-29T16:32:17.000Z</published>
    <updated>2026-07-01T00:00:46.529Z</updated>
    
    <content type="html"><![CDATA[<p>This game is born as an exercise of coding in C++. It can be found on <a href="https://play.google.com/store/apps/details?id=com.ales.wreckingmadness">Google Play</a>, I expect to update it in the future to be more challenging and entertaining.</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;This game is born as an exercise of coding in C++. It can be found on &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.ales.wre</summary>
      
    
    
    
    
  </entry>
  
  <entry>
    <title>Reinforcement learning with LEGO NXT</title>
    <link href="http://example.com/2016/08/29/q-learning-nxt/"/>
    <id>http://example.com/2016/08/29/q-learning-nxt/</id>
    <published>2016-08-29T09:05:11.000Z</published>
    <updated>2026-07-01T00:00:46.476Z</updated>
    
    <content type="html"><![CDATA[<p>In machine learning problems, it is often impossible to provide training examples to teach a software agent how to behave in a particular environment. Actually, in some cases, the environment is partially unknown: a specific set of correct and exhaustive input/output pairs can not be determined. In such situations, supervised learning is not feasible because no model of correct behavior is available: a different, <em>model-free</em> approach has to be adopted.<br>Reinforcement learning uses an environmental value called <em>reward</em>, which has to be maximized over time. With this assumption, all the problems of this type can be solved with a function to be optimized. The software attemps to determine a mapping between states of the machine and the actions that have to be taken to maximize the reward. This is called <em>policy</em>. When the the optimization algorithm converges, only a sequence of actions (optimal policy) is considered and this is the best in increasing the reward.<br>Q-learning is one of these algorithms and attemps to find the optimal policy using a matrix of pairs between action and states.</p><h2 id="The-agent">The agent</h2><img src="/2016/08/29/q-learning-nxt/robot.jpg" class="" title="Hardware agent"><p>The software is implemented on a LEGO Mindstorms NXT in NXC language, which provides a good flexibility and a low level access to the hardware resources. Our agent is a single armed robot which has to learn how to move its arm to crawl. The feedback of its actions is acquired through the encoders in the servo motor connected to the wheels.<br>The arm is composed by two joints and two links: <em>arm</em> and <em>hand</em>. The hand has a free extremity, instead the arm is connected to the robot.<br>To provide better stability and improved torque, some reduction gears have been applied between motors and connected links.<br>Building instructions can be found <a href="instructions.pdf">here</a>.</p><div class="tip">For some reason two worm gears are missing in the instructions. It can be figured out which ones they are because without them the arm can not be moved.</div>Top view of the robot:<img src="/2016/08/29/q-learning-nxt/robot-top.jpg" class="" title="Top view"><h2 id="Q-learning">Q-learning</h2><p>This algorithm has three main assumptions:</p><ul><li>a model of the environment is known</li><li>the complete set of doable actions is known</li><li>an environmental value used as reward is available</li></ul><h3 id="Model-of-the-environment">Model of the environment</h3><p>In this particular case the robot acts on itself, thus the agent can be considered the environment. In particular it is necessary to define what are the possible states in which the agent can be. In the case of a path finding agent, the states are the possibile positions of the agent in the environment. Instead, for this robot, the states are all the possible position configurations that the arm and the hand can have.<br>At first glance, the number of total states is the cartesian product of hand states and arm states, nevertheless, arm and hand states are infinite, and the consequence is an infinite number of total states. The solution is to discretize arm and hand positions, for example using a step of 30°. Moreover, both the arm and the hand can not rotate by 360°: the total range, which is smaller, can be measured using the sensor functionality of NXT motors.<br>For example 4 states will be used for both the hand and the arm: the total number of states is 16. The position of each link will be encoded with a number between <em>0</em> and <em>3</em>.</p><figure class="highlight c"><figcaption><span>states definition</span></figcaption><div><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">define</span> ARM_STATES        4</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> HAND_STATES       4</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ARM_INIT_STATE    0</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> HAND_INIT_STATE   0</span></span><br></pre></td></tr></table></div></figure><h3 id="Set-of-actions">Set of actions</h3><p>Given the structure of the agent, only two types of actions can be done for each joint: rotate in a sense or in the other. In conclusion there are <em>4</em> overall actions doable by the robot:</p><figure class="highlight c"><figcaption><span>actions definition</span></figcaption><div><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">define</span> ARM_UP      0</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ARM_DOWN    1</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> HAND_UP     2</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> HAND_DOWN   3</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> NONE       -1</span></span><br></pre></td></tr></table></div></figure><p>The definition of <em>NONE</em> action is important because it is used for the initialization of the vector containing the sequence of actions.</p><h3 id="Reward">Reward</h3><p>The reward is the movement of the robot: it is measured through the wheels. Also, velocity can be used, but it is required to compute the ratio between the displacement of the robot and the number of iterations.</p><h3 id="Algorithm-structure">Algorithm structure</h3><p>The algorithm starts with the initialization of all the variables:</p><ul><li>A <strong>matrix Q</strong> with dimension equal to the cartesian product between the number of states and the number of actions: its value measures the consequences in terms of reward of each action for a given state.</li></ul><figure class="highlight c"><figcaption><span>Q definiton</span></figcaption><div><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">float</span> Q[ARM_STATES][HAND_STATES][NUM_ACTIONS];</span><br></pre></td></tr></table></div></figure><ul><li>A <strong>matrix E</strong> (eligibility) with the same dimension of Q: it is used to create a policy and makes Q higher for actions leading to a greater reward in successive steps.</li></ul><figure class="highlight c"><figcaption><span>E definiton</span></figcaption><div><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">float</span> E[ARM_STATES][HAND_STATES][NUM_ACTIONS];</span><br></pre></td></tr></table></div></figure><p>Both Q and E matrices should be initialized with zeros.</p><ul><li><strong>Two vectors</strong> to store actions</li></ul><figure class="highlight c"><figcaption><span>sequence vectors definiton</span></figcaption><div><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">unsigned</span> <span class="type">int</span> sequence[MAXSEQ];</span><br><span class="line"><span class="type">unsigned</span> <span class="type">int</span> sequence_old[MAXSEQ];</span><br></pre></td></tr></table></div></figure><p>The two vectors of actions should be initialized with action NONE (-1);</p><p>The complete initialization code is the following:</p><figure class="highlight c"><figcaption><span>initialization</span></figcaption><div><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// set Q and E to all zeros</span></span><br><span class="line"><span class="keyword">for</span> (<span class="type">int</span> i=<span class="number">0</span>; i&lt;ARM_STATES; i++)</span><br><span class="line">  <span class="keyword">for</span> (<span class="type">int</span> j=<span class="number">0</span>; j&lt;HAND_STATES; j++)</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> k=<span class="number">0</span>; k&lt;NUM_ACTIONS; k++)&#123;</span><br><span class="line">  <span class="keyword">if</span> (init)&#123;</span><br><span class="line">    Q[i][j][k]=<span class="number">0</span>;</span><br><span class="line">    E[i][j][k]=<span class="number">0</span>;</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    E[i][j][k]=<span class="number">0</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// set policy to all none</span></span><br><span class="line"><span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; MAXSEQ; i++)&#123;</span><br><span class="line"><span class="keyword">if</span> (init)&#123;</span><br><span class="line">  sequence_old[i] = NONE;</span><br><span class="line">&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">  sequence_old[i] = sequence[i];</span><br><span class="line">&#125;</span><br><span class="line">  sequence[i] = NONE;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// reset steps</span></span><br><span class="line">steps = <span class="number">0</span>;</span><br><span class="line"><span class="comment">// initial reward</span></span><br><span class="line">reward = <span class="number">0</span>;</span><br></pre></td></tr></table></div></figure><p>The optimization part consists in a cycle which termines only when the sequence of actions is optimal, i.e. when it is the same of the previous cycle. The cycle is composed by the following steps:</p><ul><li>Between all the possible actions doable in the current state choose the one with the highest Q, if they all have the same value, then do a random action.</li><li>Do the action and get the reward.</li><li>Update the sequence vector and the matrices.</li><li>If the reward is positive check the convergence of the sequence of actions:<ul><li>if convergency happens then exit</li><li>otherwise reset the agent to initial position</li></ul></li><li>else do another action.</li></ul><h3 id="Choosing-the-action">Choosing the action</h3><p>The choice of the action to do is based on two opposite approaches: <strong>exploitation</strong> and <strong>exploration</strong>.</p><ul><li><strong>Exploitation</strong> means to use the acquired knowledge of the environment to choose an action which maximizes the reward: it is a reasoned choice.</li><li><strong>Exploration</strong> means to choose arbitrarily the following action.</li></ul><p>There are many criteria to select the right approach: in this case the exploration behavior is used only when acquired knowledge is missing or it is unuseful.<br>For example, a probabilistic approach could have been applied: the kind of approach adopted depends on the result of a random outcome.</p><figure class="highlight c"><figcaption><span>choice of the action</span></figcaption><div><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">unsigned</span> <span class="type">int</span> <span class="title function_">chooseMovement</span><span class="params">(<span class="type">unsigned</span> <span class="type">int</span> arm, <span class="type">unsigned</span> <span class="type">int</span> hand)</span>&#123;</span><br><span class="line">  <span class="type">unsigned</span> <span class="type">int</span> choices[NUM_ACTIONS];</span><br><span class="line">  <span class="type">unsigned</span> <span class="type">int</span> num_of_choices = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">if</span> (arm &gt; <span class="number">0</span>)&#123;</span><br><span class="line">      <span class="comment">// arm can be moved down</span></span><br><span class="line">    choices[num_of_choices] = ARM_DOWN;</span><br><span class="line">    num_of_choices++;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">if</span> (arm &lt; ARM_STATES)&#123;</span><br><span class="line">    <span class="comment">// arm can be moved up</span></span><br><span class="line">    choices[num_of_choices] = ARM_UP;</span><br><span class="line">    num_of_choices++;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">if</span> (hand &gt; <span class="number">0</span>)&#123;</span><br><span class="line">    <span class="comment">// hand can be moved down</span></span><br><span class="line">    choices[num_of_choices] = HAND_DOWN;</span><br><span class="line">    num_of_choices++;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">if</span> (hand &lt; HAND_STATES)&#123;</span><br><span class="line">    <span class="comment">// hand can be moved up</span></span><br><span class="line">    choices[num_of_choices] = HAND_UP;</span><br><span class="line">    num_of_choices++;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// have all the actions the same Q?</span></span><br><span class="line">  <span class="type">bool</span> eq = <span class="literal">true</span>;</span><br><span class="line">  <span class="type">float</span> curr_Q = Q[arm][hand][choices[<span class="number">0</span>]];</span><br><span class="line">  <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt; num_of_choices; i++)&#123;</span><br><span class="line">    <span class="keyword">if</span> (Q[arm][hand][choices[i]] != curr_Q)&#123;</span><br><span class="line">      eq = <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">if</span> (!eq)&#123;</span><br><span class="line">    <span class="comment">// there&#x27;s a max Q</span></span><br><span class="line">    <span class="type">float</span> bestQ = Q[arm][hand][choices[<span class="number">0</span>]];</span><br><span class="line">    <span class="type">int</span> best_index = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt; num_of_choices; i++)&#123;</span><br><span class="line">      <span class="keyword">if</span> (Q[arm][hand][choices[i]] &gt; bestQ)&#123;</span><br><span class="line">        best_index = i;</span><br><span class="line">        bestQ = Q[arm][hand][choices[i]];</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> choices[best_index];</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="comment">// they are all equal</span></span><br><span class="line">    <span class="keyword">return</span> choices[Random(num_of_choices)];</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><h3 id="Actions-execution">Actions execution</h3><p>Executing the action is a matter of motor rotation, with some simple lines of code it is easily achieved. It is important to save the motor position before and after the action to compute the value of the reward.</p><h3 id="Updating-matrices">Updating matrices</h3><p>The core of the algorithm is made by <strong>Q</strong> and <strong>E</strong> matrices.<br>In general, for each value of the matrices</p><p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>Q</mi><mrow><mi>i</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>=</mo><mo stretchy="false">(</mo><mn>1</mn><mo>−</mo><mi>α</mi><mo stretchy="false">)</mo><mo>⋅</mo><msub><mi>Q</mi><mi>i</mi></msub><mo>+</mo><mi>α</mi><mo>⋅</mo><mi>δ</mi><mo>⋅</mo><msub><mi>E</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">Q _{i+1} = (1 - \alpha) \cdot Q_i + \alpha \cdot \delta \cdot E_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8917em;vertical-align:-0.2083em;"></span><span class="mord"><span class="mord mathnormal">Q</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2083em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8778em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal">Q</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.4445em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03785em;">δ</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05764em;">E</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.0576em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></span></p><p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>E</mi><mrow><mi>i</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>=</mo><msub><mi>E</mi><mi>i</mi></msub><mo>⋅</mo><mi>τ</mi></mrow><annotation encoding="application/x-tex">E _{i+1} = E_i \cdot \tau</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8917em;vertical-align:-0.2083em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05764em;">E</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.0576em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2083em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05764em;">E</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.0576em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal" style="margin-right:0.1132em;">τ</span></span></span></span></span></p><p>where</p><p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>δ</mi><mo>=</mo><mo stretchy="false">(</mo><mi>r</mi><mi>e</mi><mi>w</mi><mi>a</mi><mi>r</mi><mi>d</mi><mo>+</mo><mo stretchy="false">(</mo><mi>β</mi><mo>⋅</mo><msub><mi>Q</mi><mrow><mi>M</mi><mi>A</mi><mi>X</mi></mrow></msub><mo stretchy="false">)</mo><mo>−</mo><msub><mi>Q</mi><mi>P</mi></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\delta = (reward + ( \beta \cdot Q _{MAX}) - Q_P)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03785em;">δ</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">re</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.05278em;">β</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">Q</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.10903em;">M</span><span class="mord mathnormal mtight">A</span><span class="mord mathnormal mtight" style="margin-right:0.07847em;">X</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">Q</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">P</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span></span></p><ul><li><strong>Q<sub>P</sub></strong> is the Q value of the old state and the current action.</li><li><strong>reward</strong> does not need any explanation.</li><li><strong>Q<sub>MAX</sub></strong> is the best Q available for the current state considering all the possible actions. It is not important to filter only available actions in particular states, because the actions that are not possible to be done will have always a 0 value for Q as they can not be chosen.</li><li><strong>α</strong>, <strong>β</strong>, <strong>τ</strong> are coefficients between 0 and 1 and they tune the algorithm. In particular<ul><li>α is the rate of learning: an higher value will produce a faster learning behavior</li><li>β is the weight of the policy (farsight): the higher it is, the more the following possible actions will influence the choice of the current action</li><li>τ is the forgetting factor</li></ul></li></ul><p>Before the computation of <strong>Q</strong> and <strong>E</strong> it is necessary to update the eligibility value of the action done:</p><p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>E</mi><mi>P</mi></msub><mo>=</mo><msub><mi>E</mi><mi>P</mi></msub><mo>+</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">E_P = E_P + 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05764em;">E</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:-0.0576em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">P</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05764em;">E</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3283em;"><span style="top:-2.55em;margin-left:-0.0576em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">P</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span></span></p><p>E<sub>P</sub> is the eligibility of the previous state and the current action.</p><figure class="highlight c"><figcaption><span>code for matrices update</span></figcaption><div><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">void</span> <span class="title function_">updateQ</span><span class="params">(<span class="type">unsigned</span> <span class="type">int</span> arm, <span class="type">unsigned</span> <span class="type">int</span> hand, <span class="type">unsigned</span> <span class="type">int</span> arm_old, <span class="type">unsigned</span> <span class="type">int</span> hand_old, <span class="type">unsigned</span> <span class="type">int</span> move, <span class="type">int</span> rew)</span>&#123;</span><br><span class="line">  <span class="type">float</span> max_Q = Q[arm][hand][<span class="number">0</span>];</span><br><span class="line">  <span class="keyword">for</span> (<span class="type">int</span> i=<span class="number">1</span>; i&lt;NUM_ACTIONS; i++)&#123;</span><br><span class="line">    <span class="keyword">if</span> (Q[arm][hand][i]&gt;max_Q) max_Q=Q[arm][hand][i];</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="type">float</span> old_Q = Q[arm_old][hand_old][move];</span><br><span class="line">  <span class="type">float</span> d = (rew + (BETA* max_Q) - old_Q);</span><br><span class="line">  E[arm_old][hand_old][move]++;</span><br><span class="line">  <span class="keyword">for</span> (<span class="type">int</span> i=<span class="number">0</span>; i&lt;ARM_STATES; i++)</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> j=<span class="number">0</span>; j&lt;HAND_STATES; j++)</span><br><span class="line">      <span class="keyword">for</span> (<span class="type">int</span> k=<span class="number">0</span>; k&lt;NUM_ACTIONS; k++)&#123;</span><br><span class="line">        Q[i][j][k]=(<span class="number">1</span>-ALPHA)*Q[i][j][k]+ ALPHA*d*E[i][j][k];</span><br><span class="line">        E[i][j][k]=E[i][j][k]* TAU;</span><br><span class="line">      &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><h3 id="The-main-cycle">The main cycle</h3><p>All these functions have to be used in the main cycle as described before: the following is an example of main function.</p><figure class="highlight c"><figcaption><span>main function</span></figcaption><div><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line">task <span class="title function_">main</span><span class="params">()</span>&#123;</span><br><span class="line">  reset(<span class="literal">true</span>); <span class="comment">// if argument is true the vector storing the old sequence is reset, too</span></span><br><span class="line">  <span class="keyword">while</span>(ButtonPressed(BTNCENTER, <span class="literal">false</span>) == <span class="number">0</span>)&#123;</span><br><span class="line">    <span class="comment">// if terminal state</span></span><br><span class="line">    <span class="keyword">if</span> (reward &gt; <span class="number">0</span>)&#123;</span><br><span class="line">      <span class="comment">// check for convergence</span></span><br><span class="line">      <span class="keyword">if</span> (checkConvergence())&#123;</span><br><span class="line">        <span class="comment">// finished learning</span></span><br><span class="line">        Wait(<span class="number">500</span>);</span><br><span class="line">        PlayTone(<span class="number">400</span>,<span class="number">300</span>);</span><br><span class="line">        Wait(<span class="number">100</span>);</span><br><span class="line">        PlayTone(<span class="number">600</span>,<span class="number">300</span>);</span><br><span class="line">        ClearLine(LCD_LINE3);</span><br><span class="line">        TextOut(<span class="number">0</span>, LCD_LINE3, <span class="string">&quot;Convergence&quot;</span>);</span><br><span class="line">        Wait(<span class="number">1000</span>);</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="comment">// reset agent</span></span><br><span class="line">        reset(<span class="literal">false</span>);</span><br><span class="line">      &#125;</span><br><span class="line">    <span class="comment">// if not a terminal state</span></span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="comment">// save old state</span></span><br><span class="line">      arm_previous = arm_current;</span><br><span class="line">      hand_previous = hand_current;</span><br><span class="line">      <span class="comment">// select move</span></span><br><span class="line">      <span class="type">unsigned</span> <span class="type">int</span> chosen_move = chooseMovement(arm_current, hand_current);</span><br><span class="line">      <span class="comment">// perform movement and change state</span></span><br><span class="line">      reward = performMovement(chosen_move);</span><br><span class="line">      <span class="comment">// update Q values</span></span><br><span class="line">      updateQ(arm_current, hand_current, arm_previous, hand_previous, chosen_move, reward);</span><br><span class="line">      <span class="comment">// record to policy</span></span><br><span class="line">      sequence[steps] = chosen_move;</span><br><span class="line">      steps++;</span><br><span class="line">    &#125;</span><br><span class="line">    ResetSleepTimer();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><h2 id="Conclusion">Conclusion</h2><p>The complete code can be found in my <a href="https://github.com/alessandroste/NXT-Q-learning">GitHub repo</a>, it requires some parameter tuning. The learning is extremely slow, because the machine is intrinsically slow: if you try to simulate the agent with only software you can see results in short time. For code compilation and deployment, <a href="http://bricxcc.sourceforge.net/">BricxCC</a> is a good choice if you are on Windows, otherwise <a href="http://bricxcc.sourceforge.net/nbc/">NBC</a> is available for all platforms, but without IDE.</p><h2 id="Sitography">Sitography</h2><ul><li><a href="http://www.applied-mathematics.net/qlearning/qlearning.html">Q-learning applet with an one arm robot</a></li><li><a href="http://burlap.cs.brown.edu/tutorials/cpl/p3.html#qlo">Q-learning overview</a></li><li><a href="https://github.com/sandropaganotti/processing.org-q-learning-td-lambda-">Visual q-learning Processing sketch</a></li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;In machine learning problems, it is often impossible to provide training examples to teach a software agent how to behave in a particular</summary>
      
    
    
    
    
  </entry>
  
</feed>
