<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.bespokerobotsociety.org/index.php?action=history&amp;feed=atom&amp;title=Capability%3AOptical_Odometry</id>
	<title>Capability:Optical Odometry - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.bespokerobotsociety.org/index.php?action=history&amp;feed=atom&amp;title=Capability%3AOptical_Odometry"/>
	<link rel="alternate" type="text/html" href="https://wiki.bespokerobotsociety.org/index.php?title=Capability:Optical_Odometry&amp;action=history"/>
	<updated>2026-04-25T11:25:26Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://wiki.bespokerobotsociety.org/index.php?title=Capability:Optical_Odometry&amp;diff=28&amp;oldid=prev</id>
		<title>John: Claude edited based on my notes, prompt, and SimpleBot code repository</title>
		<link rel="alternate" type="text/html" href="https://wiki.bespokerobotsociety.org/index.php?title=Capability:Optical_Odometry&amp;diff=28&amp;oldid=prev"/>
		<updated>2025-10-11T16:16:39Z</updated>

		<summary type="html">&lt;p&gt;Claude edited based on my notes, prompt, and SimpleBot code repository&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Capability&lt;br /&gt;
|name=Optical Odometry&lt;br /&gt;
|type=Sensing&lt;br /&gt;
|measures=Wheel rotation distance by counting optical encoder pulses&lt;br /&gt;
|hardware=Slotted encoder wheels + IR LED/photoresistor pairs + comparator ([[LM393]])&lt;br /&gt;
|enables=[[Activity:Dead Reckoning Navigation]], distance measurement, speed control&lt;br /&gt;
|used_in=[[SimpleBot]]&lt;br /&gt;
|status=Fully Documented&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Optical odometry&amp;#039;&amp;#039;&amp;#039; is a method of measuring a robot&amp;#039;s motion by optically detecting the rotation of its wheels. By counting pulses generated as slotted encoder wheels rotate, a microcontroller can calculate distance traveled, speed, and (for differential drive robots) changes in heading angle. This forms the foundation for [[Activity:Dead Reckoning Navigation]].&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Odometry comes from the Greek words &amp;#039;&amp;#039;hodos&amp;#039;&amp;#039; (journey) and &amp;#039;&amp;#039;metron&amp;#039;&amp;#039; (measure). Optical odometry specifically uses optical sensors to detect wheel rotation, converting mechanical motion into electrical pulses that can be counted digitally.&lt;br /&gt;
&lt;br /&gt;
Unlike GPS which measures absolute position, odometry measures &amp;#039;&amp;#039;relative&amp;#039;&amp;#039; motion - how far the robot has moved from its starting point. This makes it work indoors, require no external infrastructure, and provide high-frequency updates (typically 100+ Hz), but it suffers from cumulative drift over long distances.&lt;br /&gt;
&lt;br /&gt;
== How It Works ==&lt;br /&gt;
&lt;br /&gt;
The optical odometry system consists of four key components working together:&lt;br /&gt;
&lt;br /&gt;
=== Encoder Wheel ===&lt;br /&gt;
&lt;br /&gt;
A disc with evenly-spaced slots (or alternatively, alternating black/white segments) is rigidly attached to either:&lt;br /&gt;
* The drive wheel itself (SimpleBot approach)&lt;br /&gt;
* The motor output shaft before the gearbox&lt;br /&gt;
&lt;br /&gt;
As the wheel or shaft rotates, the slots pass between an emitter and detector.&lt;br /&gt;
&lt;br /&gt;
=== Optical Emitter ===&lt;br /&gt;
&lt;br /&gt;
An infrared LED provides a constant light source aimed at the detector. IR is preferred over visible light because:&lt;br /&gt;
* Less susceptible to ambient light interference&lt;br /&gt;
* Standard photoresistors and phototransistors have good IR sensitivity&lt;br /&gt;
* Does not distract operators with visible blinking&lt;br /&gt;
&lt;br /&gt;
=== Optical Detector ===&lt;br /&gt;
&lt;br /&gt;
A photoresistor (CdS cell) or phototransistor detects the light. When a slot passes by, light reaches the detector (low resistance/high current). When the solid part of the wheel blocks the light, the detector sees darkness (high resistance/low current). This creates an analog signal that oscillates between two voltage levels.&lt;br /&gt;
&lt;br /&gt;
=== Signal Conditioning ===&lt;br /&gt;
&lt;br /&gt;
The analog signal from the detector is converted to clean digital pulses using a comparator IC such as the [[LM393]]. The comparator has:&lt;br /&gt;
* A reference voltage (threshold) on one input&lt;br /&gt;
* The detector signal on the other input&lt;br /&gt;
* Digital output: HIGH when light detected, LOW when blocked&lt;br /&gt;
&lt;br /&gt;
This produces clean square waves suitable for microcontroller interrupt pins or counter inputs.&lt;br /&gt;
&lt;br /&gt;
== Implementation Approaches ==&lt;br /&gt;
&lt;br /&gt;
=== Wheel-Based Encoding (SimpleBot) ===&lt;br /&gt;
&lt;br /&gt;
[[SimpleBot]] attaches slotted encoder wheels directly to the drive wheels.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Advantages:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Simple mechanical attachment&lt;br /&gt;
* Directly measures wheel rotation (what you care about for odometry)&lt;br /&gt;
* No need for special motors with built-in encoders&lt;br /&gt;
* Easy to retrofit to existing robots&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Disadvantages:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Adds width to the robot&lt;br /&gt;
* Wheel slippage affects both propulsion &amp;#039;&amp;#039;and&amp;#039;&amp;#039; measurement equally&lt;br /&gt;
* Lower resolution unless using large diameter encoder wheels&lt;br /&gt;
&lt;br /&gt;
=== Motor Shaft Encoding ===&lt;br /&gt;
&lt;br /&gt;
Many commercial motors include quadrature encoders on the motor shaft before the gearbox.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Advantages:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Very high resolution (motor shaft spins faster than wheel)&lt;br /&gt;
* Compact - built into motor housing&lt;br /&gt;
* Can detect wheel slippage (motor turns but wheel doesn&amp;#039;t)&lt;br /&gt;
* Often provides direction information via quadrature encoding&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Disadvantages:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Requires encoder-equipped motors (more expensive)&lt;br /&gt;
* Gearbox backlash between motor and wheel&lt;br /&gt;
* Must account for gear ratio in calculations&lt;br /&gt;
&lt;br /&gt;
== Resolution and Distance Calculation ==&lt;br /&gt;
&lt;br /&gt;
The encoder&amp;#039;s &amp;#039;&amp;#039;&amp;#039;resolution&amp;#039;&amp;#039;&amp;#039; determines how precisely distance can be measured.&lt;br /&gt;
&lt;br /&gt;
=== Basic Formula ===&lt;br /&gt;
&lt;br /&gt;
For a wheel-based encoder:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\text{Distance per pulse} = \frac{\pi \times D}{N}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where:&lt;br /&gt;
* &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; = wheel diameter&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; = number of slots in encoder wheel&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example (SimpleBot):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Wheel diameter: 65mm&lt;br /&gt;
* Encoder slots: 20&lt;br /&gt;
* Distance per pulse: &amp;lt;math&amp;gt;\frac{\pi \times 65\text{mm}}{20} = 10.2\text{mm}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To calculate distance traveled:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\text{Distance} = \text{Pulses counted} \times \frac{\pi \times D}{N}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Motor Shaft Encoders ===&lt;br /&gt;
&lt;br /&gt;
For motor shaft encoders, include the gear ratio:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\text{Distance per pulse} = \frac{\pi \times D}{N \times G}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; is the gear ratio.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Wheel diameter: 70mm&lt;br /&gt;
* Motor encoder pulses per revolution: 64&lt;br /&gt;
* Gear ratio: 120:1&lt;br /&gt;
* Distance per pulse: &amp;lt;math&amp;gt;\frac{\pi \times 70}{64 \times 120} = 0.029\text{mm}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This much higher resolution is why shaft encoders are preferred in precision applications.&lt;br /&gt;
&lt;br /&gt;
== Accuracy and Error Sources ==&lt;br /&gt;
&lt;br /&gt;
Optical odometry is subject to several error sources that cause the calculated position to drift from the true position:&lt;br /&gt;
&lt;br /&gt;
=== Wheel Slip ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;The dominant error source.&amp;#039;&amp;#039;&amp;#039; When wheels slip on the surface:&lt;br /&gt;
* The wheel rotates but the robot doesn&amp;#039;t move proportionally&lt;br /&gt;
* Encoder counts pulses but robot travels less distance&lt;br /&gt;
* Turns on slippery surfaces are especially problematic&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Mitigation:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Use high-traction wheels (rubber, not hard plastic)&lt;br /&gt;
* Avoid sudden acceleration/deceleration&lt;br /&gt;
* Keep robot weight low to reduce momentum&lt;br /&gt;
* Slower speeds reduce slip&lt;br /&gt;
&lt;br /&gt;
=== Encoder Resolution ===&lt;br /&gt;
&lt;br /&gt;
Limited resolution means distance is quantized. With SimpleBot&amp;#039;s ~10mm per pulse:&lt;br /&gt;
* Distances between 0-10mm all register as &amp;quot;0&amp;quot;&lt;br /&gt;
* Actual distance of 15mm registers as &amp;quot;10mm&amp;quot;&lt;br /&gt;
* This causes ±5-10mm random error per measurement&lt;br /&gt;
&lt;br /&gt;
Higher resolution encoders (more slots, or motor shaft encoders) reduce this error.&lt;br /&gt;
&lt;br /&gt;
=== Mechanical Issues ===&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Backlash:&amp;#039;&amp;#039;&amp;#039; Play in gearboxes causes encoder to turn without wheel moving&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Wheel diameter variation:&amp;#039;&amp;#039;&amp;#039; Wear, tire pressure, or asymmetric wheels cause errors&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Axle flexing:&amp;#039;&amp;#039;&amp;#039; On flexible chassis, wheels may move without encoder detecting it&lt;br /&gt;
&lt;br /&gt;
=== Calibration Errors ===&lt;br /&gt;
&lt;br /&gt;
* Incorrect wheel diameter measurement (measure loaded wheel, not unloaded)&lt;br /&gt;
* Miscounted encoder slots&lt;br /&gt;
* Incorrect gear ratio&lt;br /&gt;
&lt;br /&gt;
=== Typical Performance ===&lt;br /&gt;
&lt;br /&gt;
For a well-built system like SimpleBot with wheel-based encoders:&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Short distances (&amp;lt; 1m):&amp;#039;&amp;#039;&amp;#039; ±5% error&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Medium distances (1-3m):&amp;#039;&amp;#039;&amp;#039; ±10-15% error&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Long distances (&amp;gt; 3m):&amp;#039;&amp;#039;&amp;#039; Drift becomes significant (±20%+)&lt;br /&gt;
&lt;br /&gt;
The error is &amp;#039;&amp;#039;&amp;#039;cumulative&amp;#039;&amp;#039;&amp;#039; - it grows with distance traveled, not with time. This is because each wheel rotation measurement includes a small error, and these errors add up.&lt;br /&gt;
&lt;br /&gt;
== Differential Drive Odometry ==&lt;br /&gt;
&lt;br /&gt;
For differential drive robots like SimpleBot, having independent encoders on left and right wheels enables both position and orientation tracking.&lt;br /&gt;
&lt;br /&gt;
=== Position Update Equations ===&lt;br /&gt;
&lt;br /&gt;
Given pulse counts since last update (&amp;lt;math&amp;gt;P_L&amp;lt;/math&amp;gt; for left, &amp;lt;math&amp;gt;P_R&amp;lt;/math&amp;gt; for right):&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
D_L = P_L \times \frac{\pi D}{N}, \quad D_R = P_R \times \frac{\pi D}{N}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
D_{center} = \frac{D_L + D_R}{2}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\Delta\theta = \frac{D_R - D_L}{W}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where &amp;lt;math&amp;gt;W&amp;lt;/math&amp;gt; is the wheelbase (distance between wheels).&lt;br /&gt;
&lt;br /&gt;
The robot&amp;#039;s new position:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
x_{new} = x_{old} + D_{center} \cos(\theta_{old} + \Delta\theta/2)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
y_{new} = y_{old} + D_{center} \sin(\theta_{old} + \Delta\theta/2)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\theta_{new} = \theta_{old} + \Delta\theta&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These equations integrate wheel motion into a 2D pose estimate.&lt;br /&gt;
&lt;br /&gt;
=== Rotation Detection ===&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Equal forward pulses:&amp;#039;&amp;#039;&amp;#039; Straight line motion&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Unequal pulses:&amp;#039;&amp;#039;&amp;#039; Curved path (arc)&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Left forward, right backward (or vice versa):&amp;#039;&amp;#039;&amp;#039; Rotation in place&lt;br /&gt;
&lt;br /&gt;
This allows the robot to maintain an estimated heading angle, critical for [[Activity:Dead Reckoning Navigation]].&lt;br /&gt;
&lt;br /&gt;
== SimpleBot Implementation ==&lt;br /&gt;
&lt;br /&gt;
SimpleBot uses a straightforward wheel-based optical odometry system:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Hardware:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* 20-slot laser-cut acrylic encoder wheels mounted on drive wheel hubs&lt;br /&gt;
* Infrared LED emitters (940nm typical)&lt;br /&gt;
* CdS photoresistor detectors&lt;br /&gt;
* [[LM393]] dual comparator IC for signal conditioning&lt;br /&gt;
* Encoder wheels positioned outside the main chassis, with emitter/detector in slots&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Circuit:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* LED connected through current-limiting resistor to constant power&lt;br /&gt;
* Photoresistor in voltage divider configuration&lt;br /&gt;
* Comparator compares detector voltage to adjustable reference voltage (potentiometer)&lt;br /&gt;
* Output connects to microcontroller interrupt-capable pins&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Software:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Interrupt service routine (ISR) increments counter on each pulse&lt;br /&gt;
* Main loop periodically reads counters and calculates distance/position&lt;br /&gt;
* Counters reset after each position update to avoid overflow&lt;br /&gt;
&lt;br /&gt;
The system provides approximately 10mm resolution per pulse, adequate for SimpleBot&amp;#039;s educational mission while remaining mechanically simple.&lt;br /&gt;
&lt;br /&gt;
== Comparison to Other Odometry Methods ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Method&lt;br /&gt;
! Resolution&lt;br /&gt;
! Cost&lt;br /&gt;
! Complexity&lt;br /&gt;
! Slip Detection&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Optical (wheel)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| Medium (5-20mm)&lt;br /&gt;
| Low ($2-5)&lt;br /&gt;
| Low&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Optical (shaft)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| High (0.01-0.1mm)&lt;br /&gt;
| Medium ($10-30)&lt;br /&gt;
| Medium&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Magnetic encoders&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| Medium-High&lt;br /&gt;
| Medium&lt;br /&gt;
| Medium&lt;br /&gt;
| Varies&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Visual odometry&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| Very High&lt;br /&gt;
| High ($50+)&lt;br /&gt;
| High&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;IMU integration&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
| Varies&lt;br /&gt;
| Medium&lt;br /&gt;
| High&lt;br /&gt;
| N/A (different principle)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
SimpleBot&amp;#039;s wheel-based optical approach prioritizes simplicity and cost over ultimate precision, making it ideal for education and hobby robotics.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Activity:Dead Reckoning Navigation]] - Primary use of odometry data&lt;br /&gt;
* [[LM393]] - Comparator IC used in SimpleBot implementation&lt;br /&gt;
* [[SimpleBot]] - Robot platform using this capability&lt;br /&gt;
* [[Capability:Differential Drive]] - Drive configuration that benefits from dual encoders&lt;br /&gt;
* [[Capability:IMU Sensing]] - Complementary sensor for orientation (can fuse with odometry)&lt;br /&gt;
&lt;br /&gt;
[[Category:Capability]]&lt;br /&gt;
[[Category:Sensing Capability]]&lt;/div&gt;</summary>
		<author><name>John</name></author>
	</entry>
</feed>