Reactive Navigation: Teach a Robot to Avoid Obstacles
You can make a robot sense obstacles and decide where to go on its own—no map, just clean sensing and a behaviour loop.
Reactive navigation is the first way most robots learn to get around: instead of holding a map and planning a route, the robot simply reacts to what its sensors report right now. Sense the space ahead, decide, move, and repeat, many times a second. It is cheap, robust, and enough to let a robot wander a cluttered room without hitting anything—the behaviour behind every beginner obstacle-avoiding robot.
This path builds that skill one layer at a time. You start by turning a raw ultrasonic ping into a distance you can trust, then learn why sensor readings jump and how to filter them. You compare ultrasonic against laser time-of-flight so you know which sensor lies to you and when, add a servo scan so the robot can see which way is open, wrap the whole thing in a behaviour state machine, and finish by tuning the complete loop in a simulator.
Follow the nodes in order—each unlocks the next once you have done it, and your progress saves on this device. When you are ready to build the real thing, this path feeds straight into the obstacle-avoiding robot project.
Before you start
You need to be able to read a sensor and drive two motors — the motor control path covers the driving half. No map, no localisation and no planning algorithm is involved here; that is deliberate, and it is what makes reactive navigation the right first approach.
What you will be able to do
- Turn an ultrasonic ping into a distance you can act on, with a timeout so a missing echo cannot stall the loop and a median filter so one bad reading cannot swerve the robot.
- Say which sensor to trust for a given surface, and why a laser time-of-flight sensor and an ultrasonic one fail on completely different materials.
- Sweep a sensor across an arc and pick the most open bearing from the readings.
- Express behaviour as explicit states rather than nested conditionals, so “what is the robot doing right now” always has an answer.
Where people get stuck
Reading the sensor before the servo has stopped moving. The measurement comes back for whatever the sensor was pointing at mid-sweep, so the robot confidently turns toward a wall. Add a settle delay after commanding the angle and before pinging.
No timeout on the echo. If nothing comes back — and on a soft or angled surface, nothing
often does — a naive pulseIn blocks the whole loop. The robot appears to freeze at random.
Trusting a single reading. Ultrasonic sensors produce occasional wild values. One spurious 20 cm reading in open space is enough to trigger an emergency turn. Take three and use the middle one.
Angled and soft surfaces. Sound reflects off a wall met at a steep angle away from the sensor, so a wall at 45° can read as open space. Cushions and curtains absorb the ping entirely. This is a physical limit, not a bug — design the behaviour to survive it.
Oscillating at a threshold. With a single stop distance, a robot hovering near it flips between driving and turning many times a second. Use two thresholds — stop closer, resume further — so the behaviour has hysteresis and commits to a decision.
What you need
| What | Why this path needs it | Notes |
|---|---|---|
| An HC-SR04 or VL53L0X | The distance sense the whole path is built on | ~$2 and ~$5 respectively |
| A hobby servo | So the sensor can look somewhere other than straight ahead | SG90 is plenty for a sensor head |
| A lever microswitch or two | The one sensor that never lies about a collision | Cheap insurance against every ranging failure below |
| A driveable robot base | Two motors and a driver you can already command | The motor control path gets you here |
| A cluttered floor | The test environment, and it must include a soft surface and an angled one | A cushion and an open door are the two best test obstacles |
Why the path runs in this order
Sensing before deciding, always. Almost every avoidance behaviour that misbehaves is acting correctly on a bad reading. Until a distance measurement is trustworthy — timeout on a missing echo, median of three against spikes — no amount of behaviour logic will produce a robot that behaves. Debugging in the other order means suspecting your state machine for a fault that lives in the sensor.
Comparing sensors before committing to one. The comparison node exists because sonar and laser fail on completely different materials, and which one is right depends entirely on the room you are driving in. Making that decision knowingly, once, is much cheaper than discovering it after a chassis is built around the wrong sensor.
Filtering before scanning. A servo sweep multiplies your sensor’s error rate by the number of angles you sample. If a single reading is unreliable, a nine-point sweep gives you nine chances to pick the wrong direction, and the robot turns confidently into a wall.
Scanning before deciding. A robot that can only see forward has exactly two options — stop, or turn blindly. Being able to measure several bearings turns avoidance from a reflex into a choice, and it is the point where the behaviour starts to look intelligent.
The state machine before the algorithm. The avoidance algorithm is a state machine; learning the structure separately means the final node is about the robotics rather than about untangling control flow.
Contact sensing throughout. The bump switch is deliberately not last. Every ranging sensor on this path has surfaces it cannot see, so a robot without contact sensing is one curtain away from pushing until something breaks. It is the cheapest reliability on the whole robot.
Checkpoints: how to know a stage landed
| Stage | The check | What a pass looks like |
|---|---|---|
| Distance reading | Point the sensor at a wall at 30 cm and print for a minute | Steady within a centimetre or two, no zeros, no stalls when you aim it at the ceiling |
| Timeout | Aim the sensor at open air and watch the loop rate | The loop keeps its interval — no echo must not mean a frozen robot |
| Median filter | Wave a hand through the beam repeatedly | Occasional wild values disappear from the output; the real approach still shows up |
| Sensor comparison | Measure a cushion, a wall at 45°, and a dark matte surface | You can predict which sensor fails on which, before you measure |
| Servo scan | Sweep and print distance per angle across an open doorway | The doorway is visibly the maximum, and the readings are repeatable sweep to sweep |
| Settle delay | Remove your settle delay deliberately | The readings smear across angles — now you know what that failure looks like |
| State machine | Print the current state every loop | You can always name what the robot is doing, and every transition has a visible cause |
| Bump switch | Press it slowly and count events | One press produces exactly one event, not the nine a raw switch generates |
| Full behaviour | Run it in a cluttered room for five minutes | It survives, and when it gets stuck you can say which state it was in |
Where this path stops
Reactive navigation has a hard ceiling, and it is worth stating plainly: a reactive robot cannot be sent anywhere. It has no memory, so it cannot go to the kitchen, cannot promise it has covered the whole floor, and cannot avoid the corner it got stuck in last time. Those are not implementation gaps — they are what having no map means.
The path also stops short of two things you will want next. Wall following is the natural extension, and it is the first behaviour that starts to look like a plan, because a robot that holds a fixed distance from a wall on one side will traverse a whole room deterministically. And coverage — actually sweeping an area rather than wandering it — is where the lack of memory finally becomes intolerable.
When it does, path planning and mapping is the answer, and this path is the right thing to have done first: every mapping robot still needs the reflexes built here for the moment its map turns out to be wrong.
Learning roadmap
The path
Follow the nodes in order—each unlocks the next once you have done it. Your progress saves on this device.
0 / 11 done
Common questions
Frequently asked questions
What is reactive navigation in robotics?
Navigation with no map and no plan. The robot senses what is in front of it right now, decides what to do about it, moves, and repeats—often fifty times a second. It never asks where it is, because it never needs to know. That makes it cheap, robust, and immune to the localisation errors that break map-based navigation, at the cost of being unable to do anything that requires memory: it cannot go to a named place, cannot guarantee it has covered a room, and can be trapped indefinitely in a concave corner.
Why does my obstacle-avoiding robot drive straight into walls?
Almost always the sensor rather than the logic, and usually one of three causes. An ultrasonic sensor meeting a wall at a steep angle reflects the ping away instead of back, so a wall at 45° reads as open space—this is physics, not a fault. Soft surfaces such as curtains and cushions absorb the ping entirely. And if you read the sensor before a scanning servo has finished moving, the distance you get belongs to whatever it was pointing at mid-sweep. Add a settle delay after commanding an angle, and add a bump switch so that contact is always detected even when ranging fails.
Why does my robot jitter back and forth at an obstacle?
A single stop threshold. When the robot hovers near it, tiny measurement changes flip the decision many times a second, and it stutters instead of committing. Use two thresholds with a gap between them—stop at 20 cm, do not resume until 30 cm. That gap is hysteresis, and it forces the behaviour to commit. The same pattern fixes almost every threshold-driven oscillation in robot code, not just this one.
Ultrasonic or laser time-of-flight for obstacle avoidance?
They fail on opposite things, which is what makes the choice easy once you know your environment. Ultrasonic has a wide cone—roughly 15° of half-angle—so it detects a table leg it cannot locate, and it is blind to soft and steeply angled surfaces. A VL53L0X laser sensor has a narrow beam, so it locates precisely but can miss a thin obstacle entirely, and it struggles with dark, matte and mirrored surfaces in bright ambient light. For wandering a cluttered room, the wide sonar cone is genuinely an advantage. For measuring the distance to a specific thing, the laser wins.
Do I need a state machine for obstacle avoidance?
You need one the moment the behaviour has more than two states, and obstacle avoidance reaches that almost immediately: drive, stop, scan, turn, back up, recover. Written as nested conditionals it becomes unreadable within an afternoon, and worse, you lose the ability to answer 'what is the robot doing right now'—which is the question every debugging session starts with. An explicit state machine makes that a single variable you can print.
Can a reactive robot get stuck?
Yes, and it is a property of the approach rather than a bug you can fix. A robot with no memory in a concave corner or a U-shaped dead end will turn toward the most open direction, drive, and arrive back where it started, forever. The usual mitigations are a random component in the turn choice, and a stuck-detector that triggers a bigger escape manoeuvre after several failed attempts. The real fix is memory, which means a map—and that is a different path.