Axis modulo 360 (not about wrapped_rotary)
29 May 2023 09:33 #272411
by am-i-go
Axis modulo 360 (not about wrapped_rotary) was created by am-i-go
Hello everyone!
I need your help, gentlemen!
There is a servo and a Leadshine motor with an absolute multi-turn encoder. They work on the axis of rotation A, and the axis should be in coordinates modulo 360 degrees.
Now , to simplify the ratio of motor speed and axis one to one - for one rotation of the motor , the axis coordinate changes to 359.999 degrees . At the same time, the value of increments per motor revolution in the drive is 10000 by default, the position-scale parameter 27.7751 is set in the linuxcnc hal file, then the maximum coordinate is recalculated from 10000 to 359.999.
Then I set the wrapped_rotary parameter in the ini file to 1 and when the axis passes through 0 degrees, the error "joint 3 following error" occurs. At low speeds, this error occurs at the 359.2 coordinate and zero crossing does not occur yet, but the axis does not rotate further.
If the encoder is configured as an absolute linear and the axis is wrapped, then I saw how the axis rotates in one direction modulo 360 degrees without errors, but only until the value of the encoder buffer overflows (at 10000 increments per motor revolution it will be 214748 turns) and after that the coordinate jump again leads to the error "joint 3 following error". If I apply the reduction coefficient, then the number of revolutions of the axis without an error in one direction will become much less.
I attach the settings files. Please indicate in which direction to dig.
I need your help, gentlemen!
There is a servo and a Leadshine motor with an absolute multi-turn encoder. They work on the axis of rotation A, and the axis should be in coordinates modulo 360 degrees.
Now , to simplify the ratio of motor speed and axis one to one - for one rotation of the motor , the axis coordinate changes to 359.999 degrees . At the same time, the value of increments per motor revolution in the drive is 10000 by default, the position-scale parameter 27.7751 is set in the linuxcnc hal file, then the maximum coordinate is recalculated from 10000 to 359.999.
Then I set the wrapped_rotary parameter in the ini file to 1 and when the axis passes through 0 degrees, the error "joint 3 following error" occurs. At low speeds, this error occurs at the 359.2 coordinate and zero crossing does not occur yet, but the axis does not rotate further.
If the encoder is configured as an absolute linear and the axis is wrapped, then I saw how the axis rotates in one direction modulo 360 degrees without errors, but only until the value of the encoder buffer overflows (at 10000 increments per motor revolution it will be 214748 turns) and after that the coordinate jump again leads to the error "joint 3 following error". If I apply the reduction coefficient, then the number of revolutions of the axis without an error in one direction will become much less.
I attach the settings files. Please indicate in which direction to dig.
Please Log in or Create an account to join the conversation.
31 May 2023 11:55 #272553
by andypugh
Replied by andypugh on topic Axis modulo 360 (not about wrapped_rotary)
If it is a _multi_ turn encoder this should not happen. Unless the single and multi turn data are on separate HAL pins?
Can you add the partial and full turns together in HAL before calculating the position?
You might end up needing a custom component.
Can you add the partial and full turns together in HAL before calculating the position?
You might end up needing a custom component.
The following user(s) said Thank You: am-i-go
Please Log in or Create an account to join the conversation.
31 May 2023 12:50 #272556
by am-i-go
The "following error" no longer appears, when I changed the parameter in the ini file:
[AXIS_A] => FERROR = 1e99
But it is not clear to me whether I did the right thing by changing the parameter in this way...
Thank you Andy for your help!
Replied by am-i-go on topic Axis modulo 360 (not about wrapped_rotary)
Only multi-turn spin data is read.Unless the single and multi turn data are on separate HAL pins?
The "following error" no longer appears, when I changed the parameter in the ini file:
[AXIS_A] => FERROR = 1e99
But it is not clear to me whether I did the right thing by changing the parameter in this way...
Thank you Andy for your help!
Please Log in or Create an account to join the conversation.
31 May 2023 13:03 #272558
by andypugh
Replied by andypugh on topic Axis modulo 360 (not about wrapped_rotary)
Well, you have set up the system to _never_ flag a following error. At that point you might as well not bother with the encoder feedback.
Please Log in or Create an account to join the conversation.
23 Jun 2023 12:42 - 27 Jun 2023 09:45 #274134
by am-i-go
Replied by am-i-go on topic Axis modulo 360 (not about wrapped_rotary)
I incorrectly described the essence of the problem.
It is necessary to be able to make an indefinitely large (infinite) number of revolutions in any direction and track the angle of the rotating globe table in the value of the coordinate modulo 360 degrees.
1) As I understand it, in this case the axis must necessarily be configured as wrapped . Is that so, there are no other options?
To interaction of linuxcnc with servos, I use a ready-made Hal component cia402 . This component recalculates the values in the following way to get the current position of the servo on the pos_scale (float) scale:
// read position feedback (float pos_fb)
pos_fb = ((double)drv_actual_position) * pos_scale_rcpt;
pin in signed drv_actual_position "Drives actual Position, index 0x6064"
pos_scale_rcpt = 1.0 / pos_scale;
In the case of servos that I use, the value of the current position in the EtherCAT register (6064) is of type int32 (a number in the range of 2147483648 ~ 2147483647 encoder increments). In this case, the pin takes the value of the signed data type (meaning int32), but the HAL documentation specifies the values -2147483647 to +2147483647 , i.e. a negative minimum is 1 more than what is commonly assumed for this type of data. It looks like an error in the documentation, probably this can be ignored ...? It turns out, even though pos_fb has the float type, but we cannot get a value beyond the int32 range of values, because the servo can only transmit int32.
Next, the cia402 Hal component recalculates the position values on the pos_scale scale for the servo movement command:
// write position command (out pin signed drv_target_position)
drv_target_position = (int32_t) (pos_cmd * pos_scale);
pin in float pos_cmd "target Position, from Motion or PID";
Everything is fine here, the command with the int32 data type goes to the servo, as expected.
In my case, with a scale of 23138.953 ... increments by one degree, it turns out to move from the zero value of the current position to the stop of the servo 92808 degrees in both directions. After reaching the value of 2147483647 (or -2147483648) increments, the motor stops without errors on the servo and in linuxcnc, and the coordinate of the rotation angle of the A axis in linuxcnc jumps from 288 to 71 degrees. It is not possible to continue moving in the same direction, the feed rate appears in the interface, but the motor stands still.
2) Explain to me what could be the reason for this behavior?
It is necessary to be able to make an indefinitely large (infinite) number of revolutions in any direction and track the angle of the rotating globe table in the value of the coordinate modulo 360 degrees.
1) As I understand it, in this case the axis must necessarily be configured as wrapped . Is that so, there are no other options?
To interaction of linuxcnc with servos, I use a ready-made Hal component cia402 . This component recalculates the values in the following way to get the current position of the servo on the pos_scale (float) scale:
// read position feedback (float pos_fb)
pos_fb = ((double)drv_actual_position) * pos_scale_rcpt;
pin in signed drv_actual_position "Drives actual Position, index 0x6064"
pos_scale_rcpt = 1.0 / pos_scale;
In the case of servos that I use, the value of the current position in the EtherCAT register (6064) is of type int32 (a number in the range of 2147483648 ~ 2147483647 encoder increments). In this case, the pin takes the value of the signed data type (meaning int32), but the HAL documentation specifies the values -2147483647 to +2147483647 , i.e. a negative minimum is 1 more than what is commonly assumed for this type of data. It looks like an error in the documentation, probably this can be ignored ...? It turns out, even though pos_fb has the float type, but we cannot get a value beyond the int32 range of values, because the servo can only transmit int32.
Next, the cia402 Hal component recalculates the position values on the pos_scale scale for the servo movement command:
// write position command (out pin signed drv_target_position)
drv_target_position = (int32_t) (pos_cmd * pos_scale);
pin in float pos_cmd "target Position, from Motion or PID";
Everything is fine here, the command with the int32 data type goes to the servo, as expected.
In my case, with a scale of 23138.953 ... increments by one degree, it turns out to move from the zero value of the current position to the stop of the servo 92808 degrees in both directions. After reaching the value of 2147483647 (or -2147483648) increments, the motor stops without errors on the servo and in linuxcnc, and the coordinate of the rotation angle of the A axis in linuxcnc jumps from 288 to 71 degrees. It is not possible to continue moving in the same direction, the feed rate appears in the interface, but the motor stands still.
2) Explain to me what could be the reason for this behavior?
Last edit: 27 Jun 2023 09:45 by am-i-go.
Please Log in or Create an account to join the conversation.
11 Jul 2023 13:17 #275208
by andypugh
Ideally the EtherCAT driver would store internal position in a 64-bit integer, which would move the problem into the far, far distant future.
Do you know what data is sent in the actual EtherCAT packet?
Replied by andypugh on topic Axis modulo 360 (not about wrapped_rotary)
This sounds like a simple 32-bit wrap.2) Explain to me what could be the reason for this behavior?
Ideally the EtherCAT driver would store internal position in a 64-bit integer, which would move the problem into the far, far distant future.
Do you know what data is sent in the actual EtherCAT packet?
Please Log in or Create an account to join the conversation.
12 Jul 2023 01:51 #275249
by rodw
It may not be simple. The data from ethercat is mapped to hal pins in an XML file and Hal does not have an int64_t data type.
Perhps the encoder value could be defined in the XML as being 2 x S32's (low byte and high byte) which are then combined in the cia402.comp to create the int64_t. But how can that value be used in HAL?
It seems like an additional S64 data type needs to be added to Hal.to solve these kinds of issues
Replied by rodw on topic Axis modulo 360 (not about wrapped_rotary)
Ideally the EtherCAT driver would store internal position in a 64-bit integer, which would move the problem into the far, far distant future.
It may not be simple. The data from ethercat is mapped to hal pins in an XML file and Hal does not have an int64_t data type.
Perhps the encoder value could be defined in the XML as being 2 x S32's (low byte and high byte) which are then combined in the cia402.comp to create the int64_t. But how can that value be used in HAL?
It seems like an additional S64 data type needs to be added to Hal.to solve these kinds of issues
Please Log in or Create an account to join the conversation.
12 Jul 2023 08:52 #275261
by andypugh
Some encoders and stepgens are internally 64 bits currently. The floating-point position can be calculated from an internal 64-bit buffer. (There are problems presenting the counts / steps, but generally it is the position that is used)
The development version of LinuxCNC does now include 64-bit HAL pin types: github.com/LinuxCNC/linuxcnc/pull/2034
I plan to make the counters which are _not_ 64 bits internally 64 bits: github.com/LinuxCNC/linuxcnc/issues/2331
Replied by andypugh on topic Axis modulo 360 (not about wrapped_rotary)
It may not be simple. The data from ethercat is mapped to hal pins in an XML file and Hal does not have an int64_t data type.
Some encoders and stepgens are internally 64 bits currently. The floating-point position can be calculated from an internal 64-bit buffer. (There are problems presenting the counts / steps, but generally it is the position that is used)
The development version of LinuxCNC does now include 64-bit HAL pin types: github.com/LinuxCNC/linuxcnc/pull/2034
I plan to make the counters which are _not_ 64 bits internally 64 bits: github.com/LinuxCNC/linuxcnc/issues/2331
The following user(s) said Thank You: rodw
Please Log in or Create an account to join the conversation.
12 Jul 2023 21:39 #275303
by rodw
Replied by rodw on topic Axis modulo 360 (not about wrapped_rotary)
Very cool Andy. The halcompile docs need updating for the new type (yes I looked before posting)
linuxcnc.org/docs/devel/html/hal/comp.html
So the issue now for EtherCAT will be that the EtherCAT hal driver is unaware of the new pin type.
A component something like conv_U32hilo_U64.comp would be a handy addition and would allow a workaround to instances like this.
This mythical comp would take the hi and lo 32 bit words (inhi and inlo), shift the hi word and output the sum as a U64 (out64)
linuxcnc.org/docs/devel/html/hal/comp.html
So the issue now for EtherCAT will be that the EtherCAT hal driver is unaware of the new pin type.
A component something like conv_U32hilo_U64.comp would be a handy addition and would allow a workaround to instances like this.
This mythical comp would take the hi and lo 32 bit words (inhi and inlo), shift the hi word and output the sum as a U64 (out64)
Please Log in or Create an account to join the conversation.
12 Jul 2023 22:05 #275306
by andypugh
Replied by andypugh on topic Axis modulo 360 (not about wrapped_rotary)
Actually, I think that your mythical comp is a great idea, as long as it's more like my idea that yours prompted.
wrap_32_64.comp
Takes a 32-bit signed input, and converts to a signed 64 output.
If the 32-bit input changes by more than 30 bits in a single thread cycle, the component assumes a wrap and outputs a wrapped value.
It's simple and solves a bunch of potential use-cases.
wrap_32_64.comp
Takes a 32-bit signed input, and converts to a signed 64 output.
If the 32-bit input changes by more than 30 bits in a single thread cycle, the component assumes a wrap and outputs a wrapped value.
It's simple and solves a bunch of potential use-cases.
The following user(s) said Thank You: rodw
Please Log in or Create an account to join the conversation.
Time to create page: 0.291 seconds