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

Bypass ramp generator #299

Open
AntoineGR opened this issue Dec 18, 2024 · 5 comments
Open

Bypass ramp generator #299

AntoineGR opened this issue Dec 18, 2024 · 5 comments

Comments

@AntoineGR
Copy link

Hello Gin66,
would you consider implementing a native command to run moves without ramp generator ?

The idea came up in previous use cases (#110 #288 #86) where motion planning is computed by an external software (3D, animation, robotic).
FastAccelStepper is then used to run many small consecutive motions (from an array in memory or streamed on the fly).
This allow for clean and time-constrained motion paths to be executed.

To bypass the current ramp generator some users tried setting the acceleration to max value (not 100% precise and use CPU ressources) or implemented their own low-level routine and queue management.

So the proposal would be to have two new commands that run in a given time without accel/decel :
moveTimed(steps, duration) and moveToTimed(steps, duration)
Duration could be in ticks or seconds or milliseconds.

@gin66
Copy link
Owner

gin66 commented Dec 19, 2024

Thanks for the proposal. Sounds easy, but solution is a bit more complex.

Assume duration is 5ms and 50kSteps/s. Then steps = 250 and duration 5ms. Step rate is 20us. Easy. Can be done by simple translation into queue commands.

Now consider 251steps and duration 5ms. Step rate should be 19,92us. But the next lower step rate is 19.9375us and 251 steps with this rate is 5,004ms. So 4us deviation. With 252steps the actual duration is 4,99275ms and 8us deviation. Sounds small, but after 1000 commands of 5ms, there can be already 4-8ms deviation, which is a complete command. so ~250 steps more or less at nearly the same time.

Correction can be done only up to 4 times per ms and the deviation may not be possible to perfectly compensate. Shall this be corrected by the new function or by the caller ?

@AntoineGR
Copy link
Author

Thank you for the quick and thoughtful answer

You're making a good point on this quantization issue, I'm pondering what could be the most elegant solution,
will report back here soon !

@AntoineGR
Copy link
Author

AntoineGR commented Jan 9, 2025

Ok so in the spirit of my proposal the important point is to have time-constrained commands.
Therefore the proposed functions should respect the desired duration and would sometime need to :

  • accomplish less steps (to avoid overflowing the target duration)
  • and wait at the end of the command (to reach the target duration)

So when using moveTimed(steps, duration) or moveToTimed(steps, duration) I guess the functions should return droppedSteps to let the user know the delta and add it to the next function call.
Does that make sense ?

PS : I created a python script to loop through all stepping rates and check how many steps need to be dropped and how long is the remaining wait time, let me know if you'd like to have it.

@gin66
Copy link
Owner

gin66 commented Jan 10, 2025

Thanks for the proposal.

Based on the existing implementation of the queue another approach seems to be more straightforward: The queue tracks very well the actual position at queue end. What is currently not available, is the time at queue end. This should be comparably easy to be maintained. Queue end time can be reset to 0 at start of the queue. Now the consecutive function calls would need to maintain their own set of target steps and target time. By comparing to the queue end time/steps, the correction should happen quite naturally.

Hope I have explained my idea good enough. What do you think?

@AntoineGR
Copy link
Author

AntoineGR commented Jan 11, 2025

Hi !
Sound alright but I'm not sure I understand all the implications : would the functions then return an absolute position + elapsed queue duration ? (maybe if you can give an example that could clear it out for me)

Continuously correcting for time might get tricky, especially with several motors working together.
I think the main use case of these functions would be to run preplanned moves (or pathtables) entirely computed beforehand.

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

No branches or pull requests

2 participants