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

feat(pipette): Detect mount at boot and assign node id #246

Merged
merged 10 commits into from
Feb 16, 2022

Conversation

sfoster1
Copy link
Member

@sfoster1 sfoster1 commented Feb 15, 2022

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 hardware works great! moving a pipette back and forth between the mounts and probing shows it reliably switching.
  • Figure out what to do about the bootloaders add separate implementation and regression tests to avoid dealing with different enum types

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.
@sfoster1 sfoster1 requested review from sotaoverride and a team February 15, 2022 22:17

using namespace tool_detection;

constexpr static auto pipette_384_chan_z_bounds =
Copy link
Contributor

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

Copy link
Contributor

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

Copy link
Member Author

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
@sfoster1 sfoster1 requested a review from amitlissack February 16, 2022 17:58
@@ -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"
Copy link
Contributor

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", "",
Copy link
Contributor

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;
Copy link
Contributor

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?

Copy link
Member Author

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>
Copy link
Contributor

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?

@@ -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
Copy link
Contributor

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?

Copy link
Member Author

Choose a reason for hiding this comment

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

sure don't!

Copy link
Contributor

@amitlissack amitlissack left a comment

Choose a reason for hiding this comment

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

Lovely

Copy link
Contributor

@Laura-Danielle Laura-Danielle left a 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());
Copy link
Contributor

Choose a reason for hiding this comment

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

cool tests

Copy link
Member Author

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

@sfoster1 sfoster1 merged commit 27e76e9 into main Feb 16, 2022
@sfoster1 sfoster1 deleted the add_pipette_mount_detect branch February 16, 2022 22:21
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.

4 participants