⚠️ A problem was encountered with serial communication, fix comingsoonprobably never
An automatic pan‑tilt camera system that uses computer vision to detect human body position and control two servos via a PID controller.
Developed for the UF22 "Automatic Systems" course.
📘 Complete documentation is now available here (only read if you are a nerd and know italian)
spotd is an automatic tracking system that:
- Uses MediaPipe‑based body‑pose detection to estimate the user’s position in the camera frame.
- Feeds the position data into a PID controller that drives a pan‑tilt head.
- Provides a GUI based on CustomTkinter for mode selection, tuning, and real‑time visualization.
- Supports both software simulation and physical hardware operation via serial communication.
Hardware is not required: the project can be tested in simulation mode, or connected to an Arduino or similar MCU to drive real servos.
⚠️ MediaPipe requires python3.12.x or earlier to run, python3.13.x will NOT work! Check out this guide on how to install python3.12
- USB camera or any other webcam with live feed
- Optional: Arduino or other MCU for hardware control
# Clone the repo
git clone https://github.com/hert1zm/spotd.git
cd spotd
# Install dependencies
pip install opencv-python mediapipe customtkinter Pillow numpy scipy
# Start the application
python spotd.pyBy default, spotd starts in simulation mode.
Stand in front of the webcam; the system will detect your position and:
- Display the tracking coordinates in the GUI.
- Show simulated servo angles in the terminal.
- Run the full PID control loop without any hardware connected.
This mode is ideal for testing, debugging, and tuning PID parameters.
- Connect an Arduino (or any MCU) that can control two servos via serial.
- In the GUI, toggle Hardware Mode.
- Select the correct serial port and click Connect.
- The system will send angle commands to the servos in real time.
This is an example configuration using an Arduino as servo controller.
Serial communication follows this format:
PAN:<angle>,TILT:<angle>\n
Example Arduino sketch:
#include <Servo.h>
Servo panServo, tiltServo;
void setup() {
Serial.begin(9600);
// Wait for serial connection to stabilize
while (!Serial && millis() < 3000)
;
panServo.attach(9);
tiltServo.attach(10);
Serial.println("spotd servo controller ready");
}
void loop() {
if (Serial.available()) {
static char buffer[64];
static int index = 0;
char c;
while (Serial.available()) {
c = Serial.read();
if (c == '\n' || c == '\r') {
buffer[index] = 0; // null‑terminate
index = 0;
// Process command
if (buffer[0] == 'P') {
char *panTag = strstr(buffer, "PAN:");
char *tiltTag = strstr(buffer, "TILT:");
if (panTag && tiltTag && tiltTag > panTag) {
int panAngle = atoi(panTag + 4);
int tiltAngle = atoi(tiltTag + 5);
// Optional: limit angles to servo range
//panAngle = constrain(panAngle, 0, 180);
//tiltAngle = constrain(tiltAngle, 0, 180);
panServo.write(panAngle);
tiltServo.write(tiltAngle);
Serial.println("OK");
}
}
break;
} else if (index < 63) {
buffer[index++] = c;
}
}
}
}