Page 2 of 5

Re: FOC low speed stuttering

Posted: Tue Apr 06, 2021 5:35 am
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.

Re: FOC low speed stuttering

Posted: Tue Apr 06, 2021 5:48 am
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?

Re: FOC low speed stuttering

Posted: Tue Apr 06, 2021 9:03 am
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.

Re: FOC low speed stuttering

Posted: Tue Apr 06, 2021 10:48 am
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

Re: FOC low speed stuttering

Posted: Tue Apr 06, 2021 12:34 pm
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!

Re: FOC low speed stuttering

Posted: Tue Apr 06, 2021 6:03 pm
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.

Re: FOC low speed stuttering

Posted: Wed Apr 07, 2021 8:10 am
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.

Re: FOC low speed stuttering

Posted: Wed Apr 07, 2021 9:44 am
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.

Re: FOC low speed stuttering

Posted: Wed Apr 07, 2021 12:34 pm
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.

Re: FOC low speed stuttering

Posted: Wed Apr 07, 2021 4:51 pm
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.

Re: FOC low speed stuttering

Posted: Sat Apr 10, 2021 12:03 pm
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.

Re: FOC low speed stuttering

Posted: Sat Apr 10, 2021 6:23 pm
by mjc506
Interesting, good find. I'll see if I can fudge some C together :)

Re: FOC low speed stuttering

Posted: Sat Apr 10, 2021 9:05 pm
by johu
Great! Pushed the latest changes so you can built on the latest version.

Re: FOC low speed stuttering

Posted: Thu Apr 15, 2021 9:56 pm
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!

Re: FOC low speed stuttering

Posted: Fri Apr 16, 2021 8:32 am
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...

Re: FOC low speed stuttering

Posted: Sun Apr 18, 2021 9:30 am
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?

Re: FOC low speed stuttering

Posted: Sun Apr 18, 2021 9:41 am
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?

Re: FOC low speed stuttering

Posted: Sun Apr 18, 2021 10:09 am
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...?

Re: FOC low speed stuttering

Posted: Sun Apr 18, 2021 1:04 pm
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

Re: FOC low speed stuttering

Posted: Sun Apr 18, 2021 1:57 pm
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

Re: FOC low speed stuttering

Posted: Sun Apr 18, 2021 2:22 pm
by mjc506
Does the stm32 not like float's at all? hah, ok, I'll give it a go, thanks :)

Re: FOC low speed stuttering

Posted: Sun Apr 18, 2021 3:34 pm
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.

Re: FOC low speed stuttering

Posted: Mon Apr 19, 2021 6:42 pm
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.

Re: FOC low speed stuttering

Posted: Mon Apr 19, 2021 7:44 pm
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.

Re: FOC low speed stuttering

Posted: Mon Apr 19, 2021 8:23 pm
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?