FOC low speed stuttering

User avatar
johu
Site Admin
Posts: 5684
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 960 times
Contact:

Re: FOC low speed stuttering

Post by johu »

Now I did some calculations. Actually I have set the ADC to run at 12 MHz. Each sample takes 14 ADC clocks, so a new sample every 1.16 us. Since we are sampling 8 channels total, every channel is updated every 9.3 us.
FOC code currently uses the median of the last 3 samples, so of the last 28us. But PWM period (nowadays independent of actual PWM frequency) is 113 us. So I'm throwing out 85 us of data. I think I can safely up the ADC sample size to 12, which will return 112 us of data, so exactly over the time of the last PWM period.

Will try what effect this has later.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
User avatar
bexander
Posts: 834
Joined: Tue Jun 16, 2020 6:00 pm
Location: Gothenburg, Sweden
Has thanked: 63 times
Been thanked: 89 times

Re: FOC low speed stuttering

Post by bexander »

Good idea!
Wouldn't it be more safe to run 11 samples though? 112us vs 113us seem to me a bit to close as some time might be needed to do other calculations and change ADC channel etc?
User avatar
johu
Site Admin
Posts: 5684
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 960 times
Contact:

Re: FOC low speed stuttering

Post by johu »

Here is something you can try. I have increased the S&H time to 7.5 cycles and samples to 10. That means it contains values from 133us, so 2 values from the last PWM cycle actually.

It doesn't feel much different because the vibration is subtle anyway, but maybe it makes a difference on your cars.

Also took an id/iq plot while slightly pushing against the handbrake. You see the oscillation is less with more filtering.

EDIT: il1 and il2 also jitter a similar amount, so I don't think the resolver is the issue.
EDIT2: When no PWM is present the jitter is less, I think that would be the actual ADC jitter. Just a few amps, won't be noticable mechanically.
Attachments
id/iq at standstill
id/iq at standstill
id/iq when pushing against hand brake. 7.5 clocks S&H time, 10 ADC samples
id/iq when pushing against hand brake. 7.5 clocks S&H time, 10 ADC samples
id/iq when pushing against hand brake. 1.5 clocks S&H time, 3 ADC samples
id/iq when pushing against hand brake. 1.5 clocks S&H time, 3 ADC samples
stm32_foc.bin
(41.24 KiB) Downloaded 104 times
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
arber333
Posts: 3241
Joined: Mon Dec 24, 2018 1:37 pm
Location: Slovenia
Has thanked: 74 times
Been thanked: 223 times
Contact:

Re: FOC low speed stuttering

Post by arber333 »

johu wrote: Mon Apr 05, 2021 9:52 am No worries, I think we have established that it is a systematic problem, just more or less pronounced on different vehicles.
Yes the way it is on Touran is very much acceptable (I will make a short video) but I want it to be smooth on all vehicles.
Can i try using the ACIM code on my Mazda? Would it work the same?

tnx

A
User avatar
johu
Site Admin
Posts: 5684
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 960 times
Contact:

Re: FOC low speed stuttering

Post by johu »

No changes to the ACIM code, sorry. That stuttering must have a different cause, probably the way I handle that encoder. Hard to debug without the apparent car, unfortunately. As always, the AC currents do not enter the control loop!
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
User avatar
bexander
Posts: 834
Joined: Tue Jun 16, 2020 6:00 pm
Location: Gothenburg, Sweden
Has thanked: 63 times
Been thanked: 89 times

Re: FOC low speed stuttering

Post by bexander »

I have tested the new SW and the result is no change in stuttering. There are less noise on the id and iq, just as johu got.
I did find something else which I don't understand. Why does fstat go from 0 to 5 in one step, can't get anything in between. I can get the car moving but 0 fstat. Could this have effect on stuttering at very low speeds?
fstat on the left and angle on the right
fstat on the left and angle on the right
Also, there are some disturbance noticable on angle at least when I drive slowly, seen in above picture as well. Hard to see if I go any faster.

A note on having averaging over more than one switch pulse, this could lead to instabillity as you can have changes in output without correspoding change in feedback signal. In this case there is only a small overlap so should be ok for testing.

EDIT: added one more plot to better illustrate the jump in fstat.
fstat on the left and angle on the right
fstat on the left and angle on the right
Above fstat 5 there looks to be any value possible.
User avatar
johu
Site Admin
Posts: 5684
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 960 times
Contact:

Re: FOC low speed stuttering

Post by johu »

frequency calculation happens every 10ms. But only if the rotor has moved more than 10 resolver degrees within 10 ms. By my calculation it should pick up at 2.7 Hz but maybe I forgot something. fstat is used in a few calculations, like regenramp and dynamic integral gain. But since you already tried disabling the latter, it's not that.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
User avatar
johu
Site Admin
Posts: 5684
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 960 times
Contact:

Re: FOC low speed stuttering

Post by johu »

I think you totally have a point. It's the rotor advance compensation:

Code: Select all

//Compensate rotor movement that happened between sampling and processing
syncOfs += FP_TOINT(dir * frq * 10);
So syncofs is modified with speed (or frequency) and if frq is jumpy motor is jumpy! I will look into it later.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
User avatar
johu
Site Admin
Posts: 5684
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 960 times
Contact:

Re: FOC low speed stuttering

Post by johu »

No, not that either. Have programmed it to start advancing at 10 Hz now but the stuttering actually happens before.
It is visible on the plot as about 40A oscillation of id.
You can see frequency picks up at about 2.8Hz. I think it is 5Hz for you because you have a ratio of 1:2 between stator and resolver.

Still attached the binary, maybe it does something. Also changed sample size to 8, so now all values come from within the last cycle.
Attachments
iq_fstat.png
stm32_foc.bin
(41.18 KiB) Downloaded 101 times
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
User avatar
bexander
Posts: 834
Joined: Tue Jun 16, 2020 6:00 pm
Location: Gothenburg, Sweden
Has thanked: 63 times
Been thanked: 89 times

Re: FOC low speed stuttering

Post by bexander »

Tested but without any noticable improvement.

I can't find any signal from the inverter that looks odd or show any sign of the stuttering. If something in SW gives bad output I should be able to see it somehow. It could also be HW or mechanical related. (With mecanical I'm thinking of mechanical oscillation due to backlash in motor/gearbox/driveshaft)
Anyway, if we could find any signal with odd behavior that would really be helpful in finding the issue. As of now all I can find is how it feels in the car.

Maybe I can test sampling angle using this: viewtopic.php?p=18031#p18031
Just to see if I can somehow measure the stuttering.
davefiddes
Posts: 211
Joined: Mon Jan 18, 2021 12:39 pm
Location: Edinburgh, Scotland, UK
Has thanked: 14 times
Been thanked: 35 times

Re: FOC low speed stuttering

Post by davefiddes »

Came across this interesting model from TI which can be used to improve resolver noise immunity: https://e2e.ti.com/support/archive/motor/m/spice/666388 It sets up an observer for the resolver angle which, if I'm understanding it correctly, involves two control loops integrating the acceleration and speed of rotation and relating that to the actual readings. The maths isn't much more complex than two IIR filters.
User avatar
mjc506
Posts: 343
Joined: Wed Sep 09, 2020 9:36 pm
Location: Wales, United Kingdom
Has thanked: 30 times
Been thanked: 28 times

Re: FOC low speed stuttering

Post by mjc506 »

Interesting, good find. I'll see if I can fudge some C together :)
User avatar
johu
Site Admin
Posts: 5684
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 960 times
Contact:

Re: FOC low speed stuttering

Post by johu »

Great! Pushed the latest changes so you can built on the latest version.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
User avatar
mjc506
Posts: 343
Joined: Wed Sep 09, 2020 9:36 pm
Location: Wales, United Kingdom
Has thanked: 30 times
Been thanked: 28 times

Re: FOC low speed stuttering

Post by mjc506 »

Sorry, I've been slow on this and too many other distractions (work sucks...) Finally had a chance to sit down and get my head around it, I've got something nasty that compiles, will test tomorrow a.m... Main anticipated issues are that everything is in s32fp (and then converted from radians to digits), and I haven't worked out the best way of getting/calculating the frequency (or more precisely 1/frequency) that the DecodeAngle() function is called...

In the meantime, here's an .ods with equivalent 'code' that seems to perform quite well!
Attachments
sim.ods
Spreadsheet sim of the code
(4.58 MiB) Downloaded 110 times
User avatar
mjc506
Posts: 343
Joined: Wed Sep 09, 2020 9:36 pm
Location: Wales, United Kingdom
Has thanked: 30 times
Been thanked: 28 times

Re: FOC low speed stuttering

Post by mjc506 »

Hah! Compiles, Flashes, Runs... but stops responding to inputs once you press 'start' :-)

Of course, SineCore::Sine and Cosine take angles as digits, not floats... I'll convert my math to integers and try again...
User avatar
mjc506
Posts: 343
Joined: Wed Sep 09, 2020 9:36 pm
Location: Wales, United Kingdom
Has thanked: 30 times
Been thanked: 28 times

Re: FOC low speed stuttering

Post by mjc506 »

Converted to integer math, compiled, flashed... it runs but then reboots when the inverter is started :( If this was a 'duino I'd do a few printf's... but I don't have the knowledge to debug this, sorry. I can't see any obvious problems...

Updated the sim.ods spreadsheet - it now has a sheet with integer math which seems to work ok.

Here's the code I've got so far:

A couple global variables (sorry)

Code: Select all

//TI encoder observer stuff
//float angle_last = 0; //angle_last = integrator2
static volatile uint16_t integrator1 = 0;
static volatile uint16_t integrator2 = 0;
and then the modified DecodeAngle()

Code: Select all

/** Calculates angle from sin and cos value
 * @param invert flip values to positive side in order to read a resolver modulated signal on negative edge
*/
uint16_t Encoder::DecodeAngle(bool invert)
{
   int sin = adc_read_injected(ADC1, sinChan);
   int cos = adc_read_injected(ADC1, cosChan);
   Param::SetInt(Param::sin, sin); //spit out for debugging
   Param::SetInt(Param::cos, cos);

   //Wait for signal to reach usable amplitude
   if ((resolverMax - resolverMin) > MIN_RES_AMP)
   {
//      if (invert)
//         return SineCore::Atan2(-sin, -cos);
//      return SineCore::Atan2(sin, cos);
      if (invert)
      {
         sin = -sin;
         cos = -cos;
      }
      int16_t angleatan = SineCore::Atan2(sin, cos);
      Param::SetFlt(Param::angleatan, FP_FROMINT(angleatan) / (65536 / 360)); //original atan2 angle calculation

      //TI observer based implementation
      uint16_t K1 = 550;
      uint16_t K2 = 10000;
      float period = 0.0001;// 1/hz?
      int32_t cos_sin_anglast = (cos - (4096/2))*SineCore::Sine(integrator2)/32767; //angle_last = integrator2
      int32_t sin_cos_anglast = (sin - (4096/2))*SineCore::Cosine(integrator2)/32767;
      int16_t sum_one = sin_cos_anglast - cos_sin_anglast;
      integrator1 += sum_one*K2*period;
      int32_t gain1 = sum_one*K1;
      uint32_t sum_two = integrator1 + gain1;
      integrator2 += sum_two*period;
      int32_t sample_delay_comp = period*integrator1/2;
      //angle_last = integrator2;
      uint16_t obs_angle = integrator2-sample_delay_comp; //digits, 2pi rad = 360 deg = 65536 digits
      return obs_angle;
   }
   else
   {
      int temp = MIN(sin, cos);
      resolverMin = MIN(temp, resolverMin);
      temp = MAX(sin, cos);
      resolverMax = MAX(temp, resolverMax);

      if (0 == startupDelay)
      {
         ErrorMessage::Post(ERR_LORESAMP);
      }
      return 0;
   }
}
and there's a new parameter 'angleatan' just to make comparing the two easier. The gains K1 and K2 should probably also be parameters, at least at this initial stage? Also missing is setting 'period' to the time between each function call, but if this is fairly constant could just become part of the gains?
Attachments
sim.ods
Updated to include integer math
(8.52 MiB) Downloaded 92 times
User avatar
zilion
Posts: 58
Joined: Tue Feb 02, 2021 7:50 am
Location: Poland

Re: FOC low speed stuttering

Post by zilion »

johu wrote: Tue Apr 06, 2021 9:03 am Here is something you can try. I have increased the S&H time to 7.5 cycles and samples to 10. That means it contains values from 133us, so 2 values from the last PWM cycle actually.

EDIT: il1 and il2 also jitter a similar amount, so I don't think the resolver is the issue.
EDIT2: When no PWM is present the jitter is less, I think that would be the actual ADC jitter. Just a few amps, won't be noticable mechanically.
Stupid question, but did you calibrated ADC before using it?
I smell lithium in the air. It's not lithium, it's glycolium.
arber333
Posts: 3241
Joined: Mon Dec 24, 2018 1:37 pm
Location: Slovenia
Has thanked: 74 times
Been thanked: 223 times
Contact:

Re: FOC low speed stuttering

Post by arber333 »

zilion wrote: Sun Apr 18, 2021 9:41 am
Stupid question, but did you calibrated ADC before using it?
Hm... from rev3 board schematic i see pin32 (which is AD reference) of the MCU is decoupled to 3V3 by 1uf cap. I have seen most MCUs use 100nf caps for that. I see rev2 olimex board has 100nf there. What are you using?
Reference pin needs to be below or at 3V3 allways for the AD to perform. If there is a voltage excursion on that pin AD could get swamped...?
User avatar
zilion
Posts: 58
Joined: Tue Feb 02, 2021 7:50 am
Location: Poland

Re: FOC low speed stuttering

Post by zilion »

ADC should be calibrated before use.
For libopencm3 method adc_calibrate() should be called before use of ADC. I haven't seen it in the code, so there was my question. But maybe pure registers were used. I dunno.
http://libopencm3.org/docs/latest/stm32 ... 757ab83641
I smell lithium in the air. It's not lithium, it's glycolium.
User avatar
johu
Site Admin
Posts: 5684
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 960 times
Contact:

Re: FOC low speed stuttering

Post by johu »

@mjc: there is still a float in your calculation, substitute it and it should work (or at least not crash)
@zilion: calibration is done in libopeninv/anain.cpp
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
User avatar
mjc506
Posts: 343
Joined: Wed Sep 09, 2020 9:36 pm
Location: Wales, United Kingdom
Has thanked: 30 times
Been thanked: 28 times

Re: FOC low speed stuttering

Post by mjc506 »

Does the stm32 not like float's at all? hah, ok, I'll give it a go, thanks :)
User avatar
johu
Site Admin
Posts: 5684
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 960 times
Contact:

Re: FOC low speed stuttering

Post by johu »

I reckon you need to play with the compiler options. Could never be bothered ;) Would be kind of interesting for the "low speed" projects though. Like BMS, VCU etc.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
User avatar
mjc506
Posts: 343
Joined: Wed Sep 09, 2020 9:36 pm
Location: Wales, United Kingdom
Has thanked: 30 times
Been thanked: 28 times

Re: FOC low speed stuttering

Post by mjc506 »

I think not adjusting compiler options is better :) haha

Thanks for your help and patience. I seem to have some success! Check this out: The left hand side of the graph is the 'new' TI observer code, the right hand side I'd switched back to the 'original' atan2 code. There is a small difference :) Also shown is the raw angle from both codes at the same time - you can just about see the new observer trace peaking out from beneath the atan2 trace.
Image
This is with ~120 digits of noise on sine and cos inputs, 6 polepairs, and 1 respolepair (encoder chip). I suspect 'better' setups won't see quite as much difference.

.bin and .hex files attached, code here: https://github.com/mjc-506/stm32-sine/c ... 913386057a and I will do a pull request Johannes? (These are based on the pure unaltered 5.03.R code)

I think though, that none of the new parameters are needed (they shouldn't need adjusting by the end user - may need adjusting for major code/hardware changes but the 'frequency' variable would probably handle most of that. Also, I see no need to retain the old atan2 code, and no need to have a value on the web interface displaying it either (once well tested of course). In addition, a few of the intermediate variables may not need to be 32bit (cos_sin_anglast, sin_cos_anglast and sum1 could probably be int16_t, sample_delay_comp could probably even get away with int8_t...) but the extra few bits guards against unexpected inputs, especially at startup.

One point of concern: On my hardware, and with my firmware (including other edits), I get no braking/regen - for example, with pot at ~50%, applying pot2 >50% will actually appear to increase throttle and the motor accelerates further (reducing both pots to zero means potnom drops to zero and the motor stops, and increasing pot2 from a stop doesn't start the motor). I can't see any reason that these code changes could/would cause that, and it's entirely possible something strange with my hardware and/or firmware edits is causing this, but please be aware that there's a potential issue here.
Attachments
stm32_foc.bin
(41.59 KiB) Downloaded 85 times
stm32_foc.hex
(117.04 KiB) Downloaded 92 times
stm32_sine.bin
(41.73 KiB) Downloaded 89 times
stm32_sine.hex
5.03.R
(117.43 KiB) Downloaded 92 times
User avatar
johu
Site Admin
Posts: 5684
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 153 times
Been thanked: 960 times
Contact:

Re: FOC low speed stuttering

Post by johu »

That looks very good! I don't quite understand what I'm seeing though. Should angle and angleatan look the same in the right half of the plot?

Yes lets test some more :) I had some similar code for calculating speed from angle change and it turned out too slow on fast speed changes, e.g. a wheel loosing traction and spinning up would trip out the inverter.

No worries about variable sizes, we have plenty of memory.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
User avatar
mjc506
Posts: 343
Joined: Wed Sep 09, 2020 9:36 pm
Location: Wales, United Kingdom
Has thanked: 30 times
Been thanked: 28 times

Re: FOC low speed stuttering

Post by mjc506 »

angleatan and angleobs are resolver degrees (and equal to mechanical degrees on my hardware), angle is scaled somewhere to electrical degrees. My hardware is 6 pole pairs and 1 resolver pole pair, so noise and angle are both *6.

The TI observer can output speed directly, I can add that in?
Post Reply