correct handling of a wrapping s32 number in a custom comp
- Henk
- Offline
- Platinum Member
Less
More
- Posts: 395
- Thank you received: 80
07 Feb 2023 14:08 #263937
by Henk
correct handling of a wrapping s32 number in a custom comp was created by Henk
HI
I have a problem with a number in a custom comp used for a gear hobbing machine. My problem is that the hob (spindle) position number wraps which cause a massive ferror on the C axis of the machine.
The hob_position number in the comp file is a float, it doesnt wrap, and will never, but the encoder position (hm2), more specifically the encoder-count wraps because it is an s32. It takes only a couple of hours due to the high resolution of the encoder (96000 counts per spindle rev)
So i came up with this, but im not sure if this is an acceptable sollution.
basically, when the encoder count (s32) wraps, it will be -2,147,483,647 and hob_pos will follow accordingly and will also be negative, but the previous hob pos will still be positive. Increment the wrap counter which results in 2*2,147,483,647/enc_scale to be added to the actual hob position.
Im not a skilled programmer, if this is acceptable, please let me know.
Im planning on posting all the configs for this machine once i ironed out all the bugs
Thank you
I have a problem with a number in a custom comp used for a gear hobbing machine. My problem is that the hob (spindle) position number wraps which cause a massive ferror on the C axis of the machine.
The hob_position number in the comp file is a float, it doesnt wrap, and will never, but the encoder position (hm2), more specifically the encoder-count wraps because it is an s32. It takes only a couple of hours due to the high resolution of the encoder (96000 counts per spindle rev)
So i came up with this, but im not sure if this is an acceptable sollution.
static long s32_maxval = [b]2147483647;[/b]
if (prev_hob_pos > 0 && hob_pos <0) { //wrapping occurred
wrap_counter +=1 ;
}
actual_hob_pos = hob_pos + (s32_maxval / enc_scale)*2*wrap_counter;
prev_hob_pos = hob_pos;
basically, when the encoder count (s32) wraps, it will be -2,147,483,647 and hob_pos will follow accordingly and will also be negative, but the previous hob pos will still be positive. Increment the wrap counter which results in 2*2,147,483,647/enc_scale to be added to the actual hob position.
Im not a skilled programmer, if this is acceptable, please let me know.
Im planning on posting all the configs for this machine once i ironed out all the bugs
Thank you
Please Log in or Create an account to join the conversation.
- andypugh
- Offline
- Moderator
Less
More
- Posts: 23162
- Thank you received: 4860
07 Feb 2023 22:59 #263986
by andypugh
Replied by andypugh on topic correct handling of a wrapping s32 number in a custom comp
If you use the double-precision float "position" of the encoder counter then you probably won't notice the wrap. This is because internally in the encoder counter the s32 counts are copied into an s64 variable and that is used to calculate the (double) position.
An example of wrapping a short encoder into an S64 buffer can be found here, in the LinuxCNC sserial code:
github.com/LinuxCNC/linuxcnc/blob/master...tmot2/encoder.c#L794
Note that this is handling the wrap of an S16 register, so the wrap happens at 65535.
Basically, you store the old encoder counts, and add the difference between that and the new counts to your 64-bit accumulator. If the difference is more than half scale, you assume a wrap, and correct it.
For reference I have attached my own hobbing.comp (but this does no internal wrapping, it just works with the floats. That's worked for me but I don't hob all day every day.
An example of wrapping a short encoder into an S64 buffer can be found here, in the LinuxCNC sserial code:
github.com/LinuxCNC/linuxcnc/blob/master...tmot2/encoder.c#L794
Note that this is handling the wrap of an S16 register, so the wrap happens at 65535.
Basically, you store the old encoder counts, and add the difference between that and the new counts to your 64-bit accumulator. If the difference is more than half scale, you assume a wrap, and correct it.
For reference I have attached my own hobbing.comp (but this does no internal wrapping, it just works with the floats. That's worked for me but I don't hob all day every day.
Please Log in or Create an account to join the conversation.
- Henk
- Offline
- Platinum Member
Less
More
- Posts: 395
- Thank you received: 80
08 Feb 2023 05:08 #264009
by Henk
Replied by Henk on topic correct handling of a wrapping s32 number in a custom comp
HI Andy
Thank you for your reply.
My component was inspired by yours which you shared with me on the mailing list a couple of years ago.
I am using the float position of the spindle encoder as an input to the comp, same as you i believe, originating from the pin hm2_7i94.0.encoder05.position, via signal spindle-revs. This is scaled for 1/spindle rev
The problem is that this float position will go negative along with the s32 count pin when the counts reach 2,147,483,647. I believe that the encoder position is scaled directly from this and is not accumulated in the hm2 driver. see line 906. github.com/LinuxCNC/linuxcnc/blob/master...tmot2/encoder.c#L906 . I verified this on my deckel, yes it took a couple of hours at 3k RPM
Can you do a test with your hobbing component next time you are in your shop? Start the spindle for a couple of seconds before you set a tooth number. i believe this will result in a following error on the A axis. My comp enables the synchronised motion via a hal pin, not the tooth number like yours, so it may be that that prevents this error.....anyway i found a solution to this in the end...
Thank you for your reply.
My component was inspired by yours which you shared with me on the mailing list a couple of years ago.
I am using the float position of the spindle encoder as an input to the comp, same as you i believe, originating from the pin hm2_7i94.0.encoder05.position, via signal spindle-revs. This is scaled for 1/spindle rev
The problem is that this float position will go negative along with the s32 count pin when the counts reach 2,147,483,647. I believe that the encoder position is scaled directly from this and is not accumulated in the hm2 driver. see line 906. github.com/LinuxCNC/linuxcnc/blob/master...tmot2/encoder.c#L906 . I verified this on my deckel, yes it took a couple of hours at 3k RPM
Can you do a test with your hobbing component next time you are in your shop? Start the spindle for a couple of seconds before you set a tooth number. i believe this will result in a following error on the A axis. My comp enables the synchronised motion via a hal pin, not the tooth number like yours, so it may be that that prevents this error.....anyway i found a solution to this in the end...
Please Log in or Create an account to join the conversation.
- Henk
- Offline
- Platinum Member
Less
More
- Posts: 395
- Thank you received: 80
09 Feb 2023 06:10 #264104
by Henk
Replied by Henk on topic correct handling of a wrapping s32 number in a custom comp
It turns out that the method i posted in my initial post is not the correct way to do it. Thanks to Andy's link below to the encoder code (i believe it is hostmot2) i did it this way and it seems to be working. Bear in mind that the hob only rotates one direction
Attached is the component file and the hal file with most of the signals, I still need to add a similar wrapper for the C axis position because that will wrap too if left long enough
This is still very untidy, lacks comments etc, but it works
Thank you Andy.
Henk
static double hob_pos_diff;
hob_pos_diff = hob_pos_enc - prev_hob_pos;
if (hob_pos_diff < -(2147483647/hob_enc_scale)) { //rollover occurred
hob_pos_diff += (2147483647/hob_enc_scale*2);
}
hob_pos += hob_pos_diff;
Attached is the component file and the hal file with most of the signals, I still need to add a similar wrapper for the C axis position because that will wrap too if left long enough
This is still very untidy, lacks comments etc, but it works
Thank you Andy.
Henk
Please Log in or Create an account to join the conversation.
- andypugh
- Offline
- Moderator
Less
More
- Posts: 23162
- Thank you received: 4860
09 Feb 2023 23:32 #264182
by andypugh
Replied by andypugh on topic correct handling of a wrapping s32 number in a custom comp
I was sure that hotmot2 and the HAL encoder kept the counts in a 64-bit buffer. But having looked, they don't.
This commit (in master) adds 64-bit HAL pins, so it should be a fairly easy fix to convert counts and rawcounts to 64-bits.
github.com/LinuxCNC/linuxcnc/commit/7a4c...cb2fe2f6c5b1341c933c
Though that would break any HAL configs that linked the counts / rawcounts, so it might be better to add "rawcounts64" and "counts64" as the actual accumulators and truncate them into the existing ~S32 pins.
This commit (in master) adds 64-bit HAL pins, so it should be a fairly easy fix to convert counts and rawcounts to 64-bits.
github.com/LinuxCNC/linuxcnc/commit/7a4c...cb2fe2f6c5b1341c933c
Though that would break any HAL configs that linked the counts / rawcounts, so it might be better to add "rawcounts64" and "counts64" as the actual accumulators and truncate them into the existing ~S32 pins.
The following user(s) said Thank You: Henk
Please Log in or Create an account to join the conversation.
Time to create page: 0.068 seconds