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

Add option to ignore endstops during startup #747

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

aaronjamt
Copy link

This is useful for devices where the endstop is pressed while power is off, due to gravity, springs, or otherwise. When the ODrive initially starts up, it sees the limit switch(es) pressed and disarms the motor(s) immediately. With this setting enabled, the limit switch will not cause the motor to disarm during inital startup, making the odrive.axis*.config.startup_* flags useful again.

As an example of a potential use case, I'm building a flight simulator, where the pod the rider sits is supported on 6 linear actuators. Each actuator has a lower endstop (odrive.axis*.min_endstop) and is configured with startup_encoder_index_search, startup_homing, and startup_closed_loop_control all enabled. However, currently, when powering on the machine, it needs 3 people to help hold the weight of the pod and a 4th operator to manually rotate the motors to lift each actuator off the endstops. Obviously, this is not ideal, and while there are potential solutions that we've thought of, the simplest (and, in my opinion, safest) is to just have it allow the startup sequence to run while the endstops are pressed. The settings for startup_encoder_index_search can be configured to make the actuators always move up, and then startup_homing takes over and moves the actuators away from the endstops.

If there are any concerns around this PR, I'd be happy to discuss them. As far as I can tell, using AXIS_STATE_UNDEFINED as a flag for initial startup seems to be correct, as it's used for that purpose in axis.cpp#458 and is used as the condition for the is_booting() variable in main.cpp#45-47.

This is useful for devices where the endstop is pressed while power is off, due to gravity, springs, or otherwise. When the ODrive initially starts up, it sees the limit switch(es) pressed and disarms the motor(s) immediately. With this setting enabled, the limit switch will not cause the motor to disarm during inital startup, making the `odrive.axis*.config.startup_*` flags useful again.
@CLAassistant
Copy link

CLAassistant commented May 23, 2024

CLA assistant check
All committers have signed the CLA.

aaronjamt added a commit to aaronjamt/ODrive that referenced this pull request May 23, 2024
This is useful for devices where the endstop is pressed while power is off, due to gravity, springs, or otherwise. When combined with odriverobotics#747, this allows the ODrive to start up the motors and perform the encoder index search while one of the endstops is pressed. With this setting enabled, the limit switch will not cause the motor to disarm during the encoder index search, making the `odrive.axis*.config.startup_encoder_index_search` flag useful again.
@samuelsadok
Copy link
Member

Thanks for your contribution! This sounds like a reasonable use case.

As it is written currently, the endstops are edge triggered, so if the axis is just sitting on the endstop, it shouldn't trigger it.
In other words, your use case should actually already be supported, the way the if condition is written, so if you ran into issues with it, it sounds like a bug and I would be interested to understand it.

Could you elaborate more what commands you ran and what behavior you observed?
Specifically, when you just reboot the ODrive into idle (without the startup_* flags enabled), does dump_errors() show any endstop errors?

And just to make sure, you're using ODrive v3.6, correct? Because the newer (current generation) ODrives are not covered by this repository, see note here.

@aaronjamt
Copy link
Author

Thanks for your contribution! This sounds like a reasonable use case.

As it is written currently, the endstops are edge triggered, so if the axis is just sitting on the endstop, it shouldn't trigger it. In other words, your use case should actually already be supported, the way the if condition is written, so if you ran into issues with it, it sounds like a bug and I would be interested to understand it.

I noticed that it appears to be edge triggered (checking .rose()) but it still seems to trigger on startup regardless.

Could you elaborate more what commands you ran and what behavior you observed? Specifically, when you just reboot the ODrive into idle (without the startup_* flags enabled), does dump_errors() show any endstop errors?

When I turn off all the startup_* flags, here's what happens (off memory, so I may have the names of the flags/states wrong, I apologize if so):

  1. Power up (then dump_errors(odrv0)): No errors
  2. Set .requested_state to AXIS_STATE_* (I believe I tried CLOSED_LOOP_CONTROL and HOMING, possibly also INDEX_SEARCH but not positive, may be able to test it tomorrow): Motors don't move and it immediately fails with MIN_ENDSTOP_PRESSED
  3. Run odrv0.clear_errors(): No errors again, motors remain idle
  4. Move one axis off bottom endstop and set requested_state again: it works fine, state is applied and operates normally

And just to make sure, you're using ODrive v3.6, correct? Because the newer (current generation) ODrives are not covered by this repository, see note here.

Yes, I'm using a V3.6 56V board (well, technically 3 boards for a total of 6 motors). I previously upgraded from the 24V boards, which I believe had the same issue, but am not 100% sure as I upgraded over a year ago and haven't used them since. Also, I noticed after submitting this PR that, for only 1 of my 3 ODrives, one axis would still fail on startup (a failure rate of 1 in 6), and after a bit more troubleshooting, I realized that it was actually failing during the index search, hence #748.

@samuelsadok
Copy link
Member

Sorry for the late reply.

For clarity I should say that due to the NRND status of ODrive v3.6, this repository is fairly deprioritized at this point, see also note here. So I try to be careful with changes because I wouldn't be testing them myself. That means we rely more on code inspection and the rigor of contributors for evaluating changes.

In this case, could you try to find out more on a code level what makes the error occur? From your last message it seems that the error doesn't only occur immediately on startup, but just the first time the axis is enabled. This means that the proposed fix (checking for AXIS_STATE_UNDEFINED) would not address the root problem. Ideally, you're able to track down which variables have the wrong value under which conditions. You can do this through experiments and code inspection. Understanding the problem at the code level will be important to decide what a suitable fix is.

If you prefer to not spend more time on this, or have moved on to other things, that's also fine with us, in this case you're free to close the PR.

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.

3 participants