EmbeddedRelated.com
Forums
The 2026 Embedded Online Conference

encoders measurements in speed control loop

Started by alb February 16, 2015
Hi everyone,

I have to control a sinusoidal BLDC through a PWM and an H-bridge, 
following a profile written in a table.

 I have encoders reading as feedback but I have not quite well 
understood how to measure the difference between the position table and 
the encoders reading.

In general if the encoder reading is in the same turn as the table than 
everything is fine:

p = 78 deg (position)
m = 75 deg (measure)

e = p - m = 3 deg

But when I cross the 0 deg (360 deg) I have some stupid issues with signs:

p = 359 deg
m = 1   deg

e = p - m = 358 deg

while I would like to get -2 deg!
Even with modulo function I'd not be better off:

e = mod(p - m, 360) = 358 deg!

Should it be dependent on the quadrant I'm in?

I'm missing some basics here. And yes, a pointer to elementary school 
math is definitely appreciated!

Al

-- 
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Hi Al (yep...splitted personality!),

alb <al.basili@gmail.com> wrote:
[skip math rant]

in order to get the difference between two angles it is sufficient to do 
the following:

diff = abs(a - b)
if diff > pi:
  diff = 2*pi - diff

the sign calculation is left to the reader.

Al
On 2015-02-16, alb <al.basili@gmail.com> wrote:

> In general if the encoder reading is in the same turn as the table > than everything is fine: > > p = 78 deg (position) > m = 75 deg (measure) > > e = p - m = 3 deg > > But when I cross the 0 deg (360 deg) I have some stupid issues with signs: > > p = 359 deg > m = 1 deg > > e = p - m = 358 deg > > while I would like to get -2 deg! > Even with modulo function I'd not be better off: > > e = mod(p - m, 360) = 358 deg! > > Should it be dependent on the quadrant I'm in? > > I'm missing some basics here. And yes, a pointer to elementary school > math is definitely appreciated!
The way this used to be solved "back in the day" when I was writing code for Navy fire control computers is that you pick a word width for which your architecture supports both usnigned and 2's compliment arithmetic (let's say 16-bits). You encode 0 degrees as binary value 0, and you encode 360 degrees as 2**16 (also represented by binary varlue 0). [This was referred to as BAM encoded: Binary Angular Measurement]. Now you do all your arithmatic using normal integer math. If your answer is supposed to be a 'relative heading' then you want the '-2' answer and you cast the value as (int). If the answer is supposed to be an absolute heading then you want the '358' answer and you cast the value as (unsigned). Those computers had single instructions to do trig functions on BAM values, and also a single instruction that converted a (radius,BAM) polar tuple [in a register pair] pair into an (easting,northing) cartesian tuple. And there was another instruction that did the converse. A lot of the protocols and peripherals were specified so that angular data was represted as BAM encoded words. -- Grant Edwards grant.b.edwards Yow! Well, O.K. at I'll compromise with my gmail.com principles because of EXISTENTIAL DESPAIR!
On Mon, 16 Feb 2015 15:21:15 +0000, Grant Edwards wrote:

> On 2015-02-16, alb <al.basili@gmail.com> wrote: > >> In general if the encoder reading is in the same turn as the table than >> everything is fine: >> >> p = 78 deg (position) >> m = 75 deg (measure) >> >> e = p - m = 3 deg >> >> But when I cross the 0 deg (360 deg) I have some stupid issues with >> signs: >> >> p = 359 deg m = 1 deg >> >> e = p - m = 358 deg >> >> while I would like to get -2 deg! >> Even with modulo function I'd not be better off: >> >> e = mod(p - m, 360) = 358 deg! >> >> Should it be dependent on the quadrant I'm in? >> >> I'm missing some basics here. And yes, a pointer to elementary school >> math is definitely appreciated! > > The way this used to be solved "back in the day" when I was writing code > for Navy fire control computers is that you pick a word width for which > your architecture supports both usnigned and 2's compliment arithmetic > (let's say 16-bits). You encode 0 degrees as binary value 0, and you > encode 360 degrees as 2**16 (also represented by binary varlue 0). [This > was referred to as BAM encoded: Binary Angular Measurement]. Now you do > all your arithmatic using normal integer math. If your answer is > supposed to be a 'relative heading' then you want the '-2' answer and > you cast the value as (int). If the answer is supposed to be an absolute > heading then you want the '358' answer and you cast the value as > (unsigned). > > Those computers had single instructions to do trig functions on BAM > values, and also a single instruction that converted a (radius,BAM) > polar tuple [in a register pair] pair into an (easting,northing) > cartesian tuple. And there was another instruction that did the > converse. > > A lot of the protocols and peripherals were specified so that angular > data was represted as BAM encoded words.
Heh. I used that back at my last corporate job without ever knowing there was an official name for it. It's convenient as hell, and quite satisfying to be able to use fixed- point rollover for gain, instead of having it do horrible things to you. -- www.wescottdesign.com
On 2015-02-16, Tim Wescott <tim@seemywebsite.com> wrote:
> On Mon, 16 Feb 2015 15:21:15 +0000, Grant Edwards wrote: >> On 2015-02-16, alb <al.basili@gmail.com> wrote:
[...]
>>> But when I cross the 0 deg (360 deg) I have some stupid issues with >>> signs: >>> >>> p = 359 deg m = 1 deg >>> >>> e = p - m = 358 deg >>> >>> while I would like to get -2 deg! >>> Even with modulo function I'd not be better off: >>> >>> e = mod(p - m, 360) = 358 deg! >>> >>> Should it be dependent on the quadrant I'm in? >>> >>> I'm missing some basics here. And yes, a pointer to elementary school >>> math is definitely appreciated! >> >> The way this used to be solved "back in the day" when I was writing code >> for Navy fire control computers is that you pick a word width for which >> your architecture supports both usnigned and 2's compliment arithmetic >> (let's say 16-bits). You encode 0 degrees as binary value 0, and you >> encode 360 degrees as 2**16 (also represented by binary varlue 0). [This >> was referred to as BAM encoded: Binary Angular Measurement]. Now you do >> all your arithmatic using normal integer math. If your answer is >> supposed to be a 'relative heading' then you want the '-2' answer and >> you cast the value as (int). If the answer is supposed to be an absolute >> heading then you want the '358' answer and you cast the value as >> (unsigned). >> >> Those computers had single instructions to do trig functions on BAM >> values, and also a single instruction that converted a (radius,BAM) >> polar tuple [in a register pair] pair into an (easting,northing) >> cartesian tuple. And there was another instruction that did the >> converse. >> >> A lot of the protocols and peripherals were specified so that angular >> data was represted as BAM encoded words. > > Heh. I used that back at my last corporate job without ever knowing > there was an official name for it.
Turns out there's a nice writeup on Wikepedia about it: http://en.wikipedia.org/wiki/Binary_scaling#Binary_angles
> It's convenient as hell, and quite satisfying to be able to use fixed- > point rollover for gain, instead of having it do horrible things to you.
Yep. There were some very expensive, wildly inefficient, and sometimes just horribly designed features in some of those shipboard mini-computer systems, but I was impressed with the binary angule stuff and the thought that went into the extra machine instructions to support it. -- Grant Edwards grant.b.edwards Yow! I'll eat ANYTHING at that's BRIGHT BLUE!! gmail.com
On 16.2.15 19:07, Grant Edwards wrote:
> On 2015-02-16, Tim Wescott <tim@seemywebsite.com> wrote: >> On Mon, 16 Feb 2015 15:21:15 +0000, Grant Edwards wrote: >>> On 2015-02-16, alb <al.basili@gmail.com> wrote: > [...] >>>> But when I cross the 0 deg (360 deg) I have some stupid issues with >>>> signs: >>>> >>>> p = 359 deg m = 1 deg >>>> >>>> e = p - m = 358 deg >>>> >>>> while I would like to get -2 deg! >>>> Even with modulo function I'd not be better off: >>>> >>>> e = mod(p - m, 360) = 358 deg! >>>> >>>> Should it be dependent on the quadrant I'm in? >>>> >>>> I'm missing some basics here. And yes, a pointer to elementary school >>>> math is definitely appreciated! >>> >>> The way this used to be solved "back in the day" when I was writing code >>> for Navy fire control computers is that you pick a word width for which >>> your architecture supports both usnigned and 2's compliment arithmetic >>> (let's say 16-bits). You encode 0 degrees as binary value 0, and you >>> encode 360 degrees as 2**16 (also represented by binary varlue 0). [This >>> was referred to as BAM encoded: Binary Angular Measurement]. Now you do >>> all your arithmatic using normal integer math. If your answer is >>> supposed to be a 'relative heading' then you want the '-2' answer and >>> you cast the value as (int). If the answer is supposed to be an absolute >>> heading then you want the '358' answer and you cast the value as >>> (unsigned). >>> >>> Those computers had single instructions to do trig functions on BAM >>> values, and also a single instruction that converted a (radius,BAM) >>> polar tuple [in a register pair] pair into an (easting,northing) >>> cartesian tuple. And there was another instruction that did the >>> converse. >>> >>> A lot of the protocols and peripherals were specified so that angular >>> data was represted as BAM encoded words. >> >> Heh. I used that back at my last corporate job without ever knowing >> there was an official name for it. > > Turns out there's a nice writeup on Wikepedia about it: > > http://en.wikipedia.org/wiki/Binary_scaling#Binary_angles > >> It's convenient as hell, and quite satisfying to be able to use fixed- >> point rollover for gain, instead of having it do horrible things to you. > > Yep. There were some very expensive, wildly inefficient, and sometimes > just horribly designed features in some of those shipboard > mini-computer systems, but I was impressed with the binary angule > stuff and the thought that went into the extra machine instructions to > support it.
One more vote for this. I used it a couple of decades ago in a flight simulator (on a PDP-11). -- -TV
Den mandag den 16. februar 2015 kl. 10.22.21 UTC+1 skrev alb:
> Hi everyone, > > I have to control a sinusoidal BLDC through a PWM and an H-bridge, > following a profile written in a table. > > I have encoders reading as feedback but I have not quite well > understood how to measure the difference between the position table and > the encoders reading. > > In general if the encoder reading is in the same turn as the table than > everything is fine: > > p = 78 deg (position) > m = 75 deg (measure) > > e = p - m = 3 deg > > But when I cross the 0 deg (360 deg) I have some stupid issues with signs: > > p = 359 deg > m = 1 deg > > e = p - m = 358 deg > > while I would like to get -2 deg! > Even with modulo function I'd not be better off: > > e = mod(p - m, 360) = 358 deg! > > Should it be dependent on the quadrant I'm in? > > I'm missing some basics here. And yes, a pointer to elementary school > math is definitely appreciated! >
the issue is that there is no way to tell if you are 2 degrees ahead or 358 degrees behind if you want the error to always be in the range +/-180, then if the result is over 180, subtract 360 -Lasse
On 16 Feb 2015 09:22:17 GMT, al.basili@gmail.com (alb) wrote:

>Hi everyone, > >I have to control a sinusoidal BLDC through a PWM and an H-bridge, >following a profile written in a table. > > I have encoders reading as feedback but I have not quite well >understood how to measure the difference between the position table and >the encoders reading. > >In general if the encoder reading is in the same turn as the table than >everything is fine: > >p = 78 deg (position) >m = 75 deg (measure) > >e = p - m = 3 deg > >But when I cross the 0 deg (360 deg) I have some stupid issues with signs: > >p = 359 deg >m = 1 deg > >e = p - m = 358 deg > >while I would like to get -2 deg! >Even with modulo function I'd not be better off: > >e = mod(p - m, 360) = 358 deg! > >Should it be dependent on the quadrant I'm in? > >I'm missing some basics here. And yes, a pointer to elementary school >math is definitely appreciated! > >Al
Have just solved this very problem for filtering the signal from a wind indicator that sends an analog signal of 0 - 360 degrees. In order to remove the discontinuity, you need to determine when it's crossed, and in which direction, this requires a suitably fast scanning rate. Say then that the direction goes 355-358-2, then you know that the angle has 'increased'. So add 360 to get 362 degrees. You can then apply a modulo function to get 2. Going the other way, eg. 5-2-357, subtract 360 to get -3. The operation is fully symmetrical in each direction. You extend the range of the angle to +/- infinity, then use modulus to bring it back to a real range. If the rotation is always one way and the extended angle value is likely to get very large in one direction, you need to do a reset when it goes above a trigger value. You can also deal with this using coss and sins and their inverses, but that's rather inelegant IMO.
On Tue, 17 Feb 2015 20:14:02 +0800, Bruce Varley wrote:

> On 16 Feb 2015 09:22:17 GMT, al.basili@gmail.com (alb) wrote: > >>Hi everyone, >> >>I have to control a sinusoidal BLDC through a PWM and an H-bridge, >>following a profile written in a table. >> >> I have encoders reading as feedback but I have not quite well >>understood how to measure the difference between the position table and >>the encoders reading. >> >>In general if the encoder reading is in the same turn as the table than >>everything is fine: >> >>p = 78 deg (position) >>m = 75 deg (measure) >> >>e = p - m = 3 deg >> >>But when I cross the 0 deg (360 deg) I have some stupid issues with >>signs: >> >>p = 359 deg m = 1 deg >> >>e = p - m = 358 deg >> >>while I would like to get -2 deg! >>Even with modulo function I'd not be better off: >> >>e = mod(p - m, 360) = 358 deg! >> >>Should it be dependent on the quadrant I'm in? >> >>I'm missing some basics here. And yes, a pointer to elementary school >>math is definitely appreciated! >> >>Al > > Have just solved this very problem for filtering the signal from a wind > indicator that sends an analog signal of 0 - 360 degrees. In order to > remove the discontinuity, you need to determine when it's crossed, and > in which direction, this requires a suitably fast scanning rate. Say > then that the direction goes 355-358-2, then you know that the angle has > 'increased'. So add 360 to get 362 degrees. You can then apply a modulo > function to get 2. Going the other way, eg. 5-2-357, subtract 360 to get > -3. The operation is fully symmetrical in each direction. You extend > the range of the angle to +/- infinity, then use modulus to bring it > back to a real range. > > If the rotation is always one way and the extended angle value is likely > to get very large in one direction, you need to do a reset when it goes > above a trigger value. > > You can also deal with this using coss and sins and their inverses, but > that's rather inelegant IMO.
Yes, encoders can be an excellent way to measure motor speed, but only if you can insure that you sample the encoder position faster than twice per revolution. -- Tim Wescott Wescott Design Services http://www.wescottdesign.com
On Tue, 17 Feb 2015 13:03:50 -0600, Tim Wescott
<seemywebsite@myfooter.really> wrote:

>On Tue, 17 Feb 2015 20:14:02 +0800, Bruce Varley wrote: > >> On 16 Feb 2015 09:22:17 GMT, al.basili@gmail.com (alb) wrote: >> >>>Hi everyone, >>> >>>I have to control a sinusoidal BLDC through a PWM and an H-bridge, >>>following a profile written in a table. >>> >>> I have encoders reading as feedback but I have not quite well >>>understood how to measure the difference between the position table and >>>the encoders reading. >>> >>>In general if the encoder reading is in the same turn as the table than >>>everything is fine: >>> >>>p = 78 deg (position) >>>m = 75 deg (measure) >>> >>>e = p - m = 3 deg >>> >>>But when I cross the 0 deg (360 deg) I have some stupid issues with >>>signs: >>> >>>p = 359 deg m = 1 deg >>> >>>e = p - m = 358 deg >>> >>>while I would like to get -2 deg! >>>Even with modulo function I'd not be better off: >>> >>>e = mod(p - m, 360) = 358 deg! >>> >>>Should it be dependent on the quadrant I'm in? >>> >>>I'm missing some basics here. And yes, a pointer to elementary school >>>math is definitely appreciated! >>> >>>Al >> >> Have just solved this very problem for filtering the signal from a wind >> indicator that sends an analog signal of 0 - 360 degrees. In order to >> remove the discontinuity, you need to determine when it's crossed, and >> in which direction, this requires a suitably fast scanning rate. Say >> then that the direction goes 355-358-2, then you know that the angle has >> 'increased'. So add 360 to get 362 degrees. You can then apply a modulo >> function to get 2. Going the other way, eg. 5-2-357, subtract 360 to get >> -3. The operation is fully symmetrical in each direction. You extend >> the range of the angle to +/- infinity, then use modulus to bring it >> back to a real range. >> >> If the rotation is always one way and the extended angle value is likely >> to get very large in one direction, you need to do a reset when it goes >> above a trigger value. >> >> You can also deal with this using coss and sins and their inverses, but >> that's rather inelegant IMO. > >Yes, encoders can be an excellent way to measure motor speed, but only if >you can insure that you sample the encoder position faster than twice per >revolution.
Hey, that's a nice visualisation of Shannons theorem (I think).
The 2026 Embedded Online Conference