robotology / icub-firmware-models

Models underlying the iCub Firmware
https://robotology.github.io/icub-firmware-models/
BSD 3-Clause "New" or "Revised" License
6 stars 5 forks source link

AMCBLDC – Model the `i2t` overcurrent protection #14

Closed pattacini closed 1 year ago

pattacini commented 1 year ago

We're required to implement in the architectural model the i2t protection. We may use some new parameters as per #8.

Some further resources:

pattacini commented 1 year ago

We may start off with a simple implementation where we just stick to the nominal current, w/o having access to those parameters that will need to be transmitted over CAN.

@mfussi66 can deal with this task, while I can act as a tutor.

pattacini commented 1 year ago

Eventually, with the i2t implemented, we will be able to increase the current thresholds (overload, peak).

cc @maggia80 @sgiraz @Nicogene

pattacini commented 1 year ago

Aside from the standard approaches reported in the OP, I have recently come across an interesting variant described in a technical note[^1] of the Faulhaber motors where a thermal model is employed.

ss2

Essentially, the Faulhaber motors equipped with an integrated Speed-Controller (SC)[^2] can enable the i2t protection according to the rules reported in the screenshot above. The key point is to resort to an internal model of how the temperature evolves because of the dissipation, once we know the thermal resistance ($R_t$) and the time constants ($\tau$).

These latter parameters ($R_t$ and $\tau$) are described in the technical manual[^3]:

ss1

and reported in some datasheets (not all, unfortunately):

ss3

Given all this, we may consider implementing the thermal circuit below (just an example):

image

We know the thermal "current", which is $R_L \cdot i^2$, so we can find the temperature variation by:

$$ \Delta T = \frac{RLi^2 \cdot R{t1}}{R{t1} + R{t2}}. $$

Finally, we can filter this temperature setpoint with a first-order filter characterized by the time constant $\tau$. When the temperature $T$ reaches $T{crit}$ we limit the current to $I{nominal}$ instead of $I_{peak}$ until the moment when $T$ goes down below another threshold.

I like this approach, but we may miss sometimes from the datasheet the thermal constants ($Rt$ and $\tau$) and the critical temperature $T{crit}$[^4]. although we can ask Faulhaber for them.

Regarding our motor, the datasheet doesn't seem to contain all the required parameters, neither for the standard i2t (e.g., the time window) nor for the thermal model.

cc @maggia80 @mfussi66

[^1]: technical note [^2]: We don't have/use native SC on our Faulhaber motors, but we could implement the same strategy. [^3]: technical manual [^4]: We should also provide an estimate of the starting temperature.

pattacini commented 1 year ago

Speaking with @maggia80, it turned out that Faulhaber is likely able to provide us with the missing parameters.

pattacini commented 1 year ago

Regarding our motor, the datasheet doesn't seem to contain all the required parameters, neither for the standard i2t (e.g., the time window) nor for the thermal model.

Actually, the online datasheet is more complete and contains the required information. See https://www.faulhaber.com/en/products/series/2214bxtr/

Thanks @fiorisi 👍🏻

image

Therefore, I think we can start, @mfussi66. We need to:

pattacini commented 1 year ago

A very quick sanity check with the values above:

$$ \begin{cases} \begin{matrix} RL = 30 \Omega \ R{t1} = 7 K/W \ R_{t2} = 49 K/W \end{matrix} \end{cases}. $$

If we think of starting from the temperature of the environment $T0 = 25$ $^oC$, then to get $\Delta T = 60$ $^oC$ to reach $85$ $^oC$ (way below $T{crit}$) we should deliver:

$$ i = \sqrt{\frac{60 \cdot \left( 7+49\right)}{30 \cdot 7}} = 4 A. $$

Well, 4 Amps is a bit off the motor specs. There must be something else 😕

pattacini commented 1 year ago

Moved to the next sprint.

pattacini commented 1 year ago

There must be something else 😕

A couple of comments:

fiorisi commented 1 year ago

A very quick sanity check with the values above:

{RL=30ΩRt1=7K/WRt2=49K/W.

If we think of starting from the temperature of the environment T0=25 oC, then to get ΔT=60 oC to reach 85 oC (way below Tcrit) we should deliver:

i=60⋅(7+49)30⋅7=4A.

Well, 4 Amps is a bit off the motor specs. There must be something else 😕

If I correctly remember we have to balance the Joule losses, the dissipated power and the temperature change in the motor windings. The balance should be the following:

$P_j - P_d = C {\partial T_w\over dt}$

Where:

This should become

$i^2 R_t - {{T_w - Ta} \over {R{th1} + R_{th2} }} = C {\partial T_w\over dt}$

Where:

We don't have $C$, but should be possible to compute it from the thermal time constant $\tau_{w1}$:

$C = {\tau{w1} \over {R{th1} + R_{th2} }}$

By solving the differential equation and initializing the widings temperature we should be able to check the model.

pattacini commented 1 year ago

I did the quick calculations in stationary conditions, when $\frac{\partial T}{\partial t}=0$, with the idea that once we know the steady state we know how the system evolves toward it relying on the time constant.

pattacini commented 1 year ago

I did the calculations wrong! I was basically confusing the heat source with a voltage generator rather than a current generator, in the electrical analogy.

Here's the correct form:

$$ \Delta T = RLi^2 \cdot \left( R{t1} + R_{t2} \right). $$

$$ i = \sqrt{\frac{60}{30 \cdot \left( 7+49 \right)}} = 188 \text{mA}. $$

The final outcome makes really sense to me.

pattacini commented 1 year ago

📝 Notes for the development

We will need to accommodate a generic thermal model for a variety of motors (also of different brands). Hence, we should come up with a single equivalent thermal resistance and a single equivalent thermal time constant.

pattacini commented 1 year ago

Let me attempt a recap after the notes above.

🎯 Objective

We aim to implement in our FW architecture (Simulink) a thermal model of the motor so that we can provide a further level of protection. We should be able to adapt the model to a wide variety of motor brands.

⚙️ Implementation

For simplicity, we can start with a first-order thermal model, where the input heat flow $\dot{Q}$ (measured in W) is determined by the electrical current $i$[^1] and the resulting electrical resistance of the circuit $R_L$:

[^1]: We can refer to the quadrature current here, as the direct current is regulated to 0 by the PID.

$$ \dot{Q} = R_L \cdot i^2. $$

The steady-state temperature variation wrt the environmental temperature $T_e$ is:

$$ \Delta T = \dot{Q} \cdot R_t, $$

where $R_t$ is the thermal resistance, whose unit is K/W.

The temporal evolution of the temperature $T$ while evolving to $T_e+\Delta T$ is specified by the time constant $\tau$.

Therefore, it suffices to implement a digital filter $F$ characterized by the same constant $\tau$ and deal with the output $\hat{T}\left(t\right)=T_e+F\left(\Delta T\right)=T_e+F\left(R_L \cdot i^2 \cdot R_t\right)$.

Conditions

📝 Involved quantities

Datasheets

It seems that we have access to the quantities at stake from the Faulhaber datasheet.

In particular, the datasheet reports on two different sets of thermal resistances and time constants: one for the windings and one for the housing. Therefore, we should come up with a unique equivalent set (we could use just one or a combination) to monitor what we are interested in.

Parameters

We would need to define these parameters: $R_L$, $Rt$, $\tau$, $T{crit}$. By contrast, the nominal current $I_N$ is already accounted for in our architecture.

Environmental temperature

We would need an estimate of $T_e$, unless we decide that we could assume $T_e = 25$ $^oC$[^2] to start with.

[^2]: We may add it up to the list of parameters.

pattacini commented 1 year ago

Development started in https://github.com/robotology/icub-firmware-models/tree/14-amcbldc--model-the-i2t-overcurrent-pr.

mfussi66 commented 1 year ago

In continuous time (to discretize at 10ms), it should result in the following model:

image

With 25.9 Ohms of terminal resistance, the motor gets toasted at about 220mA.

pattacini commented 1 year ago

We use those values to be able to perform measurements with the thermocamera. However, the motor won't get toasted at that temperature.

For checking the motor's limits, I guess we should switch to the other set of params corresponding to the windings.

At any rate, we can temporarily overcome the current limits as the temperature increases slowly compared to other dynamics at stake.

mfussi66 commented 1 year ago

In the digital domain with Tustin discretization and externally-defined coefficients, the filter could look like this:

$$ \frac{T_s R_L R_T (z + 1) } {(T_s + 2 \tau) z + T_s - 2 \tau} $$

Translated into configurable blocks:

image

Comparing the continuous model with the discretized one, there is a small quantization error that stabilizes over a long time.

Here is the step response with 250mA.

untitled

mfussi66 commented 1 year ago

I transferred the filter in the architectural model and generated the code, which seems very lean:

image

Additionally, the Keil project was updated and compiled, and is now ready to be tested.

pattacini commented 1 year ago

Nice!

Nitpicking: in the comment we can see $R{t1}$ and $R{t2}$. Could you update it? We've got only $R_t$.

pattacini commented 1 year ago

Also, I would make it clearer that the coefficients depend on $T_s$. So, $T_s$ may be a further input to the block Compute coefficients.

pattacini commented 1 year ago

⚠️ The square block for the current might be missing.

mfussi66 commented 1 year ago

Also, I would make it clearer that the coefficients depend on Ts. So, Ts may be a further input to the block Compute coefficients.

Nitpicking: in the comment we can see Rt1 and Rt2. Could you update it? We've got only Rt.

⚠️ The square block for the current might be missing.

Woops, silly oversight. Will fix locally, and then put it in a fork after @pattacini checks why the thermal model code is embedded in a function that requires explicit call in the mbdAgent. It is undesired, since it would require a dedicated thread at 10ms.

pattacini commented 1 year ago

after @pattacini checks why the thermal model code is embedded in a function that requires explicit call in the mbdAgent. It is undesired, since it would require a dedicated thread at 10ms.

We will now generate two step functions:

that we need to call accordingly in the glue code. No new thread at 10ms then, just a quick scheduler in the 1ms (a subset of ert_main).

mfussi66 commented 1 year ago

Yesterday afternoon implemented the counter inside the step_time_1ms(), that on the 10th tick calls the step_time_10ms(). The thermal model runs, seemingly correctly, now it just needs proper testing.

mfussi66 commented 1 year ago

To work around the 4096 lines limitation of the debugger printf, I'll publish the temperature on the STATUS CAN packet temporarily.

pattacini commented 1 year ago

As soon as we publish some nice graphs validating the working principle of the model, we can merge upstream against the feat branch.

I'd expect some fiddling to fit the model with the observations. However, this is a different point.

mfussi66 commented 1 year ago

It must be noted that the thermal camera cannot log data faster that one acquisition every 3 seconds. There are also internal parameters, such as emissivity, that need to be tuned depending on the motor housing material. At the moment I covered it with black rubber tape to avoid reflectivity effects.

Maybe we could also use a probe connected to an oscilloscope.

mfussi66 commented 1 year ago

Nonetheless, this is a first acquisition. There is an initial offset between the two measurements that is caused by a previous run of the wrist setup, I did not have time to let it cool down due to timing constraints, but we can clearly see that the difference between the two over time increases.

temperature

here is the data: test_i2t.zip

@fgarini Suggests that the discrepancy might be caused by the fact that we are using the peak ("picco") current instead of its rms value, which in a 3-phase system is $$I{RMS} = I{peak} / \sqrt{3}.$$

pattacini commented 1 year ago

At the moment, we're considering the instantaneous quadrature current squared for simplicity (the direct current is 0), but the assumption may be wrong, actually.

We can switch to the 3-phase currents as input to the model but we need to agree on what kind of operation we should implement to replace the $i^2$ component.

mfussi66 commented 1 year ago

While reflecting on the usage of the 3-phase currents I checked again the discretized model and I noticed I made a mistake during some premature optimization, which caused the steady-state value to be significantly higher.

I took the measurements again with the fixed firmware, but sadly I did not have the tripod, so they are a little shaky. I filtered them with a median filter with a window of 3 samples, and the results are much much better: untitled

📦: i2t_test_2023_04_07.zip

Given this result, I would try to run more tests while using the $I_q$, and switch to the 3-phase currents as needed.

pattacini commented 1 year ago

Came across a useful reference:

At page 14, one reads:

image
pattacini commented 1 year ago

I reckon we can close this task. In the upcoming sprints, we will address two more points: