<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Ywmaa</title><description>Blog</description><link>https://ywmaa.com/</link><language>en</language><item><title>Arduino Project with VR in Godot Engine</title><link>https://ywmaa.com/posts/electronics/electronicselectiveproject/</link><guid isPermaLink="true">https://ywmaa.com/posts/electronics/electronicselectiveproject/</guid><pubDate>Mon, 17 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The topic of the elective was studying electronics:
Arduino &amp;amp; electronic circuits and connecting them to a
game engine.&lt;/p&gt;
&lt;p&gt;My personal project was a co-op multiplayer game between
a VR Player &amp;amp; an Arduino Controller player.&lt;/p&gt;
&lt;p&gt;see the project showcase:
&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/wEXuCHEjK7I?si=h_A4G9F655Ge9FGX&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h3&gt;The Idea&lt;/h3&gt;
&lt;p&gt;The idea behind the project is to make a fun co-op game in Godot Engine, were two players are
connected in one multiplayer session to do survival-tower-defense game, one player plays as a VR
shooter and the other is the command center operator who is responsible for tactically fortifying the
base and helping the player increase damage by matching the tesseract cube color with the enemies
color, which will change the shooter player’s gun color to match the tesseract and so cause more
damage and faster elimination of enemies.&lt;/p&gt;
&lt;p&gt;The command center operator uses the connected Arduino-Board as their control keys/switches, and
they only observe the game and control it through the controller board.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://ywmaa.com/assets/images/ElectronicsElectiveProject/ElectronicsProjectShowcase.mp4-00:01:09.767.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Appendix&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://ywmaa.com/assets/images/ElectronicsElectiveProject/ElectronicsProjectShowcase.mp4-00:00:40.867.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;https://ywmaa.com/assets/images/ElectronicsElectiveProject/ElectronicsProjectShowcase.mp4-00:00:42.700.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;https://ywmaa.com/assets/images/ElectronicsElectiveProject/ElectronicsProjectShowcase.mp4-00:01:37.800.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;!--&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/images/∃InShadows∧Mist.png&quot;&amp;gt;
&amp;lt;/img&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/UeEvyWYLxvs&quot; frameborder=&quot;0&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;p&gt;--&amp;gt;&lt;/p&gt;
</content:encoded><category>Electronics</category><category>Electronics</category><category>Embedded</category><category>Arduino</category><category>VR</category><category>GodotEngine</category></item><item><title>AR Project in Unity Engine</title><link>https://ywmaa.com/posts/xr/arproject/</link><guid isPermaLink="true">https://ywmaa.com/posts/xr/arproject/</guid><pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This is our semester 4 AR experience -made in unity- for
the Geo-Naturpark Odenwald.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://ywmaa.com/assets/images/P4ARProject/OdenwaldMap.png&quot; alt=&quot;Odenwald Map&quot; /&gt;&lt;/p&gt;
&lt;p&gt;For visitors of Odenwald who are interested in local history &amp;amp; culture.&lt;/p&gt;
&lt;p&gt;Quest Track&lt;/p&gt;
&lt;p&gt;Is a mobile AR-app
That guides their exploration of Odenwald
By turning local folklore into a real-world, interactive puzzle quest
In order to encourage mindful exploration &amp;amp; highlight the natural &amp;amp; cultural
richness of Odenwald.
As opposed to other AR-maps &amp;amp; -puzzle games, Quest Track grounds the
experience within the local geography and culture of Odenwald.&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/images/P4ARProject/image4.png&quot; alt=&quot;In-Game Odenwald Map&quot; width=&quot;350&quot; &amp;gt;&amp;lt;i&amp;gt; In-Game Odenwald Map&amp;lt;/i&amp;gt;&amp;lt;/img&amp;gt;
&amp;lt;img src=&quot;/assets/images/P4ARProject/tlTsuCfS.jpg&quot; alt=&quot;AR Anamorphic Puzzle&quot; width=&quot;350&quot; &amp;gt;&amp;lt;i&amp;gt; AR Anamorphic Puzzle&amp;lt;/i&amp;gt;&amp;lt;/img&amp;gt;
&amp;lt;img src=&quot;/assets/images/P4ARProject/uJ4zHY5P.jpg&quot; alt=&quot;AR Anamorphic Puzzle from correct perspective&quot; width=&quot;350&quot; &amp;gt;&amp;lt;i&amp;gt; AR Anamorphic Puzzle from correct perspective&amp;lt;/i&amp;gt;&amp;lt;/img&amp;gt;&lt;/p&gt;
&lt;h2&gt;Techincal Basis:&lt;/h2&gt;
&lt;p&gt;notes and documentation of the technical background I worked on&lt;/p&gt;
&lt;h4&gt;Geopark Map GPS&lt;/h4&gt;
&lt;p&gt;The positioning of player location in the in-game map is calculated through
mapping from (GPS to GPS locations) to (virtual map point to another virtual point)
using custom written mapping functions in C# code. And the real player position is
also calculated the same way with a reference central point in the virtual map,
which acts as the point of reference or “origin point of the 2D axis”. The GPS data is
received directly from Geospatial API.&lt;/p&gt;
&lt;h4&gt;Image Recognition&lt;/h4&gt;
&lt;p&gt;It was considered at some point for the project to use Image Recognition in AR to
register and align the experience puzzles and games as a replacement for the
Geospatial setup since Geospatial is prone to problems like: hard to calibrate
outside urban spaces and requires GPS module in the device (which the Meta Quest
doesn’t have).
But after some research it was discovered that the Meta Quest doesn’t also support
image recognition by default and the other option for it is to use a paid plugin that
utilizes OpenCV, which wasn’t suitable for this project&apos;s resource limitations. Thus,
the decision was made to move forward without utilizing Image recognition as it
won’t add much compared to the Geospatial setup which the project already
utilizes.&lt;/p&gt;
&lt;h4&gt;Cross-device Geospatial Anchor Sharing&lt;/h4&gt;
&lt;p&gt;At the very early stages of development there was this idea of making the android
phone of the user share the geospatial anchors and current pose to the Meta Quest
if they are on the same network (Wifi/Hotspot). And there are scripts which can do
that in the project, yet it wasn’t utilized later, as the scope of the Meta Quest version
of the app got scaled down in its development compared to the mobile phone to
reduce development burden and reduce having to go through many workarounds
just to make both experiences match, thus it was preferred to maintain focus on the
app experience itself rather than perfect cross-platform symmetry, and design the
experience on each platform (Mobile/Meta Quest) to be within the limits of the
target platform.&lt;/p&gt;
&lt;h4&gt;Cross-device Geospatial Anchor Sharing&lt;/h4&gt;
&lt;p&gt;The scripts operate on a simple logic:
1 – The sender script only exists on the phone, once Geopose is grabbed from the
Geospatial Plugin in Unity, it formats it in a string format, then sends it using UDP
as bytes.&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/images/P4ARProject/Screenshot from 2026-08-03 03-55-26.png&quot; alt=&quot; Geospatial sent data payload&quot; width=&quot;350&quot; &amp;gt;&amp;lt;i&amp;gt; Geospatial sent data payload&amp;lt;/i&amp;gt;&amp;lt;/img&amp;gt;&lt;/p&gt;
&lt;p&gt;2 – On the receiver’s end they keep listening to the same UDP port and once new
bytes are received, they are decoded and written into a GeoPose custom class that
mainly hosts information of Geospatial Pose.&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/images/P4ARProject/Screenshot from 2026-08-03 03-57-22.png&quot; alt=&quot;Geospatial Pose Receiver&quot; width=&quot;350&quot; &amp;gt;&amp;lt;i&amp;gt;Geospatial Pose Receiver&amp;lt;/i&amp;gt;&amp;lt;/img&amp;gt;&lt;/p&gt;
&lt;h4&gt;Meta Quest Version&lt;/h4&gt;
&lt;p&gt;The Meta Quest version of the app is a scaled down experience, the Quest version
serves as an introductory/tutorial for the experience that can be used at
home/stationary space, where only one puzzle gets spawned which is the rubik-like
map puzzle around the player/user and they can have a trial of the puzzle. it doesn’t
use any GPS data or things which the Quest doesn’t support, it only utilizes the
regular Unity AR Foundation backend for the Quest.&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/images/P4ARProject/Screenshot from 2026-08-03 19-07-12.png&quot; alt=&quot;Meta Quest Version&quot; width=&quot;350&quot; &amp;gt;&amp;lt;i&amp;gt;Meta Quest Version&amp;lt;/i&amp;gt;&amp;lt;/img&amp;gt;&lt;/p&gt;
&lt;h4&gt;Map Location Tracking&lt;/h4&gt;
&lt;p&gt;Map tracking utilizes Geospatial-Data that are already stored and given in a
Geospatial-Pose and then that is fed into the map location mapping from GPS to
Virtual Map functions as mentioned before:
“The GPS in the Virtual Map is calculated through mapping from GPS to GPS
locations to Virtual map point to another virtual point from custom written mapping
functions in C# Code...&quot;&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/images/P4ARProject/Screenshot from 2026-08-05 03-04-24.png&quot; alt=&quot;Map Tracking Logic Detail&quot; width=&quot;350&quot; &amp;gt;&amp;lt;i&amp;gt;Map Tracking Logic Detail&amp;lt;/i&amp;gt;&amp;lt;/img&amp;gt;&lt;/p&gt;
&lt;p&gt;Each point in the 3D reconstructed virtual map has its own script
(LocationMarker.cs) that includes data about its real longitude &amp;amp; latitude which is
used to remap the GPS data from real life to that local coordinates and smaller
size/distances. So these data are also used and fed into the remapping functions
along with the GPS data.&lt;/p&gt;
&lt;h4&gt;Screenshot Feature&lt;/h4&gt;
&lt;p&gt;With the help of GitHub - yasirkula/UnityNativeGallery, yasirkula/UnityNativeShare
custom Unity plugins, the project includes the feature to take internal screenshot of
the AR Framebuffer excluding the App-UI, or share a screenshot to social media
with the native function available in android so the app behaves like a native
android app.&lt;/p&gt;
&lt;p&gt;There are 3 main scripts that handle the interface to the custom plugins which are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ARObjectScreenshotCapture.cs : responsible for rendering the AR Camera only
and has a function that can save that framebuffer with specified name, it is the
central hook to the screenshot Unity plugin.&lt;/li&gt;
&lt;li&gt;PuzzleScreenshotManager.cs : responsible for hooking puzzle success event
(hooked to the PuzzleEventManager.cs) and triggers an automatic screenshot of
the solved puzzle that stores that special screenshot to show it later on the
Geopark in-game map, to be the unique gallery of achievements for each user.&lt;/li&gt;
&lt;li&gt;ARScreenshotShareAndroid.cs : responsible for capturing the AR scene only (via
ARObjectScreenshotCapture), then opens the native Android share menu with
the captured image attached (via the custom android native share plugin).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/images/P4ARProject/Screenshot from 2026-08-05 03-15-29.png&quot; alt=&quot;ARObjectScreenshotCapture.cs&quot; width=&quot;350&quot; &amp;gt;&amp;lt;i&amp;gt;ARObjectScreenshotCapture.cs&amp;lt;/i&amp;gt;&amp;lt;/img&amp;gt;&lt;/p&gt;
&lt;p&gt;As shown, each script has a single responsibility and communicates with the other
script/s to achieve the desired behaviour:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;User wants a screenshot only → trigger screenshot button → trigger
CaptureScreenshot() in ARObjectScreenshotCapture.cs.&lt;/li&gt;
&lt;li&gt;User solves the puzzle → puzzle solved event trigger →
PuzzleScreenshotManager.cs listens to event trigger → trigger
CaptureScreenshot() in ARObjectScreenshotCapture.cs with unique local image
name to be shown later in the in-game map.&lt;/li&gt;
&lt;li&gt;User wants to share the current screen view → trigger share button → trigger
ARScreenshotShareAndroid.cs → trigger CaptureScreenshot() in
ARObjectScreenshotCapture.cs → triggers OnScreenshotSaved event → triggers
HandleScreenshotSaved in ARScreenshotShareAndroid.cs which uses the
provided image path to share to different applications.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Coroutine Queue System&lt;/h4&gt;
&lt;p&gt;The CoroutineQueue.cs script adds the possibility to queue coroutines as it isn’t
available by default in Unity API. It takes coroutines with assigned keys as
parameters in the Enqueue function and splits each queue in their own group if
they have matching keys in their own queue data structure. Allowing both parallel
queues and sequential queues. This helped with the Narration System as it can
queue narration one after the other easily while waiting for the previous narration
to finish or be skipped/moved forward to start executing the next narration
(execution writes the subtitles and executes the audio). But the system is not
limited to narration as it can be utilized for general usage of coroutine queues.&lt;/p&gt;
&lt;p&gt;The script also allows checking for status of a queue or current running ones or
forcefully skipping the current running coroutine in a specific queue key to the next
coroutine along with its children coroutine (a child coroutine is a coroutine
executed within the coroutine). This helped with the skip narration functionality.&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/images/P4ARProject/Screenshot from 2026-08-03 03-54-41.png&quot; alt=&quot;Skipping function of the CoroutineQueue-Class&quot; width=&quot;350&quot; &amp;gt;&amp;lt;i&amp;gt;Skipping function of the CoroutineQueue-Class&amp;lt;/i&amp;gt;&amp;lt;/img&amp;gt;&lt;/p&gt;
&lt;h4&gt;Final Refactor &amp;amp; Event System&lt;/h4&gt;
&lt;p&gt;At the latest stages of the project development when it was necessary to start
polishing the experience both visually and internally. A lot of refactoring happened,
redesigning how the PuzzleManager.cs handles the events and puzzle solving states
and hooks into other systems like the guidance system, narration events or VFX
triggering.&lt;/p&gt;
&lt;p&gt;It had to be refactored to be single-responsibility to follow the philosophy of how
OOP (Object Oriented Programming) should be written. And thus more scripts were
made to accompany the puzzle manager script such as: PuzzleEventManager.cs ,
PuzzleNarrationController.cs each are now with single-responsibility, and the latter
was used to trigger global events with puzzle success or puzzle spawned/disabled
events. and more UnityEvents were specifically added to the PuzzleManager.cs
itself to allow local events to happen on the puzzle prefab itself and not in the global
scene view (important for easy VFX and SFX triggering), which got used later by the
VFX Designer from the Unity Inspector without having to add any extra code.&lt;/p&gt;
&lt;p&gt;&amp;lt;img src=&quot;/assets/images/P4ARProject/Screenshot from 2026-08-05 02-56-00.png&quot; alt=&quot;Event System Excerpt&quot; width=&quot;350&quot; &amp;gt;&amp;lt;i&amp;gt;Event System Excerpt&amp;lt;/i&amp;gt;&amp;lt;/img&amp;gt;&lt;/p&gt;
&lt;h3&gt;Appendix&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://ywmaa.com/assets/images/P4ARProject/20260709_133120.jpg&quot; alt=&quot;Quest Track&quot; /&gt;
&lt;img src=&quot;https://ywmaa.com/assets/images/P4ARProject/20260709_133647.jpg&quot; alt=&quot;Quest Track&quot; /&gt;
&lt;img src=&quot;https://ywmaa.com/assets/images/P4ARProject/IEoLvkBo.jpg&quot; alt=&quot;Quest Track&quot; /&gt;
&lt;img src=&quot;https://ywmaa.com/assets/images/P4ARProject/image.png&quot; alt=&quot;Quest Track&quot; /&gt;
&lt;img src=&quot;https://ywmaa.com/assets/images/P4ARProject/image1.png&quot; alt=&quot;Quest Track&quot; /&gt;
&lt;img src=&quot;https://ywmaa.com/assets/images/P4ARProject/image2.png&quot; alt=&quot;Quest Track&quot; /&gt;
&lt;img src=&quot;https://ywmaa.com/assets/images/P4ARProject/image3.png&quot; alt=&quot;Quest Track&quot; /&gt;
&lt;img src=&quot;https://ywmaa.com/assets/images/P4ARProject/image5.png&quot; alt=&quot;Quest Track&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Links&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;yasirkula/UnityNativeGallery: A native Unity plugin
to interact with Gallery/Photos on Android &amp;amp; iOS (save and/or load
images/videos). GitHub. https://github.com/yasirkula/UnityNativeGallery&lt;/li&gt;
&lt;li&gt;yasirkula/UnityNativeShare: A Unity plugin to
natively share files (images, videos, documents, etc.) and/or plain text on
Android &amp;amp; iOS. GitHub. https://github.com/yasirkula/UnityNativeShare&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><category>XR</category><category>UnityEngine</category><category>AR</category><category>Meta Quest</category></item><item><title>VR Project in Unity Engine</title><link>https://ywmaa.com/posts/xr/vrproject/</link><guid isPermaLink="true">https://ywmaa.com/posts/xr/vrproject/</guid><pubDate>Sun, 01 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This is our semester 3 trailer for
proposed VR experience -made in unity- for
the Naturmuseum Senckenberg waterbear
creature exhibit.&lt;/p&gt;
&lt;h3&gt;project trailer:&lt;/h3&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/1bqPrOuCyd8?si=cPqGqKXspcdyCbWY&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h3&gt;Appendix&lt;/h3&gt;
&lt;h4&gt;The music composition I made for the project (the one you hear in the trailer)&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://ywmaa.com/assets/images/P3Project/Background_Music_Composition.png&quot; alt=&quot;music composition&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;Laser Gun VFX I made&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://ywmaa.com/assets/images/P3Project/Heatgun%20VFX%201.png&quot; alt=&quot;Laser Gun VFX&quot; /&gt;
&lt;img src=&quot;https://ywmaa.com/assets/images/P3Project/Heatgun%20VFX%202.png&quot; alt=&quot;Laser Gun VFX&quot; /&gt;
&lt;img src=&quot;https://ywmaa.com/assets/images/P3Project/Heatgun%20VFX%203.png&quot; alt=&quot;Laser Gun VFX&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;The Liquid Nitrogen Cup I modeled and textured from scratch in Blender&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://ywmaa.com/assets/images/P3Project/Modeling%20&amp;amp;%20Texturing%20Liquid%20Nitrogen%20Container%201.png&quot; alt=&quot;The Liquid Nitrogen Cup&quot; /&gt;
&lt;img src=&quot;https://ywmaa.com/assets/images/P3Project/Modeling%20&amp;amp;%20Texturing%20Liquid%20Nitrogen%20Container%202%20Closeup.png.png&quot; alt=&quot;The Liquid Nitrogen Cup&quot; /&gt;
&lt;img src=&quot;https://ywmaa.com/assets/images/P3Project/Modeling%20&amp;amp;%20Texturing%20Liquid%20Nitrogen%20Container%202.png.png&quot; alt=&quot;The Liquid Nitrogen Cup&quot; /&gt;
&lt;img src=&quot;https://ywmaa.com/assets/images/P3Project/Modeling%20&amp;amp;%20Texturing%20Liquid%20Nitrogen%20Container%203.png.png&quot; alt=&quot;The Liquid Nitrogen Cup&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;XRay effect with Stencil Buffer Shaders in unity&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://ywmaa.com/assets/images/P3Project/XRay-OutofXRay.png&quot; alt=&quot;XRay effect with Stencil Buffer Shaders&quot; /&gt;
&lt;img src=&quot;https://ywmaa.com/assets/images/P3Project/XRayEffectStencilBuffer.png&quot; alt=&quot;XRay effect with Stencil Buffer Shaders&quot; /&gt;&lt;/p&gt;
</content:encoded><category>XR</category><category>UnityEngine</category><category>VR</category><category>Blender</category><category>Modelling</category><category>Music Composition</category><category>Meta Quest</category></item><item><title>Linux commands I use regularly</title><link>https://ywmaa.com/posts/linux/linuxcommandsiuse/</link><guid isPermaLink="true">https://ywmaa.com/posts/linux/linuxcommandsiuse/</guid><pubDate>Mon, 06 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Commands I use on a regular basis in Linux&lt;/p&gt;
&lt;h1&gt;cd&lt;/h1&gt;
&lt;p&gt;cd means &quot;Change Directory&quot;&lt;/p&gt;
&lt;h4&gt;usage&lt;/h4&gt;
&lt;p&gt;obvious, change directory&lt;/p&gt;
&lt;h4&gt;syntax&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;cd $PATH&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;cd ~/Documents/&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;:::tip
if you write &quot;cd&quot; without path, it will take you to home directory
:::&lt;/p&gt;
&lt;h1&gt;ls&lt;/h1&gt;
&lt;p&gt;list files and directories&lt;/p&gt;
&lt;h4&gt;syntax&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;ls $PATH&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;ls ~/Documents/&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;or just write it without any path to execute it on current location&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ls&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;:::tip
ls -la is a useful command to list all files and directories including hidden ones.
:::&lt;/p&gt;
&lt;h1&gt;mv&lt;/h1&gt;
&lt;p&gt;move file or directory&lt;/p&gt;
&lt;h4&gt;syntax&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;mv PATH NEW_PATH&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;mv file.txt ~/Documents/file.txt&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;mv directory/ ~/Documents/new_directory_location/&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;:::tip
or can be also used to rename a file or folder&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;mv file.txt new_file.txt
:::&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;rm&lt;/h1&gt;
&lt;p&gt;remove file or directory&lt;/p&gt;
&lt;h4&gt;syntax&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;rm $PATH&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;rm file.txt&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;rm directory/&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;sudo rm -rf&lt;/h3&gt;
&lt;p&gt;even though it&apos;s dangerous, it&apos;s useful, especially when I want to delete a directory recursively and ignore all permissions.&lt;/p&gt;
&lt;p&gt;please don&apos;t use it without thinking twice or on root to not destroy your system.&lt;/p&gt;
&lt;h1&gt;cp&lt;/h1&gt;
&lt;p&gt;copy file or directory&lt;/p&gt;
&lt;h4&gt;syntax&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;cp PATH NEW_PATH&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;cp file.txt ~/Documents/file.txt&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;cp directory/ ~/Documents/new_directory_location/&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;pkill&lt;/h1&gt;
&lt;p&gt;terminates a program with closest name&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;pkill program_name&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;history | grep &quot;command_name&quot;&lt;/h1&gt;
&lt;p&gt;I use it a lot to find commands I&apos;ve used before. specifically when I want a long command but can&apos;t remember all of its components.&lt;/p&gt;
&lt;h1&gt;ffmpeg&lt;/h1&gt;
&lt;p&gt;ffmpeg is a powerful tool for video and audio processing.&lt;/p&gt;
&lt;p&gt;it is not a packaged command, you need to install it separately.&lt;/p&gt;
&lt;h4&gt;examples&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;ffmpeg -i input.mp4 -vf scale=-1:720 output.mp4&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;ffmpeg -i input.mp4 -vf scale=-1:720 -c:a copy output.mp4&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;conversion from mkv to mp4&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ffmpeg -i input.mkv -c copy output.mp4&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded><category>Linux</category><category>Linux</category></item><item><title>My Notes from CS50 AI</title><link>https://ywmaa.com/posts/ai/ainotesfromcs50/</link><guid isPermaLink="true">https://ywmaa.com/posts/ai/ainotesfromcs50/</guid><pubDate>Mon, 06 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Personal Notes of the CS50 AI course&lt;/p&gt;
&lt;h1&gt;Search&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;Agent: entity perceives its environment and acts upon that environment&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;State: config of the agent and its environment&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Actions: choices that can be made in a state&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;ACTIONS(s) returns the set of actions that can be executed in state s&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;transition model: description of what state results from performing any applicable action in any state&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;RESULT(s, a) returns the state resulting from performing action a in state s&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;state space: the set of all states reachable from the inital state by any sequence of actions (sometimes we use a Graph to represent the state space)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;goal test: way to determine whether a given state is a goal state&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;path cost: numerical cost associated with a given path&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Search Problems: init state, actions, transition model, goal test, path cost function&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Solution: sequence of actions that leads to the goal state&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Optimal Solution: the solution with the lowest path cost&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Node: data structure that keeps track of: a state, a parent, an action, a path cost (from init to node).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Normal/Classic Search&lt;/h2&gt;
&lt;p&gt;Search ALGOS: (most examples are in traversing a maze)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Frontier:
&lt;ul&gt;
&lt;li&gt;Depth-First Search (uses a stack) DFS&lt;/li&gt;
&lt;li&gt;Breadth-First Search (uses a queue) BFS&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Informed search: search startegy that uses problem-specific knowledge to find solutions more efficiently&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Greedy Best-First search: search algo that expands the node is closest to the goal, esitmated by a heuristic function h(n)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;A* Search: search algo that expands the node with lowest value of g(n) + h(n)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;g(n) = cost to reach node&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;h(n) = estimated cost to goal&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;this algo is the optimal under these conditions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;h(n) is admissible (never overestimates the true cost)
and&lt;/li&gt;
&lt;li&gt;h(n) is consistent (for every node n and successor n&apos; with step cost c,
h(n) &amp;lt;= h(n&apos;) + c)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Adversarial Search:&lt;/h2&gt;
&lt;p&gt;like playing a game against opponent (tic tac toe, )&lt;/p&gt;
&lt;p&gt;Minimax:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MAX: (X) aims to maximize score&lt;/li&gt;
&lt;li&gt;MIN: (O) aims to minimize score&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;S0: init state&lt;/p&gt;
&lt;p&gt;Player/s: returns which player to move in state s&lt;/p&gt;
&lt;p&gt;ACTIONS(s) returns the set of actions that can be executed in state s&lt;/p&gt;
&lt;p&gt;RESULT(s, a) returns the state resulting from performing action a in state s&lt;/p&gt;
&lt;p&gt;TERMINAL(s): checks if state s is a terminal state (game over)&lt;/p&gt;
&lt;p&gt;UTILITY(s): final numerical value for the terminal state s (score of the state)&lt;/p&gt;
&lt;p&gt;The algo process:
Given a state s:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MAX picks action a in ACTIONS(s) that produces
the highest value of MIN-VALUE(RESULT(s, a))&lt;/li&gt;
&lt;li&gt;MIN picks action a in ACTIONS(s) that produces
the lowest value of MAX-VALUE(RESULT(s, a))&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;function MAX-VALUE(state):
	if TERMINAL(state):
		return UTILITY(state)
	v = -∞
	for action in ACTIONS(state):
		v = MAX(v, MIN-VALUE(RESULT(state, action)))
	return v
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;function MIN-VALUE(state):
	if TERMINAL(state):
		return UTILITY(state)
	v = ∞
	for action in ACTIONS(state):
		v = MIN(v, MAX-VALUE(RESULT(state, action)))
	return v
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Alpha-Beta Pruning: I can ignore the rest of the nodes of already there is a choice for the other player that is less than we have already to optimize the minimax algo&lt;/p&gt;
&lt;p&gt;Depth-Limited Minimax: after certain number of moves I won&apos;t consider extra ones, this algo is important for complex games like Chess that got billions of possibilites that cannot be calculated in a reasonable time&lt;/p&gt;
&lt;p&gt;evaluation function: function that estimates the expected utility of the game from a given state (the better this function is in estimating, the more intelligent the AI is)&lt;/p&gt;
&lt;h1&gt;Knowledge&lt;/h1&gt;
&lt;p&gt;knowledge-based agents: agents that reason by operating on internal representations of knowledge&lt;/p&gt;
&lt;p&gt;Sentence: an assertion about the world in a knowledge representation language&lt;/p&gt;
&lt;p&gt;Propositional Logic,  Proposition Symbols: P &amp;amp; Q, Truth Tables are the essential way to represent logic and deductions for AI&lt;/p&gt;
&lt;p&gt;Model: assignment of truth value to every propositional symbol (a &quot;possible world&quot;)&lt;/p&gt;
&lt;p&gt;Knowledge base: a set of sentences known by a knowledge-based agent&lt;/p&gt;
&lt;p&gt;Entailment: $\alpha \vdash \beta$ in every model in which sentence $\alpha$ is true, sentence $\beta$ is also true&lt;/p&gt;
&lt;p&gt;Inference: the process of deriving new sentences from old ones&lt;/p&gt;
&lt;p&gt;KB is knowledge base
Inference Algo: does $KB \vdash \alpha$ ?&lt;/p&gt;
&lt;p&gt;Model Checking:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To Determine if $KB \vdash \alpha$:
&lt;ul&gt;
&lt;li&gt;Enumerate all possible models.&lt;/li&gt;
&lt;li&gt;if in every model where $KB$ is true, $\alpha$ is true, then $KB$ entails $\alpha$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Inference rules:&lt;/h4&gt;
&lt;p&gt;Modus Ponens, De Morgan&apos;s Law, And elimination, implication elimination, Double Negation elimination, bi-conditional elimination, Distributive Property&lt;/p&gt;
&lt;h3&gt;Theorem Proving&lt;/h3&gt;
&lt;p&gt;works a bit like search problems&lt;/p&gt;
&lt;p&gt;State: config of the agent and its knowledge base&lt;/p&gt;
&lt;p&gt;Actions: inference rules&lt;/p&gt;
&lt;p&gt;ACTIONS(s) returns the set of actions that can be executed in state s&lt;/p&gt;
&lt;p&gt;transition model: new knowledge base after inference&lt;/p&gt;
&lt;p&gt;RESULT(s, a) returns the state resulting from performing action a in state s&lt;/p&gt;
&lt;p&gt;state space: the set of all states reachable from the inital state by any sequence of actions (sometimes we use a Graph to represent the state space)&lt;/p&gt;
&lt;p&gt;goal test: way to determine whether a given state is a goal state (check statement we are trying to prove)&lt;/p&gt;
&lt;p&gt;path cost: number of steps in proof&lt;/p&gt;
&lt;p&gt;Theorem Proving: init state, actions, transition model, goal test, path cost function&lt;/p&gt;
&lt;h3&gt;Conversion To CNF (Conjuctive Normal Form)&lt;/h3&gt;
&lt;p&gt;disjunction: literals connected with $\lor$
conjunction: literals connected with $\land$&lt;/p&gt;
&lt;p&gt;clause: a disjunction of literals&lt;/p&gt;
&lt;p&gt;Conjuctive Normal Form: logical sentence that is a conjuction of clauses
e.g. $(A \lor B \lor C) \land (D \lor \neg E) \land (F \lor G)$&lt;/p&gt;
&lt;p&gt;Steps to Convert to CNF&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Eliminate biconditonals
&lt;ul&gt;
&lt;li&gt;turn $(\alpha \leftrightarrow \beta)$ into $(\alpha \rightarrow \beta) \land (\beta \rightarrow \alpha)$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Eliminate implications
&lt;ul&gt;
&lt;li&gt;turn $(\alpha \rightarrow \beta)$ into $\neg \alpha \lor \beta$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Move $\neg$ inwards using De Morgan&apos;s Laws
&lt;ul&gt;
&lt;li&gt;e.g. turn $\neg(\alpha \land \beta)$ into $\neg \alpha \lor \neg \beta$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use distributive law to distribute $\lor$ wherever possible&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Inference by Resolution&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;To Determine if $KB \vdash \alpha$:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Check if ($KB \land \neg \alpha$) is a contradiction
&lt;ul&gt;
&lt;li&gt;if so, then $KB \vdash \alpha$&lt;/li&gt;
&lt;li&gt;Otherwise, no entailment&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To Determine if $KB \vdash \alpha$:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Convert ($KB \land \neg \alpha$) to CNF (Conjuctive Normal Form)&lt;/li&gt;
&lt;li&gt;Keep checking to see if we can use resolution to produce a new clause
&lt;ul&gt;
&lt;li&gt;if ever we produce the empty clause (contradiction in computer represented as false), then we have a contradiction, and $KB \vdash \alpha$&lt;/li&gt;
&lt;li&gt;Otherwise, if we can&apos;t add new clauses, no entailment.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;First-Order Logic&lt;/h3&gt;
&lt;p&gt;Constant Symbols (Names, Objects, etc), Predicate Symbols (Classes) (Person, House, BelongsTo)&lt;/p&gt;
&lt;p&gt;Universal Quantification: $\forall x$
Existential Quantification: $\exists x$
and so on of Quantifications&lt;/p&gt;
&lt;h1&gt;Probability&lt;/h1&gt;
&lt;p&gt;Possible World: $\omega$
Probability of a possible world: $P(\omega)$&lt;/p&gt;
&lt;p&gt;1 = Certain
0 = Impossible&lt;/p&gt;
&lt;p&gt;$0 \leq P(\omega) \leq 1$&lt;/p&gt;
&lt;p&gt;The sum of all possible worlds $\omega$ in the set of all worlds $\Omega$ is 1
$\sum_{\omega \in \Omega} P(\omega) = 1$&lt;/p&gt;
&lt;h4&gt;unconditional probability&lt;/h4&gt;
&lt;p&gt;degree of belief in a proposition in the absence of any other evidence.&lt;/p&gt;
&lt;h4&gt;conditional probability&lt;/h4&gt;
&lt;p&gt;degree of belief in a proposition given some evidence that has already been revealed&lt;/p&gt;
&lt;p&gt;the probability of &quot;a&quot; given &quot;b&quot;
$P(a|b)$&lt;/p&gt;
&lt;p&gt;to know the probability of a given b, we take the probability of both and divide it by the probability of the second (b) to get rid of its own probability that happens when (a) doesn&apos;t&lt;/p&gt;
&lt;h5&gt;$P(a|b) = \frac{P(a \land b)}{P(b)}$&lt;/h5&gt;
&lt;h4&gt;random variable&lt;/h4&gt;
&lt;p&gt;a variable in probability theory with a domain of possible values it can take on
can be encoded as an array to distribute the probabilities&lt;/p&gt;
&lt;p&gt;Probability Distribution&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;$P(Flight = on time) = 0.6$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;$P(Flight = delayed) = 0.3$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;$P(Flight = cancelled) = 0.1$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;or as a vector/array&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;$P(Flight) = &amp;lt;0.6, 0.3, 0.1&amp;gt;$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;independence&lt;/h4&gt;
&lt;p&gt;the knowledge that one event occurs doesn&apos;t affect the probability of the other event&lt;/p&gt;
&lt;p&gt;then $P(b|a) = P(b)$ because (b) is independent of (a) anyways&lt;/p&gt;
&lt;h5&gt;$P(a \land b) = P(a)P(b|a) = P(a)P(b)$&lt;/h5&gt;
&lt;h4&gt;dependence&lt;/h4&gt;
&lt;p&gt;the knowledge that one event occurs affects the probability of the other event&lt;/p&gt;
&lt;h2&gt;Bayes&apos; Rule&lt;/h2&gt;
&lt;p&gt;:::note
$\because$
$P(a \land b) = P(b)P(a|b)$&lt;/p&gt;
&lt;p&gt;$P(a \land b) = P(a)P(b|a)$&lt;/p&gt;
&lt;p&gt;$\therefore$
$P(b)P(a|b) = P(a)P(b|a)$&lt;/p&gt;
&lt;p&gt;$\therefore$&lt;/p&gt;
&lt;p&gt;$P(b|a) = \frac{P(b) P(a | b)}{P(a)}$
:::
knowing P(a | b) we can calculate P(b | a)&lt;/p&gt;
&lt;p&gt;knowing P(visible effect | unknown cause)
we can calculate P(unknown cause | visible effect)&lt;/p&gt;
&lt;p&gt;knowing P(medical test result | disease)
we can calculate P(disease | medical test result)&lt;/p&gt;
&lt;h3&gt;Joint Probability&lt;/h3&gt;
&lt;h5&gt;$P(a|b) = \frac{P(a \land b)}{P(b)} = \alpha P(a \land b)$&lt;/h5&gt;
&lt;h5&gt;$\alpha = \frac{1}{P(b)}$&lt;/h5&gt;
&lt;p&gt;the conditional probability of (a) given (b) is proportional to a factor $\alpha$ multiplied by the joint probability of (a) and (b) $P(a \land b)$&lt;/p&gt;
&lt;h2&gt;Probability Rules&lt;/h2&gt;
&lt;h3&gt;Negation&lt;/h3&gt;
&lt;h5&gt;$P(\neg a) = 1 - P(a)$&lt;/h5&gt;
&lt;h3&gt;Inclusion-Exclusion&lt;/h3&gt;
&lt;h5&gt;$P(a \lor b) = P(a) + P(b) - P(a \land b)$&lt;/h5&gt;
&lt;h3&gt;Marginalization&lt;/h3&gt;
&lt;h5&gt;$P(a) = P(a \land b) + P(a \land \neg b)$&lt;/h5&gt;
&lt;h5&gt;$P( X = x_{i}) = \sum_{j} P(X = x_{i} \land Y = y_{j})$&lt;/h5&gt;
&lt;h3&gt;Conditioning&lt;/h3&gt;
&lt;h5&gt;$P(a) = P(a|b)P(b) + P(a| \neg b)P(\neg b)$&lt;/h5&gt;
&lt;h5&gt;$P( X = x_{i}) = \sum_{j} P(X = x_{i} | Y = y_{j})P( Y = y_{j})$&lt;/h5&gt;
&lt;h2&gt;Probability Models&lt;/h2&gt;
&lt;h3&gt;Bayesian Network&lt;/h3&gt;
&lt;p&gt;data structure that represents the dependencies among random variables.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Directed Graph&lt;/li&gt;
&lt;li&gt;Each node represents a random variable&lt;/li&gt;
&lt;li&gt;arrow from X to Y means X is a parent of Y&lt;/li&gt;
&lt;li&gt;each node X has probability distribution $P(X | Parents(X))$&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><category>AI</category><category>AI</category></item></channel></rss>