calebfletcher / foc

A Rust implementation of various Field Oriented Control algorithms.
Apache License 2.0
17 stars 3 forks source link

Tracking Issue: `embedded-hal` integration. #3

Open calebfletcher opened 6 months ago

calebfletcher commented 6 months ago

This tracking issue covers the integration of the crate with various embedded-hal traits.

Current state of embedded_hal in relation to what this crate needs:

Ben-PH commented 5 months ago

With respect to the common interface for counters, I'm not so confident in that RFC anymore. The concept I had in mind when bringing it up was that there is a common notion of counting, and it applies to many things: time-passage, pulses, etc. basically, anything that exists as a count of discrete measures (clock ticks, angle measured by encoders, etc) could be counted, but rust-embedded has dictated that no generic assosciated types are allowed.

This means that if there was to be a common interface, there cannot be an assosciated type that describes what you are counting. it has to be u32 or u64, which in my mind, completely contradicts the notion of portability.

I think what I'll do is just make a generic counter. It won't be embedded-hal, but it will be portable.

calebfletcher commented 5 months ago

@Ben-PH noted. For the moment I will likely be keeping the API such that the user supplies the angle directly, but that may change in the future.

Ben-PH commented 5 months ago

This is an early prototype of the trait:

/// Base encapsulation for reading a counting perihpereal, such as clock, pulse-counter, etc. 
/// Intended typical use-case would encapsulate the raw representation of the count-primitive,
/// with a representation of its scale/type.
/// and uses this interface to read a clock/timer/counter register.
pub trait Counter: Sized {
    /// A clock would typically use u32, or u64. 
    /// A pulse counter might use i32
    type RawData: Copy;

    /// A clock counter might use fugit::Duration
    /// A rortary encoder interfacing with a FieldOrientedControlled motor might use
    /// `ElecAngleRadians(fixed::I16U16)`
    type CountMeasure;

    type Error;

    /// Intended as an interface to a raw-data read
    fn try_count_raw(&self) -> Result<Self::RawData, Self::Error>;

    fn try_count(&self) -> Result<Self::CountMeasure, Self::Error> {
        Ok(<Self as Counter>::raw_to_measure(self.try_count_raw()?))
    }
    /// Think of this as `impl From<Self::RawData> for Self::CountMeasure`
    /// later iterations of this trait might constrain `CountMeasure` to impl the `From`
    fn raw_to_measure(from: Self::RawData) -> Self::CountMeasure;
}

For me, it makes sense for this crate to fixate on the raw FOC utilities. If this crate provides the algorithms needed, they can form the foundation of a hardware implementation.

I'm for some Simple FOC hardware to arrive in the mail before trying out one such implementation I've been working on: https://github.com/Ben-PH/SimpleFOC-rs/tree/dev

I would be happy to collaborate.

calebfletcher commented 5 months ago

Yeah I agree, my goal with this crate is to fill more of the algorithms side rather than dealing with the nitty-gritty of various hardware implementations. Your SimpleFOC work seems pretty interesting, and seeing how our two projects can interplay is definitely something I would be interested in pursuing.