-
Notifications
You must be signed in to change notification settings - Fork 2
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
feat(pipette): Detect mount at boot and assign node id #246
Conversation
The tool detection will also be needed on the pipette. In addition to therefore needing the tool detection code to live in common/ somewhere, the pipettes also need to interact with the code in a different way - they don't care what kind of tool they are (or maybe do only as a debug), just what carrier they're on. In the same way, the head doesn't really care what carrier it reads, since it knows which pins it's looking at, just which tool it is. So we can provide separate filtering options for each and let each use of the code become simpler. Unfortunately ranges and views just don't work in clang at all because of llvm/llvm-project#44178 so even though it all compiles correctly we have to do a pretty ugly hack that removes functionality when linting. It would be nice to not have this.
There's some ADC stuff that's different between devices (well, a lot of ADC stuff) but the reading->mv transition isn't, so we might as well commonize it. The core element here is an ADC channel, which is templatized with the conversion variables. That lets it do some nice conversions, and with some required implementations in the child we can have a nice generalizable interface. There isn't an ADC interface in common, because that's going to go a bunch of different places - the head has one, for instance, that specifically has gripper, z, and a channels - nothing else needs that. It relies on the common channel implementation, and the simulation and test versions override as appropriate.
Based on the voltage present on the tool sense pin and using the ADC and mount detection utilities previously added to common/, we can now pretty easily decide which mount we're on and assign ourselves a canbus id based on that.
|
||
using namespace tool_detection; | ||
|
||
constexpr static auto pipette_384_chan_z_bounds = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought we were only going to be detecting differences between gripper vs pipette vs no instrument attached
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have the means to figure out the type of pipette -this sheet shows the different expected voltages
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Laura-Danielle we'll probably go that direction eventually but this part was already implemented so I stuck with it
furthermore, a is right and z is left
This unfortunately reimplements the mount detection algorithm in C but it will work just fine (and is checked by unit tests). Bootloaders should now properly decide which mount they're on.
This flash command had the wrong openocd config value
@@ -83,7 +84,7 @@ macro(target_stm32L5 TARGET) | |||
|
|||
# Runs openocd to flash the board (without using a debugger) | |||
add_custom_target(${TARGET}-flash | |||
COMMAND "${OpenOCD_EXECUTABLE}" "-f" "${COMMON_EXECUTABLE_DIR}/STM32G491RETx/stm32g4discovery.cfg" "-c" "program $<TARGET_FILE:${TARGET}>;reset;exit" | |||
COMMAND "${OpenOCD_EXECUTABLE}" "-f" "${COMMON_EXECUTABLE_DIR}/STM32L562RETx/stm32l5discovery.cfg" "-c" "program $<TARGET_FILE:${TARGET}>;reset;exit" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙇
|
||
// Filter tests - no BDD here because these macros don't have | ||
// BDD equivalents | ||
TEMPLATE_TEST_CASE_SIG("tool list by pipette type", "", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Neato
[[nodiscard]] auto within_bounds(millivolts_t reading) const -> bool { | ||
return ((reading >= this->bounds.lower) && | ||
(reading < this->bounds.upper)); | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why two returns? Am I crazy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What how did that get there why did no tooling care about it gah
// | ||
// Can specify your own base lookup table (including, possibly, the output of | ||
// another filter function call) or load from the default one. | ||
template <ToolOrCarrier FilterTarget> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are a real macher, aren't you?
pipettes/firmware/main.cpp
Outdated
@@ -136,7 +139,7 @@ auto main() -> int { | |||
pipettes_tasks::start_tasks(can_bus_1, pipette_motor.motion_controller, | |||
pipette_motor.driver, i2c_comms, | |||
// TODO: Load from mount interface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need to TODO this anymore, innit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure don't!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lovely
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great
return a.bounds.upper < b.bounds.upper; | ||
}); | ||
auto trailer = | ||
std::ranges::subrange(copied.begin(), --copied.end()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cool tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
home, home on the std::range
Bring up the ability for the pipette to decide which node ID it should use based on the tool mount voltage it senses, reusing code from the similar implementation for head.
For code reusability, the first couple commits commonize first the tool detection (using some fun ranges and filter views which don't work with clang at all, see the comments and the commit message) and then a basic adc interface since the needs are so similar. Once those are done, the work to actually do the sensing on the pipette is surprisingly small.
Still some todos, but definitely reviewable.Does the bootloader thing now.TODO:
Test on hardwareworks great! moving a pipette back and forth between the mounts and probing shows it reliably switching.Figure out what to do about the bootloadersadd separate implementation and regression tests to avoid dealing with different enum types