Add: benchmark for ping1d and ping360 on CI#62
Conversation
ead2d29 to
a98fbea
Compare
|
@patrickelectric @joaoantoniocardoso Should we add this in the near future? Benchmarking in navigator-rs helped improve sensor readings and reliability. |
899602f to
ed531f5
Compare
ES-Alexander
left a comment
There was a problem hiding this comment.
Reviewed the calculation part - as requested from internal discussion :-)
The calculation logic seems generally ok (except maybe for the min_sample_based variable?), but I feel like it belongs somewhere accessible to users.
Some comments around code cleanliness and maintainability.
| const FIRMWARE_MIN_TRANSMIT_DURATION: u16 = 1; | ||
|
|
||
| fn calculate_sample_period(desired_range: f64, number_of_samples: u16, speed_of_sound: f64) -> u16 { | ||
| const SAMPLE_PERIOD_TICK_DURATION: f64 = 25e-9; |
There was a problem hiding this comment.
| const SAMPLE_PERIOD_TICK_DURATION: f64 = 25e-9; |
| ((2.0 * desired_range) | ||
| / (number_of_samples as f64 * speed_of_sound * SAMPLE_PERIOD_TICK_DURATION)) | ||
| .ceil() as u16 |
There was a problem hiding this comment.
| ((2.0 * desired_range) | |
| / (number_of_samples as f64 * speed_of_sound * SAMPLE_PERIOD_TICK_DURATION)) | |
| .ceil() as u16 | |
| // Ensure sample period covers the full desired range | |
| ((2.0 * desired_range) | |
| / (speed_of_sound * number_of_samples as f64 * SAMPLE_PERIOD_TICK_DURATION)) | |
| .ceil() as u16 |
- Explanatory comment for why
ceilis desirable - I think it is easier to follow if the sample-related variables are next to each other (assuming the code still works fine like that - I'm not very familiar with Rust)
| fn calculate_transmit_duration_max(sample_period: u16) -> u16 { | ||
| let sample_based_max = sample_period as f64 * 64.0 * SAMPLE_PERIOD_TICK_DURATION * 1e6; | ||
| sample_based_max.min(FIRMWARE_MAX_TRANSMIT_DURATION as f64) as u16 | ||
| } |
There was a problem hiding this comment.
This should presumably have some kind of doc-string/comment to explain why there is a maximum?
| const SAMPLE_PERIOD_TICK_DURATION: f64 = 25e-9; | ||
| const FIRMWARE_MAX_TRANSMIT_DURATION: u16 = 1000; | ||
| const FIRMWARE_MIN_TRANSMIT_DURATION: u16 = 1; |
There was a problem hiding this comment.
These seem like they should have unit information (e.g. in the variable names in not SI units, and/or in explanatory comments).
| fn calculate_transmit_duration(range: f64, speed_of_sound: f64, sample_period: u16) -> u16 { | ||
| // Calculate initial value | ||
| let mut auto_duration = ((8000.0 * range) / speed_of_sound).round(); | ||
|
|
||
| // Ensure minimum based on sample period (convert to microseconds) | ||
| let min_sample_based = (2.5 * sample_period as f64 * SAMPLE_PERIOD_TICK_DURATION * 1e6).ceil(); | ||
| auto_duration = auto_duration.max(min_sample_based).round(); | ||
|
|
||
| // Clamp between FIRMWARE_MIN_TRANSMIT_DURATION and max based on sample period | ||
| let max_duration = calculate_transmit_duration_max(sample_period); | ||
| auto_duration = auto_duration | ||
| .max(FIRMWARE_MIN_TRANSMIT_DURATION as f64) | ||
| .min(max_duration as f64); | ||
|
|
||
| auto_duration.round() as u16 | ||
| } |
There was a problem hiding this comment.
Code with no explanation is hard to follow, evaluate, and maintain.
| const SAMPLE_PERIOD_TICK_DURATION: f64 = 25e-9; | ||
| const FIRMWARE_MAX_TRANSMIT_DURATION: u16 = 1000; | ||
| const FIRMWARE_MIN_TRANSMIT_DURATION: u16 = 1; | ||
|
|
||
| fn calculate_sample_period(desired_range: f64, number_of_samples: u16, speed_of_sound: f64) -> u16 { | ||
| const SAMPLE_PERIOD_TICK_DURATION: f64 = 25e-9; | ||
| ((2.0 * desired_range) | ||
| / (number_of_samples as f64 * speed_of_sound * SAMPLE_PERIOD_TICK_DURATION)) | ||
| .ceil() as u16 | ||
| } | ||
|
|
||
| fn calculate_transmit_duration_max(sample_period: u16) -> u16 { | ||
| let sample_based_max = sample_period as f64 * 64.0 * SAMPLE_PERIOD_TICK_DURATION * 1e6; | ||
| sample_based_max.min(FIRMWARE_MAX_TRANSMIT_DURATION as f64) as u16 | ||
| } | ||
|
|
||
| fn calculate_transmit_duration(range: f64, speed_of_sound: f64, sample_period: u16) -> u16 { | ||
| // Calculate initial value | ||
| let mut auto_duration = ((8000.0 * range) / speed_of_sound).round(); | ||
|
|
||
| // Ensure minimum based on sample period (convert to microseconds) | ||
| let min_sample_based = (2.5 * sample_period as f64 * SAMPLE_PERIOD_TICK_DURATION * 1e6).ceil(); | ||
| auto_duration = auto_duration.max(min_sample_based).round(); | ||
|
|
||
| // Clamp between FIRMWARE_MIN_TRANSMIT_DURATION and max based on sample period | ||
| let max_duration = calculate_transmit_duration_max(sample_period); | ||
| auto_duration = auto_duration | ||
| .max(FIRMWARE_MIN_TRANSMIT_DURATION as f64) | ||
| .min(max_duration as f64); | ||
|
|
||
| auto_duration.round() as u16 | ||
| } |
There was a problem hiding this comment.
All of this seems like potential convenience functionality that should likely be available in the ping360 part of the library, not hidden away in a benchmark.
Do the sample period and transmit duration not need to be calculated as part of ping-viewer functionality?
|
|
||
| // Ensure minimum based on sample period (convert to microseconds) | ||
| let min_sample_based = (2.5 * sample_period as f64 * SAMPLE_PERIOD_TICK_DURATION * 1e6).ceil(); | ||
| auto_duration = auto_duration.max(min_sample_based).round(); |
There was a problem hiding this comment.
| auto_duration = auto_duration.max(min_sample_based).round(); | |
| auto_duration = auto_duration.max(min_sample_based); |
Not necessary if the inputs have already been rounded or ceiled, right?
| let mut auto_duration = ((8000.0 * range) / speed_of_sound).round(); | ||
|
|
||
| // Ensure minimum based on sample period (convert to microseconds) | ||
| let min_sample_based = (2.5 * sample_period as f64 * SAMPLE_PERIOD_TICK_DURATION * 1e6).ceil(); |
There was a problem hiding this comment.
It's hard to be sure without units specified, but it seems like this differs from Ping Viewer by 1e9 (i.e. * 1e6 instead of / 1000)?
helps