Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Full Resolution Wheel Encoder #72

Merged
merged 28 commits into from
May 31, 2024
Merged
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
d11ad29
wheel_encoder_full_resolution
SM-dot May 25, 2024
e57e7f0
Update wheel_encoder.rs
SM-dot May 28, 2024
10fdbd9
Update wheel_encoder.rs
SM-dot May 28, 2024
295bb89
Update wheel_encoder.rs
SM-dot May 29, 2024
8d0a469
handling Err for wheel_encoder
SM-dot May 29, 2024
0a8eb50
Err handling in state_machine.rs
SM-dot May 29, 2024
896f575
fixing mismatched error types
SM-dot May 29, 2024
29e9198
-cleanup
SM-dot May 29, 2024
652aa82
sm - cleanup
ryescholin May 29, 2024
b8b768e
measure function only
SM-dot May 29, 2024
347d83d
simplified to a single function only
SM-dot May 29, 2024
66abaa7
fixing measure call
SM-dot May 29, 2024
14ffad8
threshold only using distance values
SM-dot May 29, 2024
4be1cf3
-cleanup
SM-dot May 29, 2024
bb98d9c
cleanup
SM-dot May 29, 2024
74c23bf
chk
ryescholin May 29, 2024
46ba52a
import cleanup
SM-dot May 29, 2024
139152f
import cleanup
SM-dot May 29, 2024
082064a
time import
SM-dot May 30, 2024
079626c
Changing pin numbers
SM-dot May 30, 2024
20f254a
Merge branch 'main' into 58-pod-improve-wheel-encoder-measurements
taesungh May 30, 2024
c4e42a6
Upgrade RPPAL to v0.18.0 for `InputPin` with RPi 5
taesungh May 30, 2024
ba569a1
Reimplement encoder transitions and measurement
taesungh May 30, 2024
2759afa
Fix wheel encoder initialization in main
taesungh May 30, 2024
ae6e33e
Fix lint issues
taesungh May 30, 2024
c562026
Add resting velocity and wheel diameter
taesungh May 30, 2024
e12acfd
Clean up encoder enums
taesungh May 30, 2024
aff1895
Remove other full-resolution copy
taesungh May 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions pod-operation/src/components/wheel_encoder_full_resolution.rs
taesungh marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
use rppal::gpio::{Gpio, InputPin};
use std::thread;
use std::time::{Duration, Instant};
use tracing::{debug, error, info};

// GPIO pins for the encoder
const PIN_ENCODER_A: u8 = 14;
const PIN_ENCODER_B: u8 = 15;

// Constants for calculations
const DELTA_D: f64 = 1.0 / 16.0;

type EncoderState = u8;
type EncoderDiff = i8;

// Function to encode the state
// 00, 01, 10, 11
fn encode_state(a: bool, b: bool) -> EncoderState {
((a as u8) << 1) + (a as u8 ^ b as u8)
}

// Function to calculate the difference in states
// -1 => moving backwards
// 0 => no movement
// 1 => moving forward
// 2 => Undersampling
fn state_difference(p: EncoderState, q: EncoderState) -> EncoderDiff {
((p as i8 - q as i8 + 1) % 4 - 1) as EncoderDiff
}

// Struct to represent the wheel encoder
pub struct WheelEncoder {
counter: i32,
last_time: Instant,
last_state: EncoderState,
pin_a: InputPin,
pin_b: InputPin,
faulted: bool,
}

impl WheelEncoder {
// Constructor to initialize the encoder
pub fn new() -> Result<Self, rppal::gpio::Error> {
let gpio = Gpio::new()?;
let pin_a = gpio.get(PIN_ENCODER_A)?.into_input();
let pin_b = gpio.get(PIN_ENCODER_B)?.into_input();

let initial_state = encode_state(pin_a.is_high(), pin_b.is_high());

Ok(WheelEncoder {
counter: 0,
last_time: Instant::now(),
last_state: initial_state,
pin_a,
pin_b,
faulted: false,
})
}

// Method to measure speed and distance
pub fn measure(&mut self) -> Result<(f64, f64), &'static str> {
if self.faulted {
return Err("WheelEncoder is in Faulted state");
}

let current_time = Instant::now();
let state = self.read_state();

let mut speed = 0.0;
let inc = state_difference(state, self.last_state);

if inc == 2 {
self.faulted = true;
return Err("Undersampling. Transition to Faulted state please.");
}

if inc != 0 {
let delta_t = current_time.duration_since(self.last_time).as_secs_f64();
speed = inc as f64 * DELTA_D / delta_t;
self.last_time = current_time;
}

self.last_state = state;
self.counter += inc as i32;

let distance = self.counter as f64 * DELTA_D;

Ok((speed, distance))
}

// Private method to read the state of the encoder
fn read_state(&self) -> EncoderState {
encode_state(self.pin_a.is_high(), self.pin_b.is_high())
}
}