Correcting axis bend with custom component and HAL

More
07 Dec 2020 02:54 - 08 Dec 2020 18:12 #191290 by tpmagda12
Another 'i cant build straight things' thread!

I recently built a large cnc router (10ft x 4ft) out of steel which required a lot of welding. Unfortunately the welding cause some warping of the Y axis leading to a bit of an irregular curve along the entirety of the Y axis. Although this was concerning i figured it could be compensated for with some good ol fashioned math.

I found two other threads that tried to tackle the same problem:
forum.linuxcnc.org/10-advanced-configura...-correct-axis-errors
forum.linuxcnc.org/10-advanced-configura...on-with-2-7-11#99833

This lead me to create a component as proposed by pgf and Andy Pugh that looks like this
component y_axis_compensation 

license "GPL"; // GPL v2 or later


option singleton yes;


pin in float x-in;
pin in float y-in;
pin out float x-out;
pin out float x-comp;
function cmd;

;;

#include <rtapi_math.h>

FUNCTION(cmd){
    x_comp = - 0.00000000013935308593 * pow(y_in,6) + 0.00000000872640918408 * pow(y_in,5) + 0.00000013374878613596 * pow(y_in,4) - 0.0000118495699768482 * pow(y_in,3) - 0.000112795225635197 *  pow(y_in,2) + 0.00665520947546411 * y_in + 0.00876671144656871;
    x_out = x_comp + x_in;
}

I compiled this without issue and hooked her up to the existing x-pos-cmd and y-pos-cmd and the output was as desired for both x-out and x-comp when looking at the pins and signals using HAL configuration in AXIS.py
net x-pos-cmd => y-axis-compensation.x-in
net y-pos-cmd => y-axis-compensation.y-in

im running into issues when trying to translate this new value into actual motion, im struggling with the actual HAL config to get this to work. initially i tried to just correct if from custom.hal but kept getting all sorts of weird joint following errors (stepper motors). i messed around a lot with trying all sorts of different things but the closest i got to getting it to work was the following in my custom.hal
loadrt y_axis_compensation
addf y-axis-compensation.cmd servo-thread

net x-pos-cmd    <= joint.0.motor-pos-cmd
net x-vel-cmd    <= joint.0.vel-cmd
net x-output     <= hm2_7i96.0.stepgen.00.velocity-cmd
net x-pos-fb     <= hm2_7i96.0.stepgen.00.position-fb
net x-pos-fb    => y-axis-compensation.x-in
net y-pos-cmd    => y-axis-compensation.y-in
net x-pos-comp y-axis-compensation.x-out => joint.0.motor-pos-fb hm2_7i96.0.stepgen.00.position-cmd
net x-enable     <= joint.0.amp-enable-out
net x-enable     => hm2_7i96.0.stepgen.00.enable

net x2-pos-cmd    <= joint.1.motor-pos-cmd
net x2-vel-cmd    <= joint.1.vel-cmd
net x2-output     <= hm2_7i96.0.stepgen.01.velocity-cmd
net x2-pos-fb     <= hm2_7i96.0.stepgen.01.position-fb
net x-pos-comp => joint.1.motor-pos-fb hm2_7i96.0.stepgen.01.position-cmd 
net x2-enable     <= joint.0.amp-enable-out
net x2-enable     <= joint.1.amp-enable-out
net x2-enable     => hm2_7i96.0.stepgen.01.enable

most of this i stole from my HAL file generated by pncconfig and i just inserted it into my custom.hal and removed it from my machine.hal

at machine start this causes both the x and tandem x axis to rotate very quickly about 10 degrees back and forth for about 4 seconds getting smaller with each perturbation until it settles. after it settles it, when i jog the y axis the x axis seems to compensate in AXIS.py but it doesn't seem the motors are actually moving in the real world. I think my error lies somewhere in not really understanding the difference between the following
joint.1.motor-pos-fb 
hm2_7i96.0.stepgen.01.position-fb
joint.1.motor-pos-cmd
hm2_7i96.0.stepgen.01.position-cmd 

i've tried many different variations of the above and still cant seem to get it to work

this is using a Mesa_7i96 if some of the config stuff looks different than what some others have.

free beer for any insight!
Last edit: 08 Dec 2020 18:12 by tpmagda12.

Please Log in or Create an account to join the conversation.

More
08 Dec 2020 18:15 #191436 by tpmagda12
I see this is a lot and maybe i should just boil it down to the following question

what is the difference between the following? I don't understand the difference between cmd and fb
joint.1.motor-pos-fb 
hm2_7i96.0.stepgen.01.position-fb
joint.1.motor-pos-cmd
hm2_7i96.0.stepgen.01.position-cmd 

Please Log in or Create an account to join the conversation.

More
08 Dec 2020 18:25 - 08 Dec 2020 18:25 #191437 by PCW
joint.1.motor-pos-cmd is the position command from LinuxCNC (driven by gcode, MDI or jog commands)
joint.1.motor-pos-cmd is the feedback position from the hardware that tells LinuxCNC
how well the hardware is following the commanded position

BTW you should not run the hardware stepgen in position mode
(hm2_7i96.0.stepgen.0N.position-cmd should be unconnected)

pncconf will make a good velocity mode hardware stepgen hal file
you should use the as a starting point to your modifications
Last edit: 08 Dec 2020 18:25 by PCW.
The following user(s) said Thank You: tpmagda12

Please Log in or Create an account to join the conversation.

More
09 Dec 2020 00:58 - 09 Dec 2020 01:51 #191452 by tpmagda12
ok, so it should be connected to hm2_7i96.0.stepgen.0N.velocity-cmd

As far as i can tell this will be controlled via PID by passing the desired positional value to pid.N.command and then the PID controller would handle the rest via a 'positional loop' comparing the difference between the feedback and the commanded position. Because i am runner a stepper system without any encoder this feedback is actually coming from linuxcnc stepgens.

does that seem to make sense?
Last edit: 09 Dec 2020 01:51 by tpmagda12.

Please Log in or Create an account to join the conversation.

More
09 Dec 2020 01:43 #191457 by PCW
The hm2_7i96.0.stepgen.0N.velocity-cmd pin should be
connected to the PID output.

The PID command is connected to joint.N.motor-pos-cmd
and the PID feedback is connected to hm2_7i96.0.stepgen.0N.position-fb


As I mentioned, pncconf creates these connections (and instantiates
the needed components), so you don't need to bother with any of this
level of detail

Note, it may be cleaner to insert your "fudge factor" by using the external
offsets feature, rather than modifying the position command directly.
The following user(s) said Thank You: tpmagda12

Please Log in or Create an account to join the conversation.

More
09 Dec 2020 01:59 - 09 Dec 2020 02:01 #191459 by tpmagda12
Thanks PCW, you've been a huge help.

i think the external offsets feature makes more sense after looking into it.
Last edit: 09 Dec 2020 02:01 by tpmagda12.

Please Log in or Create an account to join the conversation.

More
09 Dec 2020 02:13 - 09 Dec 2020 02:33 #191462 by tpmagda12
would something like this make sense if i were to just go with the custom.hal approach? basically delete the x-pos-cmd signal created by pncconf and just replacing it with my own.
#custom.hal

delsig x-pos-cmd  # delete signal that is providing position command to pid.x.command
net x-pos-cmd-new joint.0.motor-pos-cmd => y-axis-compensation.x-in # reroute motor-pos-cmd to "fudge factor"
net y-pos-cmd    => y-axis-compensation.y-in
net x-pos-comp y-axis-compensation.x-out => pid.x.command # "fudge factor" becomes new commanded position 
Last edit: 09 Dec 2020 02:33 by tpmagda12.

Please Log in or Create an account to join the conversation.

More
14 Dec 2020 03:08 - 14 Dec 2020 03:10 #191936 by tpmagda12
External offsets was the way to go, works like a charm.Thanks PCW for pointing me in the right direction!. If anyone stumbles across this with a similar question:

Create custom component with your parameters. axis.L.eoffset-counts requires an int(s32) data type so if you are working with anything more precise than 1 machine unit (inche or mm) you are going to have to scale it up and convert to an int(s32). this later will get scaled back down in your custom.hal. Below is an example of mine based off of the post here .
component y_axis_compensation;

option singleton yes;


pin in float x-in;
pin in float y-in;
pin out float x-comp;
pin out s32 x-out;
variable float scale;
variable float m;
function Ycomp;
;;

#include <rtapi_math.h>

FUNCTION(Ycomp){
    x_comp = - 0.00000000067940966640 * pow(y_in,6) + 0.00000009976544202068 * pow(y_in,5) - 0.00000530514086312159 * pow(y_in,4) + 0.00012255623616536600 * pow(y_in,3) - 0.00129152087662694000 *  pow(y_in,2) + 0.00948807979075069000 * y_in + 0.00835436369018987000;
    scale = 0.0001;
    m = x_comp/scale;
    x_out = (int)m;
}


install custom component using halcompile

link it up to your custom.hal
loadrt y_axis_compensation
addf y-axis-compensation.Ycomp servo-thread

# Extenal Axis Offset 
# requires INI: [AXIS_L] OFFSET_AV_RATIO = value (controls accel/vel for external offsets)

setp axis.x.eoffset-scale 0.0001
setp axis.x.eoffset-enable TRUE

net y-pos-cmd => y-axis-compensation.y-in
net x-pos-comp y-axis-compensation.x-out => axis.x.eoffset-counts

and add OFFSET_AV_RATIO to your ini under [AXIS_L] to enable external offsets
[AXIS_X]
OFFSET_AV_RATIO = 0.1

and now she cuts dead straight!
Last edit: 14 Dec 2020 03:10 by tpmagda12. Reason: Thanks to PCW
The following user(s) said Thank You: tommylight, rodw, Aciera

Please Log in or Create an account to join the conversation.

Time to create page: 0.082 seconds
Powered by Kunena Forum