<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Project on Mahdi Sarfarazi</title>
    <link>https://mahdisf.ir/tags/project/</link>
    <description>Recent content in Project on Mahdi Sarfarazi</description>
    <image>
      <title>Mahdi Sarfarazi</title>
      <url>https://mahdisf.ir/images/social-card.png</url>
      <link>https://mahdisf.ir/images/social-card.png</link>
    </image>
    <generator>Hugo</generator>
    <language>en-US</language>
    <lastBuildDate>Mon, 01 Jun 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://mahdisf.ir/tags/project/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Camera-only 3D tracking and velocity estimation</title>
      <link>https://mahdisf.ir/projects/vision-3d-state-estimation/</link>
      <pubDate>Sun, 01 Feb 2026 00:00:00 +0000</pubDate>
      <guid>https://mahdisf.ir/projects/vision-3d-state-estimation/</guid>
      <description>Course project: a Python pipeline that tracks people and vehicles in 3D from a single phone camera, estimating position and velocity with a Kalman filter. Benchmarked components; limits documented.</description>
      <content:encoded><![CDATA[<p>In this machine-vision course project, I estimated where people and vehicles are in 3D, and how fast they&rsquo;re moving, using only a phone camera without LiDAR or a stereo rig.</p>
<h2 id="what-i-built">What I built</h2>
<p>YOLO11n detects objects and ByteTrack keeps their identities across frames. The metric outdoor variant of Depth Anything V2 then turns each detection into a 3D position.</p>
<p>A recursive Kalman filter tracks motion with a six-value state (position and velocity in x, y, z). It uses wall-clock time between frames, so velocity stays consistent when the frame rate varies, and it keeps predicting through missed detections.</p>
<p>I calibrated the camera (a Samsung A34) with a checkerboard, and used a second phone&rsquo;s IMU (a Samsung A54, via Phyphox) to sanity-check the estimated velocities.</p>
<h2 id="how-i-chose-the-components">How I chose the components</h2>
<p>I benchmarked the detectors myself on the target laptop (RTX 3060, 6 GB):</p>
<table>
  <thead>
      <tr>
          <th>Detector</th>
          <th style="text-align: right">Measured speed</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>YOLOv8n</td>
          <td style="text-align: right">≈ 16 FPS</td>
      </tr>
      <tr>
          <td>YOLO11n</td>
          <td style="text-align: right">≈ 20 FPS</td>
      </tr>
      <tr>
          <td>YOLO26n</td>
          <td style="text-align: right">≈ 23 FPS</td>
      </tr>
  </tbody>
</table>
<p>I picked YOLO11n. It wasn&rsquo;t the fastest, but it gave the best balance of detection quality, installation reliability and speed. The depth model was the real bottleneck at about 0.22 s per frame (≈ 4.5 FPS).</p>
<h2 id="results-and-limits">Results and limits</h2>
<p>The Kalman filter typically converged within three to five frames of a new detection. I tested qualitatively on crowded pavements, street traffic and mixed traffic.</p>
<p>The report states the main limitation. Without LiDAR or stereo ground truth, I could not measure end-to-end depth error, and metric scale needed manual calibration. The depth model&rsquo;s published benchmark (0.454 m MAE on its own validation sets) does not measure this system.</p>
]]></content:encoded>
    </item>
    <item>
      <title>LLM-powered robotic task planning</title>
      <link>https://mahdisf.ir/projects/llm-powered-robotic-task-planning/</link>
      <pubDate>Mon, 01 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://mahdisf.ir/projects/llm-powered-robotic-task-planning/</guid>
      <description>Personal experiment: translating natural-language instructions into ROS2 actions for a simulated robotic arm in Gazebo, using the Gemini API.</description>
      <content:encoded><![CDATA[<p>This is a personal experiment in connecting a language model to a robot safely. The model proposes a plan, and ROS2 executes it on a simulated arm.</p>
<p><img alt="Diagram: a natural-language instruction goes to an LLM planner, which produces ROS2 actions for a simulated arm in Gazebo." loading="lazy" src="/projects/llm-powered-robotic-task-planning/architecture.svg"></p>
<h2 id="what-it-does">What it does</h2>
<p>It takes an instruction in plain language and uses the Gemini API to turn it into a sequence of ROS2 actions, which then run on a simulated robotic arm in Gazebo.</p>
<h2 id="status-and-limits">Status and limits</h2>
<p>This is an early-stage experiment. It has no formal evaluation yet, and the code is not public. I&rsquo;ll update this page with a repository, the supported task set and results when there is something worth measuring.</p>
<p>The same question drives <a href="/projects/vigenx-agentic-video-editor/">ViGenX</a>: how to let a language model plan while keeping execution verifiable.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Human-following mobile robot</title>
      <link>https://mahdisf.ir/projects/human-follower-mobile-robot/</link>
      <pubDate>Sat, 01 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://mahdisf.ir/projects/human-follower-mobile-robot/</guid>
      <description>Course project: a four-wheeled robot that follows a person, using on-phone vision and an Arduino motor controller with an ultrasonic safety stop.</description>
      <content:encoded><![CDATA[<p>A course project in which I owned the requirements and the end-to-end build of a small robot that follows a person indoors.</p>
<p><img alt="Diagram: an Android phone sends direction commands over USB serial to an Arduino Uno and L298N motor driver, with an ultrasonic sensor that can stop the robot." loading="lazy" src="/projects/human-follower-mobile-robot/architecture.svg"></p>
<h2 id="what-i-built">What I built</h2>
<p>A Python (Kivy/Buildozer) Android app runs a TensorFlow Lite MobileNet v1 model on the phone to detect and select the person to follow, at roughly 60 frames per second.</p>
<p>The phone sends forward, backward, left, right and stop commands over USB serial to an Arduino Uno, which drives four DC motors through an L298N driver.</p>
<p>An HC-SR04 ultrasonic sensor overrides the vision system. It stops or redirects the robot whenever an obstacle is closer than 1.5 m.</p>
<h2 id="decisions-worth-noting">Decisions worth noting</h2>
<p>I compared a Raspberry Pi with a smartphone as the compute platform, and SAMURAI, YOLOv8 and MobileNet as detectors, choosing on inference efficiency. Running vision on the phone kept the robot&rsquo;s electronics simple and cheap.</p>
<h2 id="limits">Limits</h2>
<p>This was a course prototype. It was not evaluated with a formal protocol, and no code or video is public.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
