<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Faizan’s Blog]]></title><description><![CDATA[Software Engineering, Startup, Scale-up]]></description><link>https://www.faixan.com</link><image><url>https://www.faixan.com/img/substack.png</url><title>Faizan’s Blog</title><link>https://www.faixan.com</link></image><generator>Substack</generator><lastBuildDate>Wed, 06 May 2026 11:49:11 GMT</lastBuildDate><atom:link href="https://www.faixan.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Faizan Naqvi]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[faizann@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[faizann@substack.com]]></itunes:email><itunes:name><![CDATA[Faizan Naqvi]]></itunes:name></itunes:owner><itunes:author><![CDATA[Faizan Naqvi]]></itunes:author><googleplay:owner><![CDATA[faizann@substack.com]]></googleplay:owner><googleplay:email><![CDATA[faizann@substack.com]]></googleplay:email><googleplay:author><![CDATA[Faizan Naqvi]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Agentic Code Execution instead of tool calls]]></title><description><![CDATA[Elixir and function docs are perfect for agentic code generation instead of tool call chaining.]]></description><link>https://www.faixan.com/p/agentic-code-execution-instead-of</link><guid isPermaLink="false">https://www.faixan.com/p/agentic-code-execution-instead-of</guid><dc:creator><![CDATA[Faizan Naqvi]]></dc:creator><pubDate>Fri, 19 Dec 2025 09:38:57 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/3085fda6-eb8a-4ef2-a222-bda4f0fd1a10_1280x896.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>This post is my own words and not generated by LLM.</em></p><h2>TL;DR</h2><ul><li><p>LLM generates code instead of calling tools one by one.</p></li><li><p>Elixir docs contain the samples needed by LLM to generate code.</p></li><li><p>Virtual file system for agent to browse sample code.</p></li><li><p>Security is achieved with function wrapping and <a href="https://hexdocs.pm/dune/Dune.html">Dune</a> library.</p><div><hr></div></li></ul><p>Working with LLM agents, most of us have found tool calling slow and wastage of LLM tokens. Moreover, building the tools usually requires adding another layer to encapsulate the business logic with a request/response schema and then maintaining it.</p><p>Lately, there has been a lot of buzz around <a href="https://www.anthropic.com/engineering/code-execution-with-mcp">code execution with MCP</a> to speed up multi-step tool calling. The idea is to simply let LLM generate code using samples provided and execute it directly instead of sequential tool calling. This optimises the speed, reliability and token economics.</p><h2>Elixir and Agentic Code Generation</h2><p>I had already written an agentic framework in Elixir as it is a very suitable ecosystem for LLM Agents. Apparently, Elixir also really shines in agentic code generation as the documentation of functions comes with <a href="https://github.com/wojtekmach/req/blob/v0.5.16/lib/req.ex#L592">examples</a> as to how to call that code. These examples can be tested using <a href="https://hexdocs.pm/ex_unit/ExUnit.DocTest.html#doctest/1">doctest</a> to make sure the code changes and documentation don&#8217;t deviate. This coupling reduces the need to provide samples separately and maintain them.</p><p>Having examples meant that I could simply look for <code>## Examples</code> heading in the function&#8217;s <code>@doc</code> tag, thus avoiding the need to write separate tool files with sample code.</p><h3>Virtual File System</h3><p>I ended up with a framework where I created a virtual file system that agent could browse to list resources and tool definitions.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pHOv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e0fe4e-5909-4c70-9963-e9a335e561cb_1216x436.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pHOv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e0fe4e-5909-4c70-9963-e9a335e561cb_1216x436.png 424w, https://substackcdn.com/image/fetch/$s_!pHOv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e0fe4e-5909-4c70-9963-e9a335e561cb_1216x436.png 848w, https://substackcdn.com/image/fetch/$s_!pHOv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e0fe4e-5909-4c70-9963-e9a335e561cb_1216x436.png 1272w, https://substackcdn.com/image/fetch/$s_!pHOv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e0fe4e-5909-4c70-9963-e9a335e561cb_1216x436.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pHOv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e0fe4e-5909-4c70-9963-e9a335e561cb_1216x436.png" width="1216" height="436" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e8e0fe4e-5909-4c70-9963-e9a335e561cb_1216x436.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:436,&quot;width&quot;:1216,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:76550,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.faixan.com/i/182058093?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e0fe4e-5909-4c70-9963-e9a335e561cb_1216x436.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!pHOv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e0fe4e-5909-4c70-9963-e9a335e561cb_1216x436.png 424w, https://substackcdn.com/image/fetch/$s_!pHOv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e0fe4e-5909-4c70-9963-e9a335e561cb_1216x436.png 848w, https://substackcdn.com/image/fetch/$s_!pHOv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e0fe4e-5909-4c70-9963-e9a335e561cb_1216x436.png 1272w, https://substackcdn.com/image/fetch/$s_!pHOv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e0fe4e-5909-4c70-9963-e9a335e561cb_1216x436.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em><strong>Note</strong>: I decided to go with .exs extension to add a hint to the LLM that this is elixir code. I have no proof if it increased accuracy of the generated code.</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!m3W2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F185a1715-3cff-46ca-a6f2-a24aa73ec7d6_1236x652.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!m3W2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F185a1715-3cff-46ca-a6f2-a24aa73ec7d6_1236x652.png 424w, https://substackcdn.com/image/fetch/$s_!m3W2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F185a1715-3cff-46ca-a6f2-a24aa73ec7d6_1236x652.png 848w, https://substackcdn.com/image/fetch/$s_!m3W2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F185a1715-3cff-46ca-a6f2-a24aa73ec7d6_1236x652.png 1272w, https://substackcdn.com/image/fetch/$s_!m3W2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F185a1715-3cff-46ca-a6f2-a24aa73ec7d6_1236x652.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!m3W2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F185a1715-3cff-46ca-a6f2-a24aa73ec7d6_1236x652.png" width="1236" height="652" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/185a1715-3cff-46ca-a6f2-a24aa73ec7d6_1236x652.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:652,&quot;width&quot;:1236,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:111373,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.faixan.com/i/182058093?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F185a1715-3cff-46ca-a6f2-a24aa73ec7d6_1236x652.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!m3W2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F185a1715-3cff-46ca-a6f2-a24aa73ec7d6_1236x652.png 424w, https://substackcdn.com/image/fetch/$s_!m3W2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F185a1715-3cff-46ca-a6f2-a24aa73ec7d6_1236x652.png 848w, https://substackcdn.com/image/fetch/$s_!m3W2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F185a1715-3cff-46ca-a6f2-a24aa73ec7d6_1236x652.png 1272w, https://substackcdn.com/image/fetch/$s_!m3W2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F185a1715-3cff-46ca-a6f2-a24aa73ec7d6_1236x652.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>File Browsing Tools</h3><p>Next I created 3 tools <strong>list_resources</strong>, <strong>list_files</strong> and <strong>read_file</strong>. These tools allowed agent to browse the virtual file system and read code in each file.</p><h4>list_resources</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fV6R!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feac3f767-7126-4343-b1dd-b639d078fd6a_836x324.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fV6R!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feac3f767-7126-4343-b1dd-b639d078fd6a_836x324.png 424w, https://substackcdn.com/image/fetch/$s_!fV6R!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feac3f767-7126-4343-b1dd-b639d078fd6a_836x324.png 848w, https://substackcdn.com/image/fetch/$s_!fV6R!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feac3f767-7126-4343-b1dd-b639d078fd6a_836x324.png 1272w, https://substackcdn.com/image/fetch/$s_!fV6R!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feac3f767-7126-4343-b1dd-b639d078fd6a_836x324.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fV6R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feac3f767-7126-4343-b1dd-b639d078fd6a_836x324.png" width="836" height="324" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/eac3f767-7126-4343-b1dd-b639d078fd6a_836x324.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:324,&quot;width&quot;:836,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:42541,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.faixan.com/i/182058093?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feac3f767-7126-4343-b1dd-b639d078fd6a_836x324.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fV6R!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feac3f767-7126-4343-b1dd-b639d078fd6a_836x324.png 424w, https://substackcdn.com/image/fetch/$s_!fV6R!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feac3f767-7126-4343-b1dd-b639d078fd6a_836x324.png 848w, https://substackcdn.com/image/fetch/$s_!fV6R!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feac3f767-7126-4343-b1dd-b639d078fd6a_836x324.png 1272w, https://substackcdn.com/image/fetch/$s_!fV6R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feac3f767-7126-4343-b1dd-b639d078fd6a_836x324.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4>list_files</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FzLm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cee48a1-62db-43c2-8e43-5f90c349cd89_1302x884.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FzLm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cee48a1-62db-43c2-8e43-5f90c349cd89_1302x884.png 424w, https://substackcdn.com/image/fetch/$s_!FzLm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cee48a1-62db-43c2-8e43-5f90c349cd89_1302x884.png 848w, https://substackcdn.com/image/fetch/$s_!FzLm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cee48a1-62db-43c2-8e43-5f90c349cd89_1302x884.png 1272w, https://substackcdn.com/image/fetch/$s_!FzLm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cee48a1-62db-43c2-8e43-5f90c349cd89_1302x884.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FzLm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cee48a1-62db-43c2-8e43-5f90c349cd89_1302x884.png" width="1302" height="884" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0cee48a1-62db-43c2-8e43-5f90c349cd89_1302x884.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:884,&quot;width&quot;:1302,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:168135,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.faixan.com/i/182058093?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cee48a1-62db-43c2-8e43-5f90c349cd89_1302x884.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!FzLm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cee48a1-62db-43c2-8e43-5f90c349cd89_1302x884.png 424w, https://substackcdn.com/image/fetch/$s_!FzLm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cee48a1-62db-43c2-8e43-5f90c349cd89_1302x884.png 848w, https://substackcdn.com/image/fetch/$s_!FzLm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cee48a1-62db-43c2-8e43-5f90c349cd89_1302x884.png 1272w, https://substackcdn.com/image/fetch/$s_!FzLm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0cee48a1-62db-43c2-8e43-5f90c349cd89_1302x884.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4>read_file</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eBl0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e35ded1-a0d7-4cfa-82f7-600f48b745df_1456x698.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eBl0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e35ded1-a0d7-4cfa-82f7-600f48b745df_1456x698.png 424w, https://substackcdn.com/image/fetch/$s_!eBl0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e35ded1-a0d7-4cfa-82f7-600f48b745df_1456x698.png 848w, https://substackcdn.com/image/fetch/$s_!eBl0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e35ded1-a0d7-4cfa-82f7-600f48b745df_1456x698.png 1272w, https://substackcdn.com/image/fetch/$s_!eBl0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e35ded1-a0d7-4cfa-82f7-600f48b745df_1456x698.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eBl0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e35ded1-a0d7-4cfa-82f7-600f48b745df_1456x698.png" width="1456" height="698" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8e35ded1-a0d7-4cfa-82f7-600f48b745df_1456x698.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:698,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:159822,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.faixan.com/i/182058093?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e35ded1-a0d7-4cfa-82f7-600f48b745df_1456x698.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!eBl0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e35ded1-a0d7-4cfa-82f7-600f48b745df_1456x698.png 424w, https://substackcdn.com/image/fetch/$s_!eBl0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e35ded1-a0d7-4cfa-82f7-600f48b745df_1456x698.png 848w, https://substackcdn.com/image/fetch/$s_!eBl0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e35ded1-a0d7-4cfa-82f7-600f48b745df_1456x698.png 1272w, https://substackcdn.com/image/fetch/$s_!eBl0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e35ded1-a0d7-4cfa-82f7-600f48b745df_1456x698.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Security in Code Execution</h2><p>Code generation and evaluation by LLM Agents brings a huge security risk, where a malicious prompt can perform unwanted activities on the system.</p><p>I devised 4 layers of security to reduce chances of malicious code execution.</p><p><strong>Layer 1</strong> - Guard rails in the system prompt to disallow importing/aliasing of other modules or accepting <strong>```elixir</strong> tag code.</p><p><strong>Layer 2</strong> - Make sure all functions being called accept Auth Scope so that the actions are performed within that organisation or tenant. Use <strong>%MyApp.Accounts.Scope{}</strong> pattern on the function call signatures.</p><p><strong>Layer 3</strong> - Wrap the generated code inside an anonymous function to provide Scope thus making sure that scope can be passed by the the code executor and not defined during code generation.</p><p><strong>Layer 4</strong> - Sandbox the generated code using <a href="https://hexdocs.pm/dune/Dune.html">Dune</a> and maintain a strict allow list. Dune does not allow creating of structs which means that <strong>%Scope{}</strong> cannot be called and can only be passed by executor.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_eul!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30c18472-6699-42a1-89d8-a4f3ee488b0c_1774x660.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_eul!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30c18472-6699-42a1-89d8-a4f3ee488b0c_1774x660.png 424w, https://substackcdn.com/image/fetch/$s_!_eul!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30c18472-6699-42a1-89d8-a4f3ee488b0c_1774x660.png 848w, https://substackcdn.com/image/fetch/$s_!_eul!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30c18472-6699-42a1-89d8-a4f3ee488b0c_1774x660.png 1272w, https://substackcdn.com/image/fetch/$s_!_eul!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30c18472-6699-42a1-89d8-a4f3ee488b0c_1774x660.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_eul!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30c18472-6699-42a1-89d8-a4f3ee488b0c_1774x660.png" width="1456" height="542" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/30c18472-6699-42a1-89d8-a4f3ee488b0c_1774x660.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:542,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:139841,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.faixan.com/i/182058093?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30c18472-6699-42a1-89d8-a4f3ee488b0c_1774x660.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!_eul!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30c18472-6699-42a1-89d8-a4f3ee488b0c_1774x660.png 424w, https://substackcdn.com/image/fetch/$s_!_eul!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30c18472-6699-42a1-89d8-a4f3ee488b0c_1774x660.png 848w, https://substackcdn.com/image/fetch/$s_!_eul!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30c18472-6699-42a1-89d8-a4f3ee488b0c_1774x660.png 1272w, https://substackcdn.com/image/fetch/$s_!_eul!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30c18472-6699-42a1-89d8-a4f3ee488b0c_1774x660.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.faixan.com/p/agentic-code-execution-instead-of?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.faixan.com/p/agentic-code-execution-instead-of?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.faixan.com/p/agentic-code-execution-instead-of/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.faixan.com/p/agentic-code-execution-instead-of/comments"><span>Leave a comment</span></a></p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.faixan.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Faizan&#8217;s Blog! Subscribe for free to receive new posts and support my w</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[Project: Driven by Optimism | Hyundai]]></title><description><![CDATA[How we customised a car to drive using Brain Computer Interface (BCI)]]></description><link>https://www.faixan.com/p/project-driven-by-optimism-hyundai</link><guid isPermaLink="false">https://www.faixan.com/p/project-driven-by-optimism-hyundai</guid><dc:creator><![CDATA[Faizan Naqvi]]></dc:creator><pubDate>Sun, 30 Jan 2022 14:58:25 GMT</pubDate><enclosure url="https://cdn.substack.com/image/fetch/h_600,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0be3413a-92bb-47e7-b7a4-d142a59f8aa1_3264x1836.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In April 2016, my friend Matt (founder of <a href="http://thealphabetcollective.com/">TheAlphabetCollective</a>), bumped into an old work acquaintance on the train. During catching up, the acquaintance mentioned about an advertising agency that was looking for a team to customise <strong>a car to be controlled by brain activity</strong>. This was for a campaign by Hyundai about promoting positivity. My friend asked me for help on the project. I am usually very confident (somewhat delusional) about my tech skills and instantly agreed to work on it.</p><p>This project made us nervous as <strong>safety of the passengers</strong> was of extreme importance. The nervousness was amplified by a hard deadline of <strong>6 weeks</strong> after which the video shooting had to be done. The issue of tight deadlines is very common for most experiential projects. The creative teams usually take a lot of time in refining and negotiating which leaves very little time for the actual execution ( Or may be they just like to see us suffer). </p><p>We quickly went into action and started planning the development.</p><h2>Quest to find a BCI device</h2><p>Our first challenge was finding a BCI device that we could easily program. Neither of us had ever worked with a BCI (Brain Computer Interface) device and it was our understanding that they are pretty expensive to purchase. </p><h3>EMOTIV to the rescue</h3><p>We googled for affordable BCI devices and within a short time found out about <strong><a href="https://www.emotiv.com">EMOTIV</a></strong>. The pricing was reasonable, around 300 USD for <a href="https://www.emotiv.com/insight/">EMOTIV insight product</a>. EMOTIV was fairly new at that time, just out of <a href="https://www.kickstarter.com/projects/tanttle/emotiv-insight-optimize-your-brain-fitness-and-per">kickstarter</a>. I quickly read the SDK documentation and decided to go for EMOTIV.</p><p>We ordered 5 of EMOTIV Insight devices. 2 of those were delivered to me in Amsterdam while the other 3 went to TheAlphabetCollective in London.</p><h2>Mock it till you make it</h2><p>As there was going to be some lead time in the delivery of devices, we started working on the code and hardware assembly by simulating the BCI device. In other words, made more buttons and notches in the UI :)</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!P6Ch!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F69690608-e4e2-4e33-8485-6db78451a957_1140x200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!P6Ch!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F69690608-e4e2-4e33-8485-6db78451a957_1140x200.png 424w, https://substackcdn.com/image/fetch/$s_!P6Ch!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F69690608-e4e2-4e33-8485-6db78451a957_1140x200.png 848w, https://substackcdn.com/image/fetch/$s_!P6Ch!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F69690608-e4e2-4e33-8485-6db78451a957_1140x200.png 1272w, https://substackcdn.com/image/fetch/$s_!P6Ch!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F69690608-e4e2-4e33-8485-6db78451a957_1140x200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!P6Ch!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F69690608-e4e2-4e33-8485-6db78451a957_1140x200.png" width="1140" height="200" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/69690608-e4e2-4e33-8485-6db78451a957_1140x200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:200,&quot;width&quot;:1140,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:11920,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!P6Ch!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F69690608-e4e2-4e33-8485-6db78451a957_1140x200.png 424w, https://substackcdn.com/image/fetch/$s_!P6Ch!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F69690608-e4e2-4e33-8485-6db78451a957_1140x200.png 848w, https://substackcdn.com/image/fetch/$s_!P6Ch!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F69690608-e4e2-4e33-8485-6db78451a957_1140x200.png 1272w, https://substackcdn.com/image/fetch/$s_!P6Ch!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F69690608-e4e2-4e33-8485-6db78451a957_1140x200.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Major components of the system </figcaption></figure></div><p></p><h3>Arduino and Actuators</h3><p>Matt took care of the hardware. He procured actuators that were more powerful than needed and could possibly destroy the car. I guess he didn&#8217;t listen to the advice from Spiderman&#8217;s uncle about power and responsibility. He connected those actuators to Arduino controller, which sends the commands on the serial port.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xOKc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F00033702-93e3-4146-a1ee-74d601895027_3264x1836.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xOKc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F00033702-93e3-4146-a1ee-74d601895027_3264x1836.jpeg 424w, https://substackcdn.com/image/fetch/$s_!xOKc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F00033702-93e3-4146-a1ee-74d601895027_3264x1836.jpeg 848w, https://substackcdn.com/image/fetch/$s_!xOKc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F00033702-93e3-4146-a1ee-74d601895027_3264x1836.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!xOKc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F00033702-93e3-4146-a1ee-74d601895027_3264x1836.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xOKc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F00033702-93e3-4146-a1ee-74d601895027_3264x1836.jpeg" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/00033702-93e3-4146-a1ee-74d601895027_3264x1836.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1860188,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xOKc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F00033702-93e3-4146-a1ee-74d601895027_3264x1836.jpeg 424w, https://substackcdn.com/image/fetch/$s_!xOKc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F00033702-93e3-4146-a1ee-74d601895027_3264x1836.jpeg 848w, https://substackcdn.com/image/fetch/$s_!xOKc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F00033702-93e3-4146-a1ee-74d601895027_3264x1836.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!xOKc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F00033702-93e3-4146-a1ee-74d601895027_3264x1836.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Actuators on the table with EMOTIV headsets in the background. Arduino with switches just on the right side of the actuators with green lights.</figcaption></figure></div><h3>Software for BCI</h3><p>My part was to write the software for interaction with the BCI device and the Arduino controller. We had a few Windows laptops lying around from previous jobs and decided to aim for Windows OS. I decided to go with <strong>Python</strong> as a language for faster development, plus EMOTIV SDK support for Python was excellent. We also wanted to create a GUI control panel for manual safety overrides and visualisation of the overall working of the software (e.g., actuator position, BCI metrics). The UI framework seemed a bit tricky to get <s>it</s> right at first but I settled on <strong><a href="https://www.wxpython.org/">wxPython</a></strong> framework. In retrospect, I would not choose Python for such a realtime application due to Python <strong><a href="https://realpython.com/python-gil/#the-impact-on-multi-threaded-python-programs">GIL</a></strong>. I ended up using queues to get some level of concurrency and a responsive UI. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YuNv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe958fa81-2302-462c-8e85-bbe0ac46d219_3264x1836.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YuNv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe958fa81-2302-462c-8e85-bbe0ac46d219_3264x1836.jpeg 424w, https://substackcdn.com/image/fetch/$s_!YuNv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe958fa81-2302-462c-8e85-bbe0ac46d219_3264x1836.jpeg 848w, https://substackcdn.com/image/fetch/$s_!YuNv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe958fa81-2302-462c-8e85-bbe0ac46d219_3264x1836.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!YuNv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe958fa81-2302-462c-8e85-bbe0ac46d219_3264x1836.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YuNv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe958fa81-2302-462c-8e85-bbe0ac46d219_3264x1836.jpeg" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/e958fa81-2302-462c-8e85-bbe0ac46d219_3264x1836.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1708685,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!YuNv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe958fa81-2302-462c-8e85-bbe0ac46d219_3264x1836.jpeg 424w, https://substackcdn.com/image/fetch/$s_!YuNv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe958fa81-2302-462c-8e85-bbe0ac46d219_3264x1836.jpeg 848w, https://substackcdn.com/image/fetch/$s_!YuNv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe958fa81-2302-462c-8e85-bbe0ac46d219_3264x1836.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!YuNv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fe958fa81-2302-462c-8e85-bbe0ac46d219_3264x1836.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A screenshot of the Python based GUI panel</figcaption></figure></div><h3>Safety concerns</h3><p>Safety was of high importance as we couldn&#8217;t risk car going out of control if software misbehaved. We created 4 levels of failsafes.</p><ol><li><p>Bake/Release buttons on the GUI on the Windows laptop that would release accelerator and press the brake.</p></li><li><p>A bigger reset button on the Arduino.</p></li><li><p>A switch that sat between Arduino and Actuators.</p></li><li><p>Lastly, the rig with actuators could be released manually with one hand.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tP-r!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0be3413a-92bb-47e7-b7a4-d142a59f8aa1_3264x1836.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tP-r!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0be3413a-92bb-47e7-b7a4-d142a59f8aa1_3264x1836.jpeg 424w, https://substackcdn.com/image/fetch/$s_!tP-r!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0be3413a-92bb-47e7-b7a4-d142a59f8aa1_3264x1836.jpeg 848w, https://substackcdn.com/image/fetch/$s_!tP-r!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0be3413a-92bb-47e7-b7a4-d142a59f8aa1_3264x1836.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!tP-r!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0be3413a-92bb-47e7-b7a4-d142a59f8aa1_3264x1836.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tP-r!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0be3413a-92bb-47e7-b7a4-d142a59f8aa1_3264x1836.jpeg" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/0be3413a-92bb-47e7-b7a4-d142a59f8aa1_3264x1836.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2222839,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tP-r!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0be3413a-92bb-47e7-b7a4-d142a59f8aa1_3264x1836.jpeg 424w, https://substackcdn.com/image/fetch/$s_!tP-r!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0be3413a-92bb-47e7-b7a4-d142a59f8aa1_3264x1836.jpeg 848w, https://substackcdn.com/image/fetch/$s_!tP-r!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0be3413a-92bb-47e7-b7a4-d142a59f8aa1_3264x1836.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!tP-r!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0be3413a-92bb-47e7-b7a4-d142a59f8aa1_3264x1836.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Actuators below the steering wheel for brake &amp; acceleration</figcaption></figure></div><h2>If bugs could kill</h2><p>Once the simulated code was completed, I flew a few days before the event to test integration with real actuators. While testing we realised that every few minutes the actuators went crazy and pushed their full length of 12 cm out. If we had tested with a real car, it would have <strong>accelerated to max</strong> which could have threatened the life of the passengers. Luckily, we figured out the issue quickly. Apparently, we were sending commands to the actuators faster than they could accept on the serial bitrate. This caused corruption of data on the serial port towards actuators. We fixed it by making Python code wait for an <strong>ACK</strong> from the Arduino code before sending the next accelerate/brake value.</p><h2>Shooting day </h2><p>Shooting took place at an airfield. We configured <strong>2 cars</strong>, a day before the shooting and drove them around with the power of our minds. Even though, we knew how the whole system worked, it was still a very strange feeling in the stomach when car moved on its own due to our focus.</p><p>We had a separate rig on a table to train the talent (advertising term for the main characters) on the system before sitting in the car. The rest of the shooting went well and we had a lot of fun.</p><div id="youtube2-ugxrh_VXT3U" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;ugxrh_VXT3U&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/ugxrh_VXT3U?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div>]]></content:encoded></item><item><title><![CDATA[Project: Android Wall ]]></title><description><![CDATA[How we built a display wall consisting of 140 android devices from TV to smart watches]]></description><link>https://www.faixan.com/p/project-android-wall</link><guid isPermaLink="false">https://www.faixan.com/p/project-android-wall</guid><dc:creator><![CDATA[Faizan Naqvi]]></dc:creator><pubDate>Fri, 11 Jun 2021 15:10:05 GMT</pubDate><enclosure url="https://substackcdn.com/image/vimeo/w_728,c_limit,d_video_placeholder.png/337390169" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div id="vimeo-337390169" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;337390169&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:false}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/337390169?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true"></iframe></div></div><p></p><h1>How it all started?</h1><p>I occasionally help my friend Matt from TheAlphabetCollective agency/studio in their experiential marketing projects. In 2019 they were asked via BrandFuel to help build one of the Android installations for MobileWorldCongress in Barcelona. My friends asked me if I could help in building the software side.</p><p>The requirement of the project was to play a video in loop on <strong>~140 devices</strong> during the whole of MWC 2019 event that lasted for 4 days.  The videos had to be switched between day and night. </p><p>We had about 2 months to build out the software, hardware and the frame to place all the devices. A friend designed the iron rig and it was assembled by us at the convention. This images shows the rig assembled and being installed.</p><p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qVnY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca0b2bb-5f76-41b1-89bc-e8342a4f9feb" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qVnY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca0b2bb-5f76-41b1-89bc-e8342a4f9feb 424w, https://substackcdn.com/image/fetch/$s_!qVnY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca0b2bb-5f76-41b1-89bc-e8342a4f9feb 848w, https://substackcdn.com/image/fetch/$s_!qVnY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca0b2bb-5f76-41b1-89bc-e8342a4f9feb 1272w, https://substackcdn.com/image/fetch/$s_!qVnY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca0b2bb-5f76-41b1-89bc-e8342a4f9feb 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qVnY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca0b2bb-5f76-41b1-89bc-e8342a4f9feb" width="1456" height="1092" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/8ca0b2bb-5f76-41b1-89bc-e8342a4f9feb&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1092,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1571846,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qVnY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca0b2bb-5f76-41b1-89bc-e8342a4f9feb 424w, https://substackcdn.com/image/fetch/$s_!qVnY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca0b2bb-5f76-41b1-89bc-e8342a4f9feb 848w, https://substackcdn.com/image/fetch/$s_!qVnY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca0b2bb-5f76-41b1-89bc-e8342a4f9feb 1272w, https://substackcdn.com/image/fetch/$s_!qVnY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8ca0b2bb-5f76-41b1-89bc-e8342a4f9feb 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Team installing the assembled rig.</figcaption></figure></div><h1>Challenges and Solutions</h1><p>We knew right from the start that this was not going to be an easy project. My friend and I come from a telecom background. We built together long-range WiFi to GSM networks as well as media distribution systems. </p><p>We faced following technical challenges during the project.</p><h2>1 - Fragmented Android Devices and OS versions:</h2><p>We were given a list of android devices that included Android TV, Tablets, Smart Phones and Smart Watches. The devices were from various manufacturers including Huawei, Samsung, Nokia, LG, Xiaomi, Motorola and a few other lesser known brands.</p><p>Android is a highly fragmented platform and we knew this was going to be a problem for software development.</p><h4>Solution: Android SDK 7</h4><p>We decided early on that we will have to build apps using Android SDK instead of going with ReactNative or Xamarin like tools to stay close to the OS to be able to support devices even if it meant creating various versions. A good thing about these projects is that they are short lived and you don&#8217;t have to support it for years to come. We also constrained our android app to Android 7 (API level 24) to support all the devices.</p><p>We ended up creating only 3 versions of the app mainly due to UI differences all in the same project with different UI code. TV, Mobile and SmartWatch.</p><p>Here is a picture of software displaying DEBUG screen.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xgrg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9d19cb0c-153c-45cc-ae00-47c16eef774e_1920x1080.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xgrg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9d19cb0c-153c-45cc-ae00-47c16eef774e_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!xgrg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9d19cb0c-153c-45cc-ae00-47c16eef774e_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!xgrg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9d19cb0c-153c-45cc-ae00-47c16eef774e_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!xgrg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9d19cb0c-153c-45cc-ae00-47c16eef774e_1920x1080.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xgrg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9d19cb0c-153c-45cc-ae00-47c16eef774e_1920x1080.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/9d19cb0c-153c-45cc-ae00-47c16eef774e_1920x1080.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3704310,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xgrg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9d19cb0c-153c-45cc-ae00-47c16eef774e_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!xgrg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9d19cb0c-153c-45cc-ae00-47c16eef774e_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!xgrg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9d19cb0c-153c-45cc-ae00-47c16eef774e_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!xgrg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9d19cb0c-153c-45cc-ae00-47c16eef774e_1920x1080.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Matt debugging network connectivity. We could show debug display of any device via a remote command.</figcaption></figure></div><h2>2 - Connectivity</h2><p>We knew from previous experience that connectivity provided by the venues in such events is never stable enough for a realtime application. </p><h4>Solution - Our own LAN</h4><p>We decided to build our own local network. We checked all devices that we could connect via ethernet and the rest had to go on WiFi. We created 3 networks with a mix of WiFi and LAN to provide reliability and capacity for all the devices.</p><h2>3 - Content delivery to the devices</h2><p>The playback on all devices had to be in sync to create a unified bigger screen effect. We went through a few approaches to get the best result.</p><h4>Discarded Solution - WebRTC(RTSP) playback</h4><p>We discussed for a while the possibility to stream videos to the phones using WebRTC or RTSP streaming. In this approach, the devices would connect to the streaming server on the LAN network and stream videos realtime. We discarded this initial idea as we were concerned about the connection reliability of the devices on WiFi. Moreover, the videos had to be played in a loop and if one device started a second later to play the video due to its Hardware speed, the video would have been off by a second and over time, would have gone completely out of sync. </p><h4>Solution - Pre-loaded files</h4><p>We decided to pre-load video files on the devices as they were not going to change that often. We also decided that we would get the videos cropped for each device for its position on the grid. This way the video size would be smaller and software would not have to crop the video realtime/offline. This info was provided to our video editing partner who created the grid in Unity3D to crop and export the videos.</p><h2>4 - Playback position deviation</h2><p>We had the local files playback idea but we still had to make sure that devices played files synchronously and didn&#8217;t deviate over time. </p><h4><br>Solution - Central Synchronisation Server</h4><p>The solution was simply to fake video playback with a timer on the server and broadcast the expected frame of the video to all the devices. Devices would then seek the playback to the correct position. If it is done consistently the users would not see the difference. The accepted deviation in the playback of all the devices was set to within 50-100ms.</p><p>This server also acted as web server and controller of devices allowing us to upload new videos with a single command and switch between night/day videos.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-PyX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4eeff3e-938b-4c86-88a5-eb2ad99d73d9" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-PyX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4eeff3e-938b-4c86-88a5-eb2ad99d73d9 424w, https://substackcdn.com/image/fetch/$s_!-PyX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4eeff3e-938b-4c86-88a5-eb2ad99d73d9 848w, https://substackcdn.com/image/fetch/$s_!-PyX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4eeff3e-938b-4c86-88a5-eb2ad99d73d9 1272w, https://substackcdn.com/image/fetch/$s_!-PyX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4eeff3e-938b-4c86-88a5-eb2ad99d73d9 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-PyX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4eeff3e-938b-4c86-88a5-eb2ad99d73d9" width="1456" height="1092" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/f4eeff3e-938b-4c86-88a5-eb2ad99d73d9&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1092,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1369612,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-PyX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4eeff3e-938b-4c86-88a5-eb2ad99d73d9 424w, https://substackcdn.com/image/fetch/$s_!-PyX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4eeff3e-938b-4c86-88a5-eb2ad99d73d9 848w, https://substackcdn.com/image/fetch/$s_!-PyX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4eeff3e-938b-4c86-88a5-eb2ad99d73d9 1272w, https://substackcdn.com/image/fetch/$s_!-PyX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4eeff3e-938b-4c86-88a5-eb2ad99d73d9 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Laptop on the left was our server for synchronisation and control of devices</figcaption></figure></div><h2>5 - Device Time</h2><p>It seemed simple at first to just <strong>broadcast</strong> a packet to the devices forcing them to seek but not all packets would reach the devices the same time. This meant that network latency even local could affect the playback as a device reading the packet after 1 second would seek 1 second later and hence will be always behind. </p><h4>Solution - NTP</h4><p>We added timestamp of the server to each playback position broadcast packet. This meant that now devices could calculate the latency and account for that in the playback seek. This could only work if all the devices had their timing synced from a single source. We noticed that Android devices had a few seconds time skew. We decided to setup NTP server on the same synchronisation server and make sure that devices used it to sync their timing. Android (at that time at least) didn&#8217;t have the option to set custom NTP server and we ended up using <a href="https://github.com/instacart/truetime-android">TrueTime</a> library for this.</p><h2>6 - Transport protocol for broadcasting</h2><p>Early on it seemed plausible to just use <a href="https://en.wikipedia.org/wiki/Broadcast_address">UDP broadcast</a> from server to send the new position to all of the devices. This proved very difficult due to different versions of OS and security implementation by manufacturers.</p><h4>Solution - TCP sockets with Actor Model</h4><p>After all failed with UDP, we decided that TCP sockets were the best way to manage devices. The devices would act as clients and connect to the synchronisation server configured in the app. We decided to use <strong><a href="https://golang.org/">GO</a></strong> as the language for the server side.  To keep track of the devices connected we decided to use <strong><a href="https://proto.actor/">Proto.Actor</a></strong> framework. This way we got the goodness of supervisors and stateful actors to manage each device&#8217;s life cycle.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JuVB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff75cbe90-123b-457e-9039-341eea440a3b_471x541.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JuVB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff75cbe90-123b-457e-9039-341eea440a3b_471x541.png 424w, https://substackcdn.com/image/fetch/$s_!JuVB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff75cbe90-123b-457e-9039-341eea440a3b_471x541.png 848w, https://substackcdn.com/image/fetch/$s_!JuVB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff75cbe90-123b-457e-9039-341eea440a3b_471x541.png 1272w, https://substackcdn.com/image/fetch/$s_!JuVB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff75cbe90-123b-457e-9039-341eea440a3b_471x541.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JuVB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff75cbe90-123b-457e-9039-341eea440a3b_471x541.png" width="471" height="541" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/f75cbe90-123b-457e-9039-341eea440a3b_471x541.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:541,&quot;width&quot;:471,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:41307,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!JuVB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff75cbe90-123b-457e-9039-341eea440a3b_471x541.png 424w, https://substackcdn.com/image/fetch/$s_!JuVB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff75cbe90-123b-457e-9039-341eea440a3b_471x541.png 848w, https://substackcdn.com/image/fetch/$s_!JuVB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff75cbe90-123b-457e-9039-341eea440a3b_471x541.png 1272w, https://substackcdn.com/image/fetch/$s_!JuVB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff75cbe90-123b-457e-9039-341eea440a3b_471x541.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>7 - Irregular Keyframe positions in the video</h2><p>Video encoders optimise the video size by placing <a href="https://en.wikipedia.org/wiki/Key_frame">keyframes</a> only when necessary. We realised that seek function tries to seek to the closest keyframe instead of the exact location specified. This caused the videos on devices to go out of sync by a second or more, sometimes. </p><h4>Solution - Export videos with consistent keyframes</h4><p>We requested our video editing partner to export keyframes at consistent positions ignoring the size optimisation. We didn&#8217;t care about the size as we were going to pre-load the videos anyway. This was the last key in keeping video playbacks synchronised.</p><h1>Final Result</h1><p>It took us about 3 days of working 16 hours at the site to assemble and test the whole system.</p><p>This is how it looked like at 4 am before the event in the morning.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!41T-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fca21992b-6fd5-4bad-b395-c150d88f6519_1920x1080.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!41T-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fca21992b-6fd5-4bad-b395-c150d88f6519_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!41T-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fca21992b-6fd5-4bad-b395-c150d88f6519_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!41T-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fca21992b-6fd5-4bad-b395-c150d88f6519_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!41T-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fca21992b-6fd5-4bad-b395-c150d88f6519_1920x1080.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!41T-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fca21992b-6fd5-4bad-b395-c150d88f6519_1920x1080.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/ca21992b-6fd5-4bad-b395-c150d88f6519_1920x1080.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2616869,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!41T-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fca21992b-6fd5-4bad-b395-c150d88f6519_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!41T-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fca21992b-6fd5-4bad-b395-c150d88f6519_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!41T-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fca21992b-6fd5-4bad-b395-c150d88f6519_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!41T-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fca21992b-6fd5-4bad-b395-c150d88f6519_1920x1080.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Finished display at 4 am just the day before the event</figcaption></figure></div><h1>TL;DR</h1><p>Built app for  Android 7 the lowest supported Android OS on the devices.</p><p>Own private network with mostly Ethernet for connectivity.</p><p>Pre-loaded files on the devices pushed using the central server also running on the LAN.</p><p>Used TCP sockets instead of <a href="https://en.wikipedia.org/wiki/Broadcast_address">UDP broadcast</a>. </p><p>GO with Proto.Actor for synchronisation server.</p><p>Local NTP server for device time synchronisation.</p><p>Consistent keyframes in the video.</p><p>Expected playback position broadcast from sync server to all the devices to keep videos in sync.</p><p><a href="http://thealphabetcollective.com/portfolio/android-mwc">Business Case Study and Pictures.</a></p>]]></content:encoded></item></channel></rss>