Fundamentals of Robotic Control and Programming
From the Robotics curriculum
Fundamentals of Robotic Control and Programming
TL;DR
Robotic control makes robots do what you want them to do, using sensors to understand the world and actuators to move. Programming provides the instructions for this control, defining how the robot interprets information and executes tasks. You'll learn about open-loop vs. closed-loop control and how to structure basic robot programs.
1. The Mental Model
Think of a robot like a toddler learning. It needs to know what to do (programming), how to do it (control), and whether it actually did it (sensors and feedback). Our goal is to give it clear instructions and ensure it can follow them reliably.
2. The Core Material
Robotic control is all about getting your robot to perform desired actions. This involves understanding its current state, making decisions, and then commanding its motors or other components. Programming is the language you use to give these commands.
Open-Loop vs. Closed-Loop Control

Photo by Denzel V on Pexels
The biggest distinction in control is whether you're checking your work.
- Open-Loop Control: You tell the robot to do something, and you trust it'll happen without confirming. It's like telling your car to drive for 10 seconds at full throttle, assuming it will cover a certain distance. This is simple but risky; if anything unexpected happens, the robot won't adjust.
- Closed-Loop Control (Feedback Control): You tell the robot to do something, and then you measure if it actually did it. Based on that measurement, you make adjustments. It's like telling your car to drive 100 meters, using a speedometer and odometer to continuously check your speed and distance, and adjusting the throttle as needed. This is more complex but much more robust and accurate. Most useful robotic tasks rely on closed-loop control.
Let's look at the feedback loop:
graph LR
A["Desired Output/Goal (e.g., Go straight)"] --> B["Controller (Brain)"];
B --> C["Actuator (Motor)"];
C --> D["Robot (Body)"];
D --> E["Sensor (Eyes/Ears)"];
E --> F["Actual Output/State (e.g., Drifting left)"];
F --> G{"Compare (Is Actual = Desired?)"};
G -- "Error (Difference)" --> B;
G -- "No Error" --> A;
Basic Robot Programming Concepts

Photo by Laura Musikanski on Pexels
When you program a robot, you're essentially writing a sequence of instructions. These instructions often involve:
- Reading Sensor Data: Getting input from the environment (e.g.,
read_distance_sensor(),get_motor_encoder()). - Making Decisions: Using
if/elsestatements or loops to react to sensor data (e.g.,if distance < 10: stop()). - Commanding Actuators: Telling motors, grippers, or other components what to do (e.g.,
set_motor_speed(left, 50),open_gripper()). - Delays/Timing: Waiting for a specific duration (
sleep(1)).
Example: Simple Motor Control

Photo by ThisIsEngineering on Pexels
Let's say you have a motor and you want to control its speed.
Open-Loop:
# Assuming 'motor' is an object representing your motor
motor.set_speed(100) # Set motor to full speed
# The motor will now spin at full speed until told otherwise.
# We don't check if it's actually at full speed or facing resistance.
Closed-Loop (using a Proportional Controller idea):
import time
class Motor:
def __init__(self):
self._current_speed = 0 # Simulate actual motor speed
self._target_power = 0 # What we tell the motor to do
def set_power(self, power):
# In a real robot, this would send a signal to a motor driver
self._target_power = max(-100, min(100, power)) # Limit power -100 to 100
# For simulation, let's say power affects speed over time
self._current_speed += (self._target_power / 10.0)
self._current_speed = max(-100, min(100, self._current_speed)) # Cap speed
print(f" Motor given power: {self._target_power}, Actual speed approx: {self._current_speed:.1f}")
def get_current_speed(self):
# In a real robot, this would read an encoder or tachometer
return self._current_speed
def simple_pid_controller(desired_speed, motor, Kp, Ki, Kd, dt):
previous_error = 0
integral_error = 0
for _ in range(20): # Simulate 20 control cycles
actual_speed = motor.get_current_speed()
error = desired_speed - actual_speed
integral_error += error * dt
derivative_error = (error - previous_error) / dt
output_power = (Kp * error) + (Ki * integral_error) + (Kd * derivative_error)
motor.set_power(output_power)
previous_error = error
time.sleep(dt) # Wait for the next control cycle
# Initialize
my_motor = Motor()
Kp_val = 2.0 # Proportional gain
Ki_val = 0.1 # Integral gain
Kd_val = 0.5 # Derivative gain
delta_t = 0.1 # Time step for simulation
print("Trying to reach desired speed of 50 using closed-loop control:")
simple_pid_controller(50, my_motor, Kp_val, Ki_val, Kd_val, delta_t)
print("\nMotor reached speed of:", my_motor.get_current_speed())
In the simple_pid_controller, Kp, Ki, and Kd are gains. Kp (Proportional) reacts to the current error. Ki (Integral) reacts to accumulated past errors, helping to eliminate steady-state errors. Kd (Derivative) reacts to the rate of change of error, helping to dampen oscillations. Adjusting these values (called "tuning") is a big part of control engineering.
3. Worked Example
Let's program a simple "avoid obstacles" behavior for a hypothetical robot with two wheels (left, right) and a front distance sensor.
Goal: Move forward. If an obstacle is detected within 20cm, stop, turn right, then continue moving forward.
import time
# --- Simulate Robot Hardware ---
class SimulatedRobot:
def __init__(self):
self.left_motor_speed = 0
self.right_motor_speed = 0
self.distance_sensor_reading = 100 # Start with no obstacle (100cm)
def set_motor_speeds(self, left, right):
self.left_motor_speed = left
self.right_motor_speed = right
print(f" Motors set: Left={left}, Right={right}")
def get_distance(self):
# In a real robot, this would read an actual sensor.
# For simulation, let's make it change sometimes
if time.time() % 10 < 3: # Simulate obstacle appearing every 10 seconds for 3 seconds
self.distance_sensor_reading = 15
else:
self.distance_sensor_reading = 100
return self.distance_sensor_reading
# --- Robot Control Logic ---
def run_robot():
robot = SimulatedRobot()
OBSTACLE_THRESHOLD = 20 # cm
FORWARD_SPEED = 50
TURN_SPEED = 30
TURN_DURATION = 2.0 # seconds
print("Robot starting...")
while True: # Main robot loop
current_distance = robot.get_distance()
print(f"Current distance: {current_distance}cm")
if current_distance < OBSTACLE_THRESHOLD:
print("OBSTACLE DETECTED! Stopping and turning right.")
robot.set_motor_speeds(0, 0) # Stop
time.sleep(1) # Pause briefly
robot.set_motor_speeds(TURN_SPEED, -TURN_SPEED) # Turn right (left fwd, right bwd)
time.sleep(TURN_DURATION) # Turn for 2 seconds
robot.set_motor_speeds(0, 0) # Stop after turning
print("Finished turning, checking again...")
time.sleep(0.5) # Small pause before checking distance again
else:
print("Clear path, moving forward.")
robot.set_motor_speeds(FORWARD_SPEED, FORWARD_SPEED) # Move forward
time.sleep(0.5) # Control loop runs every half second
# To run this example, uncomment the line below and run the Python script.
# It will print output indicating robot behavior. Use Ctrl+C to stop it.
run_robot()
This example shows how sensors (distance) drive decisions (if current_distance < OBSTACLE_THRESHOLD) which then command actuators (motor speeds). This is a basic form of reactive closed-loop control.
4. Key Takeaways
- Robotic control directs robot actions, while programming provides the instructions.
- Open-loop control gives commands without checking outcomes; it's simpler but less reliable.
- Closed-loop control uses sensor feedback to compare actual results with desired results, making adjustments for accuracy and robustness.
- Most practical robot tasks use closed-loop control to adapt to their environment.
- Robot programs primarily involve reading sensors, making decisions based on that data, and commanding actuators.
- PID control (Proportional-Integral-Derivative) is a common and powerful closed-loop control technique for maintaining desired states.
- Understanding the flow from sensing to decision to actuation is fundamental to robotics.
Common Mistakes to Avoid:
- Ignoring feedback: Assuming your robot will always do exactly what you tell it without checking can lead to errors.
- Over-complicating initially: Start with simple open-loop actions before adding complex closed-loop systems.
- Not testing enough: Robot behavior can be unpredictable; test thoroughly in varied conditions.
- Forgetting about timing: Delays (time.sleep()) are crucial for allowing actions to complete or for sensors to stabilize.
5. Now Try It
Exercise: Modify the run_robot() example. Instead of just turning right, make the robot try to turn left if an obstacle is detected within 20cm, and then if an obstacle is still detected after the left turn, then make it turn right.
What success looks like: Your robot's print statements should show it detecting an obstacle, attempting a left turn
Frequently asked about Fundamentals of Robotic Control and Programming
More from Robotics
Get the full Robotics curriculum
Clone the complete plan to your dashboard for unlimited AI-generated notes, practice quizzes, and a personalised revision schedule.
Create Free Account