Wow, half a year has passed since my last blog.
I have to admit, during this period I was a bit disconnected from the physical AI world. I transitioned to a different team at work after their two data scientists were reassigned to other teams, and I had to ramp up quickly to take over their projects. We were mainly working on fine-tuning BERT but it was a complicated project. There were days I’d wake up at 7 am to check model results, and nights when I kept coding until it was far too late.
But now the projects are in a stable phase (mostly maintenance and a few experiments) so I finally have time to think about physical AI again.
We have a problem at home
My wife and I are both a bit paranoid when it comes to our house. As soon as we leave, we immediately start worrying about things like:
- Is the refrigerator door closed properly?
- Did we feed the cat?
- Is the cat okay?
- Did we leave a window open? (The cat could escape.)
- Did we leave the iron plugged in?
So what if we can control a car with our phone and see what’s around, even if we are not at home?
I know this might not be an ‘AI’ project, but it could serve as the foundation for a platform that can later support AI projects. If we want to explore AI in manipulation and navigation, we have to start somewhere. But most importantly, I want to play with an RC car without being judged.
I bought this thing because it was on sale
You might have noticed that in previous blogs I mentioned Arduino and ESP32 as options. While it’s perfectly possible to use them, I bought a Raspberry Pi Zero 2 W without really knowing what it was because it was on sale. I wanted to explore it.
And turns out, having a full computer with an OS is much more fun than using a microcontroller, especially if you’re not concerned with efficiency for now. After all, you’re working with a full Linux computer that happens to fit in your palm and costs $15 ($10 if you are lucky like me).
2WD kit
For 5 dollars, you can get a 2wd car kit:

This kit has a frame, 2 motors and wheels and a battery holder. You can connect the motors to the batteries and it will move forward until the batteries die. But with the following stack, it becomes more interesting:
- a Raspberry Pi
- tb6612 motor driver so that we can control the direction and the speed of the motors.
- two 18650 batteries (7.4v), instead of 4 AA batteries (4 x 1.5v = 6V)
- buck converter to step down 7.4V to 5V for Raspberry Pi
- a usb camera to see things
I only had this long breadboard, so it looks ridiculous:

If you accelerate really fast, the breadboard touches the ground and it looks funny (it’s a feature, not a bug)
How do we even use Raspberry Pi?
We first need to download the Raspberry Pi imager from the official website. There you select OS, hostname, username and password, Then it will write this image to the sd card. Now when you plug the sd card and power the Raspberry Pi, it’s done. The Raspberry Pi is literally a computer. You can plug your mouse, keyboard and monitor and start working on it.
But I dont have the correct hdmi adapter, so I will do this in a headless way using SSH.
You can open your terminal and write ping <hostname>. It will show you the IP of your Raspberry Pi. Then if you execute ssh <username>@<IP>, it will ask for your password.
Now you are in! You are connected to your Raspberry Pi’s command line interface. From here, you can install software, configure settings, and run programs. It’s incredible.
All the software
We need a couple of things to make this work:
- Motor control server for driving two motors.
This will be a small Python app that receives HTTP requests like: /motor?x=50&y=-20
- Live video streaming using mjpg-streamer and a USB camera.
For this I use mjpg-streamer, a lightweight tool that:
- captures frames from the USB camera
- converts them into JPEGs
- streams them continuously over HTTP
There may be a better way but it’s a simple way to expose a camera feed without requiring heavy libraries.
- A web interface with a virtual joystick for control and a video feed.
Joystick enables us to select motor speed from a grid (x axis: motor a speed, y axis: motor b speed)
Routing Everything Through One URL (Nginx)
The Pi now has multiple local services:
motor-server on port 5000
mjpg-streamer on port 8080
the web UI on port 3000
Nginx acts as a reverse proxy, combining all of them under one clean address:
/ → web interface
/stream → video feed
/motor → motor server
This lets us control the entire robot through a single URL, even though internally it’s multiple programs.
But we don’t want to SSH everytime and manually start these processes. If power cuts or the Pi reboots, everything should come back online by itself.
What is systemd?
systemd is the init system on modern Linux — it’s the thing that boots the machine and also manages background services. Instead of manually starting programs every time you boot your computer, systemd can automatically start, stop, and monitor them. Each service is described in a unit file (like motor-server.service) that tells systemd what to run (ExecStart), where to run it (WorkingDirectory), and what to do if it stops (Restart=always). Once you enable a service with sudo systemctl enable <service> and start it with sudo systemctl start <service>, systemd makes sure it runs automatically at boot and keeps it running in the background.
You create a service file for each component: motor-server.service, mjpg-streamer.service etc.
A systemd unit file looks like this:
[Unit]
Description=Motor Server
[Service]
ExecStart=/usr/bin/python3 /home/pi/project/motor_server.py
WorkingDirectory=/home/pi/project
Restart=always
[Install]
WantedBy=multi-user.target
Enable it:
sudo systemctl enable motor-server
sudo systemctl start motor-server
Now it runs on every boot.
It’s time to leave the house
At this point, everything works locally, meaning only devices on the same Wi-Fi network can see the robot. To access it globally—without exposing the home IP or touching router settings—we create a Cloudflare Tunnel.
First I bought a domain from namecheap for 60 cents (accurate brand name). Then I moved its DNS to Cloudflare. After that I installed cloudflared on the Pi and followed the instructions on the dashboard. It’s incredibly fast and easy to implement: https://one.dash.cloudflare.com/ → Networks → Connectors → Cloudflared
It works!
Now we can safely go outside, and if we ever worry about something, we can just use this little mobile camera guy that also serves its own website. Now the only worry we have is that if batteries explode, the house could catch fire and burn down everything. Not a big deal at all.
Thanks for reading
You start by flashing an SD card and somehow end up configuring services, routing traffic with nginx, streaming video, and controlling motors with HTTP requests.
The Raspberry Pi + Linux world is insane. It feels a bit sad that I’m only discovering all of this at 26. I wish someone had introduced me to it years ago. If I accidentally become that person for you, that genuinely makes this blog worth writing.