Git Product home page Git Product logo

Comments (5)

jamwaffles avatar jamwaffles commented on June 2, 2024 1

I just merged #47 which is enormous, but buried within it removes GroupSlaves entirely. Hopefully a) you don't get too many conflicts and b) it makes your implementation a little easier.

from ethercrab.

jamwaffles avatar jamwaffles commented on June 2, 2024 1

Thanks for the discussion, however this isn't a direction I'd like to take EtherCrab in at this time.

from ethercrab.

jimy-byerley avatar jimy-byerley commented on June 2, 2024

I tested the proposed functions and structs yesterday, and I'm quite satisfied with them. What would you think of a PR ?

Note that my current use of these functions rely on a fix I made for #46 ...

from ethercrab.

jamwaffles avatar jamwaffles commented on June 2, 2024

The PRE-OP configuration idea looks quite nice, and might fit well into something that parses from ESI files.

In terms of reading/writing during OP mode, I was considering an API something like this very pseudo-code-ey idea:
Example 1: Servo drive

struct Ds402<'a> {
    pdi: SlavePdi<'a>

    // DS402 state machine, whatever else it needs
}

impl Ds402 {
    fn position(&self) -> u32 {
        self.position
    }

    fn set_position(&mut self, target: u32) {
        self.target_pos = target
    }

    fn state_machine_tick(&mut self) {
        // ...
    }
}

loop {
    tick.await;

    group.tx_rx().await;

    // NOTE: Need to figure out how to do `mut` here!
    let mut slave = group.slave::<SlaveRef<'_, Ds402>>(0);

    println!("Current pos: {}", slave.position());

    slave.set_position(slave.position() + 100);
}

Example 2: EL2004 quad output

struct El2004<'a> {
    pdi: SlavePdi<'a>
}

enum Pin {
    Pin1,
    Pin2,
    Pin3,
    Pin4,
}

impl Ds402 {
    fn set_pin(&mut self, pin: Pin, state: bool) {
        // ...
    }
}

loop {
    tick.await;

    group.tx_rx().await;

    // NOTE: Need to figure out how to do `mut` here!
    let mut slave = group.slave::<SlaveRef<'_, El2004>>(0);

    // Turn first pin on
    slave.set_pin(Pin::Pin1, true);
}

I like the idea of using typestates for this, even if they are validated only at runtime. I still have questions around that validation, e.g. if I try to select slave 0 as an El2004 but it is actually a Ds402 servo drive, that needs to return an error, but how do we check that?

Anyway, what do you think? I'm presenting the above as an idea, not the final solution but I'd be interested to hear your feedback.

from ethercrab.

jimy-byerley avatar jimy-byerley commented on June 2, 2024

regarding slave manipulations, I am hesitating about defining a fixed struct to manage a standard slave: Most of the slaves I know do have standard features in common, but often coming with a bunch of manufacturer specific features and behaviors. Think of servodrives: they all respect cia402 definitions, but

  • some will have many modes of operations, some will have only few
  • some will allow operation mode switch, some will not, some will allow only switching from some modes to some others but not switching back
  • same for torque limitations
  • some will use manufacturer specific homing procedures, or powering on cycles

So I'm sot sure that it will be easy to write a struct for the features common to every cia402 servo drives for example. The common features set is very small if we consider the poorest drives implementing cia402, so the struct written for it would have to either: implement ony very few functions, or implement a lot of functions for all optional features, and half of those will not be available on most servodrives ...

Facing this, I am personaly considering a slightly different approach:

  • the user has to create its own structs, for its specific devices, its specific needs, and the specific feature set of the devices
  • the library will provide tools to easily interact with the ethercat devices, independently of their type
  • it does not prevent the library to provide structs to manage specific features, but they shall not be too opaque, and shall interoperate with other structs managing other features of the same device.

To summarize, I like the idea of one struct per device feature rather than one struct per device type. And the user will instantiate these structs according to the actual features of its devices.

This is the way the SyncMapping I propose is working: it only manage a specific feature of a set of devices (this feature is PDO mapping, concerning complex ethercat slaves), and the user may use this struct or not to configure its device, and SyncMapping is not taking full control over the device.

The Field<T> returned by the PDO mappings may help this: it makes the user able to easily read/write SDO without particular knowledge of their addresses and data types. So I think letting the user interact with the process data through Field<T> instances is fine.

Here are my thoughts 😌

I like the idea of using typestates for this

I like it typestate too :) as long as it does not make the code much more verbose or does not constrain too much the architecture of the user's program.
I got an idea of typestate coding style to ease the rust's ownership of the ethercat client struct. I will tell you about this when my idea is more mature.

even if they are validated only at runtime

how are they validated at runtime ?! isn't this only using the compiler's type-checking ?

from ethercrab.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.