Your First System
We've covered sensors, actuators, and the modular software architecture that connects them. Now let's put it all together. We'll design a simple robot system from scratch and trace exactly how information flows through it.
The Mission
Our robot needs to do one thing: drive toward a red ball.
Simple enough, right? But even this basic task requires multiple components working together. Let's design the system.
Step 1: Define the Hardware
Our robot has:
- 1 RGB camera (640×480, 30 fps) — to see the ball
- 2 DC motors with encoders — left and right wheel (differential drive)
- 1 microcontroller — runs the software
That's it. Minimal hardware, maximum learning.
Step 2: Design the Nodes
Following the modular approach from the last lesson, we need:
| Node | Input | Output | Job |
|---|---|---|---|
| Camera Driver | Hardware | Image on /camera/rgb | Read frames from the camera |
| Ball Detector | Image from /camera/rgb | BallPosition on /perception/ball | Find the red ball in the image |
| Controller | BallPosition from /perception/ball | Twist on /cmd_vel | Decide how to steer |
| Motor Driver | Twist from /cmd_vel | Hardware | Send voltage to motors |
Four nodes, three topics, one mission.
Step 3: Trace the Data Flow
Let's follow one cycle of the sense-think-act loop:
1. Camera Driver publishes an image
Every 33ms (30 fps), the camera driver reads a frame and publishes it:
2. Ball Detector finds the red ball
The detector subscribes to images and looks for red pixels:
3. Controller decides the steering
The controller uses a simple rule: if the ball is left of center, turn left. If right, turn right. Drive forward proportionally to the ball's apparent size (bigger = closer = slow down).
4. Motor Driver moves the wheels
The motor driver converts the Twist command into individual wheel speeds:
The Complete Picture
Here's the full data flow in one cycle:
Camera (hardware)
↓ capture
Camera Node
↓ publishes Image to /camera/rgb
Ball Detector Node
↓ processes image, finds ball at pixel (420, 300)
↓ publishes BallPosition to /perception/ball
Controller Node
↓ ball is right of center → steer left
↓ publishes Twist(linear=0.4, angular=0.15) to /cmd_vel
Motor Driver Node
↓ converts to wheel speeds: left=0.377, right=0.423
Left Motor + Right Motor (hardware)
→ robot curves to the right toward the ball
This entire cycle takes about 40-50 milliseconds. The robot updates its behavior 20-30 times per second — fast enough to smoothly track a moving ball.
Notice how each node only knows about its own inputs and outputs. The camera node doesn't know about balls. The ball detector doesn't know about motors. This separation of concerns is what makes the system maintainable and extensible.
What Could Go Wrong?
Real robots encounter real problems:
- The ball moves behind an obstacle → The detector publishes
found=False, the controller switches to search mode - The camera feed is delayed → The controller acts on stale data, possibly overshooting the turn
- A motor stalls → The robot drives in a curve even though it commanded straight
- Another red object appears → The detector might track the wrong thing
Each of these problems has solutions — better algorithms, sensor fusion, error handling — that we'll explore in later modules.
Why This Matters
This tiny ball-following robot uses the exact same architecture as self-driving cars, warehouse robots, and Mars rovers. The nodes are more complex, the sensors are more numerous, and the algorithms are more sophisticated — but the pattern is identical:
Sense → Process → Decide → Act → Repeat
What's Next?
Congratulations! You've just designed your first robot system. You understand sensors, actuators, modular software architecture, and data flow. In Module 2, we'll dive deeper into how parts communicate — the publish-subscribe pattern, message types, and what happens when things need to talk in real-time.