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

ease of use improvements #11

Merged
merged 10 commits into from
May 20, 2024
Merged

Conversation

omelia-iliffe
Copy link
Contributor

Another week another pull request 🛩️

Couple of things that I needed to change:

Add getters for the internal SerialPort

Useful if you want to use or configure the serial port directly (such as using the SerialPort's set_read_timeout fn)
I have more thoughts about this but don't have the time rn

use AsRef for the data in SyncWriteData

If you have to provide the data as &'a [u8]but have it stored in as a Vec<u8> you have to call as ref on it:

which leads to this mess (sync_write_pos: Vec<SyncWriteData<Vec>)

 self.bus
     .sync_write(
         reg.address,
         reg.length,
         sync_write_pos
             .iter()
             .map(|d| SyncWriteData {
                 motor_id: d.motor_id,
                 data: d.data.as_ref(),
             })
             .collect::<Vec<_>>(),
     )

changing the signature to include AsRef leads to cleaner user code:

self.bus.sync_write(reg.address, reg.length, data)

A quick look at BulkWriteData shows that the data is already typed: AsRef but implementation doesn't use iterators. I could update the bulk_write fn to use iterators. Making both the function impls similar

Copy link
Member

@de-vri-es de-vri-es left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thanks :D

Regarding the timeouts, I'm also working on a PR to remove the manual read_timeout parameter and instead compute it from the expected response size and the baud rate for each read.

In that PR, I'm also adding calls to set_read_timeout. I'll update the documentation in that PR though, to add a note about it in the getter for the serial port.

src/bus.rs Outdated Show resolved Hide resolved
src/bus.rs Outdated Show resolved Hide resolved
src/bus.rs Outdated Show resolved Hide resolved
@@ -15,11 +15,12 @@ where
/// # Panics
/// The amount of data to write for each motor must be exactly `count` bytes.
/// This function panics if that is not the case.
pub fn sync_write<'a, Iter, Data>(&mut self, address: u16, count: u16, data: Iter) -> Result<(), WriteError>
pub fn sync_write<'a, Iter, Data, Buf>(&mut self, address: u16, count: u16, data: Iter) -> Result<(), WriteError>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice addition!

Not backwards compatible, but that's okay. I have more incompatible changes coming up :p

@de-vri-es de-vri-es self-assigned this Apr 23, 2024
@de-vri-es
Copy link
Member

A quick look at BulkWriteData shows that the data is already typed: AsRef but implementation doesn't use iterators. I could update the bulk_write fn to use iterators. Making both the function impls similar

This sounds good too!

@omelia-iliffe
Copy link
Contributor Author

sorry have been very inactive. Busy with install of our project. Will try find some more time this week or if you have time feel free to start/do it all :)

@de-vri-es
Copy link
Member

A quick look at BulkWriteData shows that the data is already typed: AsRef but implementation doesn't use iterators. I could update the bulk_write fn to use iterators. Making both the function impls similar

This sounds good too!

Ah, I tried to implement this, but I figured out why this isn't the case currently: we need to calculate the number of parameters first, before building the instruction message. This means we need to loop over the writes twice.

The Iterator trait isn't great for that. We could demand Iterator + Clone, but some iterator implementations might clone their data.

There are ways around it, but all of them require allocations. So I figured it's ok to limit the input to a slice and make the caller responsible for the allocation.

But I'm always open to suggestions to improve this :)

@de-vri-es
Copy link
Member

sorry have been very inactive. Busy with install of our project. Will try find some more time this week or if you have time feel free to start/do it all :)

No problem. I'm in the middle of moving and renovating my new place, so I'm also quite busy. But I think I can find some time for this crate :)

@de-vri-es
Copy link
Member

Ah, I tried to implement this, but I figured out why this isn't the case currently: we need to calculate the number of parameters first, before building the instruction message. This means we need to loop over the writes twice.

The Iterator trait isn't great for that. We could demand Iterator + Clone, but some iterator implementations might clone their data.

There are ways around it, but all of them require allocations. So I figured it's ok to limit the input to a slice and make the caller responsible for the allocation.

But I'm always open to suggestions to improve this :)

One option would be to document clearly that the iterator will be cloned, so that you should use a cheaply clonable iterator by preference.

@de-vri-es de-vri-es merged commit d346970 into robohouse-delft:main May 20, 2024
1 check passed
@de-vri-es
Copy link
Member

Released with v0.9.0 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants