Skip to content

drivers: stepper: introduce rudimentary ramp control #88564

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

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

Conversation

jilaypandya
Copy link
Member

@jilaypandya jilaypandya commented Apr 13, 2025

Introduce rudimentary control using following paper:

https://www.boost.org/doc/libs/1_81_0/libs/safe_numerics/example/stepper-motor.pdf

Other References:
Equation 13 in the above mentioned paper can also be seen in this app note.
https://ww1.microchip.com/downloads/en/Appnotes/doc8017.pdf (Thanks @andre-stefanov :) )

The idea is to create a ramp lib that can be integrated in any driver, the step counting for the driver itself stay unaffected by integration a ramp lib

I have been using Shell to see how the ramping looks like.

Starting This PR to get some early feedback.


Known open points:

  • Integrate ramp control for stepper_run as well
  • use of sqrt in calculate_start_velocity, this function gets called once when the ramping starts from zero-velocity
  • Implement unit tests
  • Introduce DT based selection of trapezoidal ramp, allowing inclusion of other ramps in future

Sorry, something went wrong.

/** Ramp acceleration in micro-steps per second squared */
uint32_t acceleration;
/** Ramp maximum velocity in micro-steps per second */
uint32_t max_velocity;

Choose a reason for hiding this comment

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

is max_velocity really needed? next step interval depends only on current interval and acceleration/deceleration values.

the actual limit will be given by the requested stepper interval

Copy link
Member Author

@jilaypandya jilaypandya Apr 13, 2025

Choose a reason for hiding this comment

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

Trying to depict a trapezoidal ramp. I am also using max_velocity to check for valid_timing in move_by and move_to. But i'll check this again for sure if it is actually needed :).

Copy link
Collaborator

Choose a reason for hiding this comment

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

In my experience, the speed set via set_microstep_interval is sufficient.

Copy link
Member Author

Choose a reason for hiding this comment

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

Okay we can use that function, but we definitely need to have a better name for it though. set_microstep_interval atleast imo sounds like this interval will take place with immediate effect. Probably something like set_target_step_interval ?

@jilaypandya jilaypandya force-pushed the feature/introduce-rudimentary-ramp branch 4 times, most recently from 03d7e6a to 002919a Compare April 14, 2025 07:12
/** Ramp acceleration in micro-steps per second squared */
uint32_t acceleration;
/** Ramp maximum velocity in micro-steps per second */
uint32_t max_velocity;
Copy link
Collaborator

Choose a reason for hiding this comment

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

In my experience, the speed set via set_microstep_interval is sufficient.


K_SPINLOCK(&data->lock) {
data->ramp_common.ramp_profile.acceleration = ramp_profile->acceleration;
data->ramp_common.ramp_profile.max_velocity = ramp_profile->max_velocity;
Copy link
Collaborator

Choose a reason for hiding this comment

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

You don't need max_velocity, you already have set_microstep_interval.

Copy link
Member Author

Choose a reason for hiding this comment

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

We need to find a consensus on how to rename that function, set_microstep_interval imo signifies more like a tick time, could be compared with for instance , can_set_bitrate.


if STEPPER_RAMP

config STEPPER_RAMP_TRAPEZOIDAL
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would prefer a dt-binding instead to allow for a per stepper-controller decision on using ramps or not.

Copy link
Member Author

Choose a reason for hiding this comment

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

done. However, you would need one such variable for the source to be included, or is there a better way?

switch (ramp_data->current_ramp_state) {
case STEPPER_RAMP_STATE_ACCELERATION:
ramp_data->ramp_actual_position++;
new_step_interval_in_ns = current_step_interval_in_ns -
Copy link
Collaborator

Choose a reason for hiding this comment

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

You cant always use the approximation. You will need to use the accurate algorithm using the sqrt for a number of steps after starting accelerating and a couple of steps before stopping when decelerating. This is because of the approximation error.

@jbehrensnx
Copy link
Collaborator

My PR 88342 already uses the same algorithm (through I forgot to mention the algorithm admittedly) for a step-dir implementation. Several decisions made during development for that are relevant for this PR as well, so it should be included in the discussion.

@kartben kartben assigned jilaypandya and unassigned kartben Apr 14, 2025
@decsny decsny removed their request for review April 14, 2025 17:04
@jilaypandya jilaypandya force-pushed the feature/introduce-rudimentary-ramp branch from 002919a to 2fb84c6 Compare April 14, 2025 19:33
@dipakgmx
Copy link
Member

This is not related to the changes made in this PR, but could the functions move_to & move_by call either of them, I mean, in move_by, call move_to(current_pos+move_by_target)? It seems to me that some bits of code are repeated in both the functions (or thats what I felt when reviewing)

@jilaypandya jilaypandya force-pushed the feature/introduce-rudimentary-ramp branch from 2fb84c6 to 2f12222 Compare April 14, 2025 21:20
@jilaypandya
Copy link
Member Author

This is not related to the changes made in this PR, but could the functions move_to & move_by call either of them, I mean, in move_by, call move_to(current_pos+move_by_target)? It seems to me that some bits of code are repeated in both the functions (or thats what I felt when reviewing)

you are right, move_to should call move_by. When can i expect a patch from you :-)

@jilaypandya jilaypandya force-pushed the feature/introduce-rudimentary-ramp branch 5 times, most recently from fd21b8d to 32d6c94 Compare April 16, 2025 14:59
@jilaypandya jilaypandya requested a review from Copilot April 16, 2025 19:10
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces rudimentary ramp control for stepper drivers by implementing a trapezoidal ramp algorithm and integrating ramp profile support into both generic and GPIO stepper drivers. Key changes include:

  • Integrating a ramp profile in the main application code for the generic stepper driver.
  • Adding device tree bindings and header definitions for ramp parameters.
  • Implementing a trapezoidal ramp algorithm and integrating its API into the GPIO driver.

Reviewed Changes

Copilot reviewed 11 out of 18 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
samples/drivers/stepper/generic/src/main.c Initializes and applies ramp profile in main for driver testing.
include/zephyr/dt-bindings/stepper/ramp.h Defines ramp type constants for DT binding.
include/zephyr/drivers/stepper/stepper_ramp.h Declares the ramp profile structure and APIs.
include/zephyr/drivers/stepper.h Integrates ramp profile API into the stepper driver interface.
dts/bindings/stepper/zephyr,gpio-stepper.yaml Adds ramp parameters inclusion for DT configuration.
dts/bindings/stepper/ramp-parameters.yaml Provides DT properties for ramp configuration.
drivers/stepper/stepper_common.h Introduces common stepper run modes.
drivers/stepper/step_dir/step_dir_stepper_common.h Uses common stepper definitions.
drivers/stepper/ramp/ramp_trapezoidal.c Implements the trapezoidal ramp algorithm logic.
drivers/stepper/ramp/ramp.h Declares ramp API and supporting structures.
drivers/stepper/gpio_stepper_controller.c Integrates ramp control logic within the GPIO stepper driver.
Files not reviewed (7)
  • drivers/stepper/CMakeLists.txt: Language not supported
  • drivers/stepper/Kconfig: Language not supported
  • drivers/stepper/ramp/CMakeLists.txt: Language not supported
  • drivers/stepper/ramp/Kconfig: Language not supported
  • samples/drivers/stepper/generic/Kconfig: Language not supported
  • samples/drivers/stepper/generic/boards/nucleo_g071rb.overlay: Language not supported
  • samples/drivers/stepper/generic/prj.conf: Language not supported
Comments suppressed due to low confidence (1)

drivers/stepper/gpio_stepper_controller.c:388

  • Using a magic number (10000) for steps in the ramp reset call reduces code clarity and flexibility. Consider defining a named constant or using a DT property for improved maintainability.
config->ramp_api->reset_ramp_data(&config->ramp_config, &data->ramp_common, &data->delay_in_ns, is_dir_changed, is_stepper_moving, 10000);

@jilaypandya jilaypandya force-pushed the feature/introduce-rudimentary-ramp branch from 32d6c94 to dd51fb8 Compare April 16, 2025 19:16
Introduce rudimentary control using following paper:
https://www.boost.org/doc/libs/1_81_0/libs/safe_numerics/example/stepper-motor.pdf

Signed-off-by: Jilay Pandya <[email protected]>
@jilaypandya jilaypandya force-pushed the feature/introduce-rudimentary-ramp branch from dd51fb8 to 67e6a1e Compare April 17, 2025 21:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants