AUTO · Group Project · 2026 S1

QBot AutonomousNavigation System

A single Simulink behaviour-arbitration model running on the Quanser QBot Platform. It follows a line, reads traffic signals, avoids obstacles, builds a live occupancy map, and stops at a coloured target — autonomously, on real hardware.

5
Tasks
5
Behaviours
501×501
Map grid
3 min
Run cap
QBot Platform
RealSense D435
Leishen M10P LIDAR
LED [0 1 1] cyan
scroll

01The Task

The demo course requires sequential autonomous operation through five distinct phases — from initial line detection through to target acquisition — within a hard 3-minute run cap. Course layout varies between runs.

3 min
3-minute run cap
Hard limit — robot must complete all tasks
Demo course top-down view
01Line entry
02Map zone
03Traffic
04Obstacles
05Pink target

Demo course — top-down view

Guided tour — labelled course zones from line entry to pink target

Course layout varies between runs — obstacles, signals, and target position change

01

Blue Line Follow

Detect the blue floor strip with the downward camera and follow it onto the course using proportional centroid control.

02

Build a Map

Fuse RealSense depth point clouds into a persistent 501×501 uint8 occupancy grid as the robot navigates.

03

Traffic Compliance

Detect red (stop) and yellow (slow) traffic signals with the forward RGB camera and respond with the correct motion command.

04

Obstacle Avoidance

Detect and avoid obstacles using depth imagery — close-range only, splitting the point cloud left/right and steering away from the nearer side.

05

Target Approach & Stop

Detect the pink target, approach it proportionally, and stop precisely when target area exceeds 1500 px².

02System Architecture

The complete system is one Simulink model running on the QBot. Every control tick, each behaviour module produces a wheel-velocity vector and a status flag. The arbiter selects exactly one winner and drives the motors — no behaviour holds the motors directly.

Intel RealSense D435 + LIDAR

Intel RealSense D435 + LIDAR

Forward RGB + depth — traffic, target, obstacles, mapping

Drive base & encoders

Drive base & encoders

Differential drive — wheel encoders feed odometry

Sensors

Wheel Encoders
→ odometry pose x, y, θ
RealSense Depth
→ local point cloud, obstacle avoidance
RealSense RGB
→ pink target, red/yellow traffic
Downward Camera
→ blue line follower
LIDAR
→ workspace log only (not navigation)

Behaviour Modules

Traffic (Red/Yellow)S1
Pink TargetS2
Blue Line FollowS4
Obstacle AvoidanceS3
Default Cruisealways
Occupancy Map
PC2Map fuses point clouds into a persistent 501×501 grid (20×20 m, ~4 cm/px)

Arbiter → Motors

Behaviour_Control
9 inputs → 1 winner
Output: [vL; vR]
QBot Motors
vL · vR → Stream Client

S2 == 2 (pink goal reached) sits above all flags — it fires a hard stop before any other behaviour can respond.

Top-level signal flow of the Simulink model — sensors → behaviour modules → arbiter → motor commands, every control tick.

Top-level Simulink model

Top-level Simulink model — as implemented on the QBot

Why Subsumption?

Priority-based arbitration is deterministic and transparent — exactly one behaviour wins every tick with no ambiguous transitions. Easier to debug and tune than a state machine with explicit transition guards.

Two Sample Rates

Motor commands run at the QBot step size. Perception, mapping, and the arbiter run at 10× slower. Rate Transitions bridge the boundary — fast enough for smooth control, slow enough for vision processing.

LIDAR: Logged Only

LIDAR data is logged to workspace via To Workspace blocks but not used for navigation. Deliberate choice: the RealSense depth gives forward-facing obstacle data sufficient for the course, and fusing LIDAR mid-semester would have introduced more integration risk than gain.

03Perception

Perception is how the QBot turns raw camera and depth frames into the five decisions it has to make on the course. Four of the five behaviours share one colour pipeline; the depth camera runs a parallel path that builds the map and watches for obstacles. The subsections below follow the order the robot actually uses them.

Shared 3-stage colour pipeline

Blue-line, target and traffic detection all run the same three stages. Only the threshold and the action at the end differ.

  1. 1
    Segment
    Threshold the frame into a binary mask of the target colour
  2. 2
    Measure
    Compute the mask area A and its horizontal centroid xc
  3. 3
    Act
    Compare xc to the image centre → proportional wheel command; use A for distance / goal logic
Why chromaticity?

Standard RGB is sensitive to lighting — a well-lit card and a shadowed card of the same colour give different R,G,B values. Chromaticity divides each channel by the total intensity, leaving only the colour ratio. The result is near-invariant to illumination, which mattered when the course lighting changed between calibration and demo day.

Normalisation formula
total = R + G + B + ε

r = R / total
g = G / total
b = B / total
ε prevents divide-by-zero on black pixels
03.1

Environment Mapping

Requirement 2 · Map an unknown environmentsensor: RealSense D435 depth → point cloud

The course layout is unknown and changes between runs, so the robot builds its own map as it drives. Each depth frame becomes a local point cloud, is transformed into the world frame using the odometry pose, then blended into a single persistent occupancy grid. A persistent map variable means the grid is never reset between time steps — it accumulates across the whole run.

Each new scan only nudges the grid: occupied detections raise a cell toward 255, free-space detections slowly clear it back toward 0. Low blend weight keeps a single noisy frame from corrupting the map.

Parameters & tuning
map_size501 × 501 px

Too small and the full course won't fit on the grid; covers 20 × 20 m here.

resolution~4 cm / px

Too fine and the model gets heavy — it can slow the real-time run or crash the QBot.

w (update)0.01

Too high → noisy map; too low → the map updates too slowly to be useful. Tune when the map looks noisy, too small, or runs slow.

Environment Mapping

Depth camera → 501×501 occupancy grid — good run at cruise speed

Grid specification
size501 × 501 cells (uint8)
world coverage20 × 20 m
resolution~4 cm per pixel
originrobot start position (251, 251)
init value0 = free space (all cells)
occupied255 = fully occupied
Update rule
grid(u, v) = (1 - w) × grid(u, v)
            + w × new_obs

w = 0.01  (blend weight)

Low w prevents a single noisy frame corrupting the grid; each occupied detection increments steadily while free-space detections slowly clear cells.

Point cloud pipeline
  1. 1
    RealSense depth frame
    Raw 16-bit depth at 30 fps
  2. 2
    Reproject to 3D
    Each pixel → local (X, Y, Z) point using camera intrinsics
  3. 3
    Transform to world frame
    Rotate and translate by current odometry pose (x, y, θ)
  4. 4
    Project to grid cell
    world_X / 0.04 + 251, world_Y / 0.04 + 251 → integer (u, v)
  5. 5
    Blend into grid
    Apply the update rule with w = 0.01; clamp to [0, 255]
Cell padding

Each occupied cell is thickened by a 5 × 5 px neighbourhood before the grid is used. At 4 cm/px the robot body is ~4.5 px wide, so the padding lets any path planner treat the robot as a point while keeping clearance around real obstacles.

Keeping it real-time

Compressed video display was used instead of full video, and unnecessary scopes/displays were stripped, so the mapping load doesn't starve the control loop.

03.2

Blue Line Following

Requirement 1 · Navigate to the obstacle coursesensor: Downward camera → intensity channel

The robot enters the course by following a blue floor line with its downward camera. The frame is segmented for blue pixels; from that mask the model takes the blue area A and the line centroid xc, then steers proportionally to keep the line centred.

Intensity [80, 180]

Raw brightness, not chromaticity — the blue line is distinct enough in the brightness channel that normalising adds nothing.

  1. 01Line near image centre → both wheels forward
  2. 02Line to the left of centre → turn left
  3. 03Line to the right of centre → turn right
  4. 04Line area drops below threshold → BlueLock + last_turn memory recover the line
Parameters & tuning
Amin570 px²

Minimum blue area to confirm the line is visible. Too high → thinks the line is lost too often; too low → noise gets treated as the line.

Agoal

Area used to decide the line has ended. Too high → leaves the line early; too low → keeps searching for blue after it ends.

deadzone±5 px

Suppresses tiny centroid errors. Increase if the robot wiggles; reduce if it misses sharp turns.

Kp

Correction strength. Increase if it turns too slowly; reduce if it oscillates.

V_A

Forward speed — high enough to finish in time, low enough not to overshoot corners or stall the motors.

Blue Line Following

Downward camera — raw frame, intensity channel [80, 180]

Line-loss recovery

A BlueLock flag and last_turn memory hold the robot's intent through intersections and momentary line loss, so a single dropped frame doesn't hand control to another behaviour.

03.3

Target Detection & Approach

Requirement 3 · Approach the targetsensor: Forward RGB camera → chromaticity

Once the pink target is detected, the robot steers toward its centroid exactly like line following — left of centre turn left, right of centre turn right, centred move forward. The target area doubles as a distance estimate: as the robot closes in, the pink area grows.

r ∈ [0.40, 0.49]

Pink target isolated by chromaticity so the threshold survives the lighting change between calibration and demo.

  1. 01Pink detected → steer proportionally toward its centroid
  2. 02Pink area grows as the robot approaches
  3. 03Area exceeds Agoal → status becomes 2 (goal reached)
  4. 04Status 2 → hard stop, highest priority in the arbiter
Parameters & tuning
A_goal_pink1500 px²

Stop threshold (~0.5 m standoff). Too low → stops too late / too close; too high → stops too early. Tune during target-stopping tests; requirement is to stop within 1 m.

A_min_pink50 px²

Minimum area for a confident detection — below this the centroid is unreliable.

Target Detection & Approach

Forward camera — raw frame → chromaticity mask r ∈ [0.40, 0.49]

StopFlips hysteresis — 0.3 s hold

When the target straddles the image centre, left/right oscillation can occur. A 0.3 s hold on the last steering command stops the robot flipping direction every tick.

03.4

Traffic Signal Recognition

Requirement 4 · Obey traffic signalssensor: Forward RGB camera → chromaticity

The forward RGB camera detects red and yellow signals by chromaticity. The response is priority-based: red means stop, yellow means slow down and proceed with caution — yellow never brings the robot to a full halt because it represents caution, not a stop.

red r ∈ [0.78, 0.95] · yellow r ∈ [0.47, 0.60]

Two chromaticity bands on the same forward camera distinguish a stop signal from a slow signal.

  1. 01Red detected → stop and hold until the signal clears
  2. 02Yellow detected → reduce speed, keep moving carefully
  3. 03Neither → continue with the active navigation behaviour
Parameters & tuning
red / yellow thresholdschromaticity bands

Too low → reacts to noise; too high → misses the signal. Tune under the actual demo lighting.

area thresholds

Minimum coloured area before a signal is accepted — filters out small false detections.

Traffic Signal Recognition

Red / yellow chromaticity threshold — stop or slow

03.5

Obstacle Avoidance

Requirement 5 · Avoid collisions at all timessensor: RealSense depth → point cloud (split L / R)

The final design uses close-range avoidance only. The point cloud is split into a left and a right half and the controller takes the minimum distance on each side. Whichever side has the nearer obstacle inside the close threshold, the robot turns away from it.

  1. 01Split the point cloud into left and right halves
  2. 02Take the minimum distance on each side
  3. 03Obstacle close on the left → turn right
  4. 04Obstacle close on the right → turn left
Parameters & tuning
th (close threshold)0.5 m

Distance that triggers avoidance. Too high → turns too early and oscillates; too low → may not avoid in time. Tune when it reacts too early or nearly clips an obstacle.

turn_time (StopFlips)0.3 s

How long the robot commits to one turn direction before a flip is allowed. Too short → still flickers left↔right; too long → keeps turning after the path is clear.

Obstacle Avoidance

Close-range avoidance — point cloud split left / right

Far avoidance was removed

Far-range avoidance was tested but cut — on a tight course it reacts too early, causing unnecessary turning, hesitation and getting wedged between obstacles. Kept as a system-improvement talking point for the report (see 4.4).

Group SIX · QBot Platform on course

04Behaviour Arbitration

Every tick, the arbiter receives nine inputs — five velocity vectors, four status flags. Six lines of MATLAB select one winner. Priority is fixed: safety first, task second, nominal cruise as fallback.

1
Pink Goal Reachedsafety
Condition: S2 == 2
Output: V = [0 0]′ (full stop)
Highest-priority flag. Once the pink target area exceeds 1500 px², the robot is commanded to zero velocity permanently. No behaviour can override this.
2
Traffic (Red / Yellow)safety
Condition: S1 == true
Output: V = V1 (stop or slow)
Red signal → V1 = [0 0]. Yellow signal → V1 = reduced cruise. Both detected via forward RGB camera chromaticity.
3
Pink Target Approachtask
Condition: S2 == 1
Output: V = V2 (proportional steer)
Proportional controller steers toward centroid of pink mask. Centroid offset → differential wheel speed.
4
Blue Line Followtask
Condition: S4 == true
Output: V = V4 (centroid track)
Centroid of blue mask drives proportional correction. BlueLock flag and last_turn memory handle momentary line loss. Sits above obstacle avoidance — line-following resumes as soon as safety/task triggers clear.
5
Obstacle Avoidancetask
Condition: S3 == true
Output: V = V3 (steer away)
Point cloud is split left/right; the robot turns away from whichever side has the nearest return inside the close threshold (th = 0.5 m). A StopFlips hold (turn_time) prevents left↔right flicker. Far-range avoidance was removed — the course is too tight for early steering.
6
Default Cruisenominal
Condition: else
Output: V = V5 (constant forward)
Fixed-speed forward drive when no other behaviour fires. Keeps the robot moving between task phases.
Close Obstacle Avoidance

The point cloud is split into left and right halves and the controller takes the nearest return on each side. If an obstacle falls inside th on one side, the robot steers away from it. Far-range avoidance was removed — on a tight course it reacts too early.

th0.5 m — close threshold
splitpoint cloud → left / right
ruleturn away from nearer side
turn_time0.3 s StopFlips hold
Blue Line Follower State

The blue line follower uses a BlueLock flag and last_turn memory to handle intersections and momentary line loss. Once locked onto the line, it stays committed until task completion.

BlueLockbool — line acquired
last_turnmemory — last steering direction
priority3 of 5 — below stop/task, above obstacle
Design Tradeoff: Blue Line > Obstacle

Blue line follow (priority 4) sits above obstacle avoidance (priority 5). Once safety/task triggers clear, the robot immediately resumes line tracking rather than entering avoidance — keeping it on course. Obstacle avoidance still fires when S3 is true and no line is detected, so cornered situations are still handled.

05Parameters

These are not defaults. Each value was taken from the Quanser hardware specification or tuned through iterative lab testing. The rationale column records what we tried first.

ParameterValueUnitDescriptionCategory
r_wheel0.04445mWheel radius — encoder pulse → arc length. Quanser QBot Platform spec, verified by square-path test.Platform
L_wheel0.3928mWheel base — arc → heading change in RL2Centre differential drive model.Platform
v_cruise4rad/sDefault cruise speed (V5). Balance of run time vs odometry accuracy — 6 rad/s increased mapping artefacts noticeably.Control
w_localmap0.01Map update weight. Low weight prevents one noisy frame corrupting the grid. 0.2 caused severe artefacts in W12 lab.Mapping
wall_pad5×5pxNeighbourhood thickening on each occupied cell. Robot is ~4.5 px wide at 4 cm/px — 5×5 ensures planner clearance.Mapping
map_size501×501pxOccupancy grid dimensions. Covers 20×20 m at 4 cm/px resolution.Mapping
th0.5mClose obstacle threshold. Point cloud split L/R, robot turns away from the nearer side. Too high → turns too early/oscillates; too low → may not avoid in time. Far avoidance removed for the tight course.Behaviour
turn_time0.3sStopFlips hold. Commits to one turn direction before a left↔right flip is allowed. Used on both obstacle avoidance and pink approach. Too short → still flickers; too long → keeps turning when clear.Behaviour
A_goal_pink1500px²Pink target area stop threshold. ~0.5 m standoff at typical target size. 800 → too far; 2000 → too close.Colour
A_min_pink50px²Minimum pink area for confident detection. Below this, centroid is unreliable.Colour
A_min_blue570px²Blue line minimum area before line-loss recovery. 300 triggered recovery too often on faded floor markings.Colour
blue_deadzone±5pxCentroid deadzone before proportional correction activates. ±5 px ≈ 3° heading error. ±2 caused snaking.Colour
r_pink[0.40–0.49]Pink chromaticity r-channel range.Colour
r_red[0.78–0.95]Red (stop signal) chromaticity r-channel range.Colour
r_yellow[0.47–0.60]Yellow (slow signal) chromaticity r-channel range.Colour
blue_intensity[80–180]Blue line raw intensity threshold (not chromaticity). Downward camera channel.Colour

16 of 16 parameters shown

06Results & Improvements

Results will be updated after the Week 14 demo run. Task scorecard, timing, and map screenshots are placeholders pending the live evaluation.

Task Scorecard

TaskMetricResultStatus
Blue Line FollowLine acquired + followedTBDTBD
Occupancy MappingGrid populated, no artefactsTBDTBD
Traffic ComplianceStop on red, slow on yellowTBDTBD
Obstacle AvoidanceNo contact with obstaclesTBDTBD
Target Approach & StopStop ≤ 0.5 m from pinkTBDTBD

Timing Breakdown

~15 s
Line acquisition
From start to stable BlueLock on line
~35 s
Line follow + map
Tracking line, occupancy grid building continuously
~40 s
Traffic zone
Approach + red stop (variable) + slow on yellow + clearance
~50 s
Obstacle section
Close-range steer-away — point cloud split left/right, turn from nearer side
~30 s
Pink approach
Proportional closure, stops when area ≥ 1500 px²
~170 s
Total
Under the 3 min hard limit

Demo day — real run footage

QBot Platform as-built — front

QBot Platform as-built — front

QBot Platform as-built — rear

QBot Platform as-built — rear

Lessons Learned
1

A map update weight of 0.01 sounds tiny but accumulates reliably over multiple passes — starting at 0.2 was our biggest early mistake.

2

The StopFlips hysteresis was not in the original design. One lab run revealed left-right oscillation so severe the robot barely moved. 0.3 s fixed it immediately.

3

LIDAR is already wired — we just don't fuse it. Every future team should fuse it from day one for full 360° awareness.

4

Chromaticity is genuinely robust to lighting. We tested under three different lab lighting conditions and the same thresholds worked each time.

5

Far-range obstacle avoidance was tested and removed — on a tight course it steers too early and the robot hesitates or wedges between obstacles. Close-only avoidance with a StopFlips hold proved far more reliable.