Skip to content

Improve _normalizeAngle speed.#530

Draft
jaguilar wants to merge 1 commit intosimplefoc:devfrom
jaguilar:opt_normalize_angle
Draft

Improve _normalizeAngle speed.#530
jaguilar wants to merge 1 commit intosimplefoc:devfrom
jaguilar:opt_normalize_angle

Conversation

@jaguilar
Copy link
Copy Markdown

Description

Previously _normalizeAngle used fmodf, which is expensive on Cortex-M series chips (40-100 cycles). For normalizing the angle, we can use a trick of just subtracking 2 pi times the number of full rotations from the angle.

This method does lose precision much faster than the fmodf approach. There will be significant error if the total number of radians passed in is greater than 10^5. However, we can counteract this by not passing in such a large number of radians -- basically making sure that we are not using an accumulating radian count in any location where the angle will eventually need to be normalized. This should typically be the case since accumulating radian use cases are definitionally not in need of normalization. We should consider adding an assert here to ensure that we catch any existing cases where we should be passing the mechanical or electrical angle and are instead passing an accumulator.

Performance test (on STM32G474, with certain other optimizations):

Before: foc_nanos:13737
After: foc_nanos:12550 (approx 9% reduction in loopFOC time)

Type of change

  • Optimization

How Has This Been Tested?

I built an arduino-foc-based test program based on this commit and observed that the motor still worked fine. I also benchmarked the code and observed it to be faster. I have not tested all possible control modes so it is not impossible that this approach is unacceptable in some configurations. Please review carefully and suggest anything further that I should check.

Test Configuration/Setup:

  • Hardware: STM32G474 with custom gate driver board
  • IDE: STM32CubeMX/VSCode/CMake
  • MCU package version (stm32duino/arduino-esp32/..): N/A, using my own custom Arduino shims

Previously _normalizeAngle used fmodf, which is expensive on Cortex-M
series chips (40-100 cycles). For normalizing the angle, we can use
a trick of just subtracking 2 pi times the number of full rotations from
the angle.

This method does lose precision much faster than the fmodf approach.
There will be significant error if the total number of radians passed
in is greater than 10^5. However, we can counteract this by not passing
in such a large number of radians -- basically making sure that we are
not using an accumulating radian count in any location where the angle
will eventually need to be normalized. This should typically be the case
since accumulating radian use cases are definitionally not in need of
normalization. We should consider adding an assert here to ensure
that we catch any existing cases where we should be passing the
mechanical or electrical angle and are instead passing an accumulator.

Performance test (on STM32G474, with certain other optimizations):

Before:   foc_nanos:13737
After:    foc_nanos:12550 (approx 9% reduction in loopFOC time)
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.

1 participant