You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: Improve motor control documentation details and cross-references
- Corrected Back-EMF measurement CV from CV63 to CV61.
- Rewrote 'Startup Controller' section for clarity and accuracy.
- Added Sphinx C cross-references for get_kp(), init_controller(), and speed_helper() functions.
Copy file name to clipboardExpand all lines: docs/sphinx/source/software/sw_description.rst
+17-15Lines changed: 17 additions & 15 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -72,7 +72,7 @@ The *Speed Helper* block effectively sets the setpoint of the controller accordi
72
72
For feedback the back EMF voltage *V_EMF* is measured via voltage divider and ADC. *V_EMF* is proportional to the motor speed.
73
73
74
74
75
-
While the central component is the PID controller, there is an additional block called `Feed-forward <https://en.wikipedia.org/wiki/Feed_forward_(control)>`_ that has an impact on the control output variable. The Feed-forward block adds an additional offset to the output depending on the setpoint; this is done to achieve better control. A more detailed explanation regarding Feed-forward can be found below. The speed helper block corresponds to the ``speed_helper()`` function, which delays changing the setpoint according to the configured deceleration/acceleration rates.
75
+
While the central component is the PID controller, there is an additional block called `Feed-forward <https://en.wikipedia.org/wiki/Feed_forward_(control)>`_ that has an impact on the control output variable. The Feed-forward block adds an additional offset to the output depending on the setpoint; this is done to achieve better control. A more detailed explanation regarding Feed-forward can be found below. The speed helper block corresponds to the :c:func:`speed_helper()` function, which delays changing the setpoint according to the configured deceleration/acceleration rates.
@@ -93,30 +93,32 @@ The benefit of doing this is that the PID controller does not have to work in th
93
93
Speed Table Initialization
94
94
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
95
95
96
-
The speed table is a crucial component of the motor control system, as it translates the 128 speed steps received from the DCC controller into specific setpoints for the PID controller. This table is initialized once at startup in the `init_controller` function. The shape of the speed curve can be configured using three CV values: `V_min` (CV2), `V_mid` (CV6), and `V_max` (CV5).
96
+
The speed table is a crucial component of the motor control system, as it translates the 128 speed steps received from the DCC controller into specific setpoints for the PID controller. This table is initialized once at startup in the :c:func:`init_controller` function. The shape of the speed curve can be configured using three CV values: `V_min` (CV2), `V_mid` (CV6), and `V_max` (CV5).
97
97
98
98
- **V_min (CV2):** Defines the starting voltage (setpoint) for the first speed step.
99
99
- **V_mid (CV6):** Sets the voltage at the midpoint of the speed range (speed step 64).
100
100
- **V_max (CV5):** Determines the maximum voltage at the highest speed step (126).
101
101
102
102
The speed table is calculated with two linear interpolations: one from `V_min` to `V_mid` and another from `V_mid` to `V_max`. This creates a two-segment linear speed curve, which allows for a non-linear relationship between the speed step and the motor voltage. For example, you can have a gentle acceleration at low speeds and a more aggressive one at higher speeds.
103
103
104
-
The `speed_helper` function then uses this table to gradually adjust the setpoint based on the configured acceleration and deceleration rates.
104
+
The :c:func:`speed_helper` function then uses this table to gradually adjust the setpoint based on the configured acceleration and deceleration rates.
105
105
106
106
107
107
Startup Controller
108
108
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
109
109
110
-
Used on startup, meaning when the motor is not moving. First the startup controller retrieves the last `BASE_PWM_ARR_LEN` base PWM levels.
111
-
The base pwm levels are not retained on a power cycle. That means when there is no previous base PWM level saved, the startup controller will start ramping up from 0.
112
-
When there is less than `BASE_PWM_ARR_LEN` base PWM levels saved, the startup controller will ramp up from the average of the saved base PWM levels.
110
+
The startup controller is used when the motor is stationary to find the minimum PWM level required to overcome static friction. This process is not retained on a power cycle.
113
111
114
-
After the startup controller retrieved the average of the last base pwm levels :math:`\bar{b}` it sets a PWM duty cycle level of :math:`\frac{2}{3} \cdot\bar{b}` and then ramps up the duty cycle/PWM level until the motor starts moving.
115
-
When no previous startup PWM levels are saved the startup controller begins ramping up from 0. The ramp-up is not a smooth, linear increase. Instead, the PWM level is incremented in steps, with the size of each step determined by the maximum possible PWM level (`max_level`) divided by 250. This `max_level` is a function of the PWM frequency.
112
+
The initial PWM level for the startup sequence is determined as follows:
116
113
117
-
If the PWM level reaches `max_level` and the motor still hasn't moved, the startup controller will try again with a lower starting PWM level (half of the initial `get_initial_level()` value). This prevents the motor from receiving excessive power if it's stalled.
114
+
- If previous successful startup levels are saved in memory, the controller calculates their average, :math:`\bar{b}`, and sets the initial PWM level to :math:`\frac{2}{3} \cdot\bar{b}`.
115
+
- If no previous levels are saved, the ramp-up starts from a PWM level of 0.
118
116
119
-
Once the motor starts moving (detected by a back-EMF voltage greater than 7.5), the current PWM `level` is saved as a new base PWM value. This value is then multiplied by `K_FF` (a configurable factor from CV47) and used as the feed-forward term for the PID controller.
117
+
From this starting point, the controller progressively ramps up the duty cycle until motor movement is detected. The ramp-up is not smooth but occurs in steps, with the step size determined by the maximum PWM level (which is a function of the PWM frequency).
118
+
119
+
If the PWM level reaches its maximum without motor movement, the controller reduces the starting level by half and retries, preventing excessive power to a stalled motor.
120
+
121
+
Once movement is detected (via back-EMF voltage), the current PWM `level` is saved as a new base value for future startups. This value is also multiplied by `K_FF` (from CV47) and used as the feed-forward term for the PID controller.
120
122
121
123
122
124
@@ -173,9 +175,9 @@ Gain Scheduling
173
175
174
176
Another aspect to consider is the implementation of `gain scheduling <https://en.wikipedia.org/wiki/Gain_scheduling>`_. K\ :sub:`P` is a function of the current setpoint. Often it is favorable to have a higher proportional gain K\ :sub:`P` for slow speeds, achieving better control results. The illustration above shows the default setting for K\ :sub:`P`. CV_54 & CV_55 are used to set K\ :sub:`P` @ x\ :sub:`0`, CV_56 & CV_57 for K\ :sub:`P` @ x\ :sub:`1`, and CV_58 & CV_59 for K\ :sub:`P` @ x\ :sub:`2`. Additionally, CV_60 is used to shift x\ :sub:`1` from the leftmost point (0% = 0/255) to the rightmost point (100% = 255/255).
175
177
176
-
The `get_kp()` function implements this gain scheduling. It calculates the proportional gain `K_p` based on the current setpoint `sp`. The function uses two different linear equations to determine `K_p`, depending on whether the setpoint is above or below the `k_p_x_1` threshold. This creates a piecewise linear function for `K_p`, allowing for different gain characteristics at different speed ranges.
178
+
The :c:func:`get_kp()` function implements this gain scheduling. It calculates the proportional gain `K_p` based on the current setpoint `sp`. The function uses two different linear equations to determine `K_p`, depending on whether the setpoint is above or below the `k_p_x_1` threshold. This creates a piecewise linear function for `K_p`, allowing for different gain characteristics at different speed ranges.
177
179
178
-
The parameters for these linear equations (`k_p_m_1`, `k_p_m_2`, `k_p_y_0`, `k_p_y_1`) are pre-calculated in the `init_controller` function based on the corresponding CV values.
180
+
The parameters for these linear equations (`k_p_m_1`, `k_p_m_2`, `k_p_y_0`, `k_p_y_1`) are pre-calculated in the :c:func:`init_controller` function based on the corresponding CV values.
179
181
180
182
181
183
.. _feed_forward:
@@ -191,17 +193,17 @@ The base PWM level is set by the startup controller and is the PWM level at whic
191
193
Speed Helper
192
194
^^^^^^^^^^^^^^^^^^
193
195
194
-
The `speed_helper` function is responsible for implementing smooth acceleration and deceleration. It is called by a repeating timer, with the interval configured by CV175. This function acts as a temporal filter for the speed setpoint.
196
+
The :c:func:`speed_helper` function is responsible for implementing smooth acceleration and deceleration. It is called by a repeating timer, with the interval configured by CV175. This function acts as a temporal filter for the speed setpoint.
195
197
196
-
Instead of instantly changing the motor's setpoint to the new target speed step, the `speed_helper` function gradually increments or decrements the current setpoint based on the acceleration (CV3) and deceleration (CV4) rates. These CVs determine how many calls to `speed_helper` are needed for a single speed step change. For example, if the acceleration rate is set to 5, the `speed_helper` must be called 5 times before the setpoint is incremented to the next speed step. This creates a time-based acceleration/deceleration curve.
198
+
Instead of instantly changing the motor's setpoint to the new target speed step, the :c:func:`speed_helper` function gradually increments or decrements the current setpoint based on the acceleration (CV3) and deceleration (CV4) rates. These CVs determine how many calls to :c:func:`speed_helper` are needed for a single speed step change. For example, if the acceleration rate is set to 5, the :c:func:`speed_helper` must be called 5 times before the setpoint is incremented to the next speed step. This creates a time-based acceleration/deceleration curve.
197
199
198
200
The function also handles direction changes. If a direction change is detected, it will immediately jump to the new target speed without any delay, ensuring a responsive change in direction.
199
201
200
202
201
203
Back-EMF voltage measurement
202
204
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
203
205
204
-
To provide a feedback signal proportional to the motor speed, the ADC is used to measure the `Back-EMF voltage <https://en.wikipedia.org/wiki/Counter-electromotive_force>`_. The measurement works by setting the PWM duty cycle to 0%, waiting for a certain delay time (CV_62), and then measuring x times (x = CV_63). The ADC input channel is selected based on the motor's direction (forward or reverse). While measuring, the array with measurement values is sorted using insertion sort. Afterwards, y elements (y = CV_63) from the left (lowest values) and z elements (z = CV_64) from the right (highest values) will be dismissed to mitigate the impact of potential outliers in measurement. The average value of the remaining values will be computed and fed back into the control algorithm. Considering default settings (100us delay, 100 samples, ~2µs sampling time), the complete measurement run, including averaging, takes about 0.3ms to 0.35ms, which effectively reduces the maximum possible duty cycle to about 93% to 94%.
206
+
To provide a feedback signal proportional to the motor speed, the ADC is used to measure the `Back-EMF voltage <https://en.wikipedia.org/wiki/Counter-electromotive_force>`_. The measurement works by setting the PWM duty cycle to 0%, waiting for a certain delay time (CV_62), and then measuring x times (x = CV_61). The ADC input channel is selected based on the motor's direction (forward or reverse). While measuring, the array with measurement values is sorted using insertion sort. Afterwards, y elements (y = CV_63) from the left (lowest values) and z elements (z = CV_64) from the right (highest values) will be dismissed to mitigate the impact of potential outliers in measurement. The average value of the remaining values will be computed and fed back into the control algorithm. Considering default settings (100us delay, 100 samples, ~2µs sampling time), the complete measurement run, including averaging, takes about 0.3ms to 0.35ms, which effectively reduces the maximum possible duty cycle to about 93% to 94%.
0 commit comments