Spindle Orient and Rigid Tapping without an Encoder (M19, G33.1)

More
07 Jul 2022 16:06 #246815 by mattroberts
Spindle Orient and Rigid Tapping without an Encoder (M19, G33.1, ...)

Firstly a little bit of background: I am using a servo as my spindle motor, and that servo is connected to a hardware stepgen. With a bit of effort, I'm using the stepgen position-fb to get both spindle orient (M19) and rigid tapping (G33.1, ...) to work.

The main trick is a custom hal component that I wrote. I've called it "stepgenencoder", but that is unlikely to be the best name.
Here is source code for it:
component stepgenencoder "use a stepgen position-fb output as an encoder";
pin in float position-in;
pin io bit index-enable;
pin in bit reset;
pin out float position-out;
variable float offset = 0;
variable float offset_frac = 0;
variable float whole_revs = 0;
function _ fp;
license "GPL";
;;
#include <rtapi_math.h>
FUNCTION(_) {
    float whole_revs_old;

    whole_revs_old = whole_revs;
    whole_revs = floor(position_in - offset);

    if (index_enable && whole_revs != whole_revs_old) {
        offset = floor(position_in - offset_frac) + offset_frac;
        whole_revs = 0;
        index_enable = false;
    }

    if (reset) {
        offset = position_in;
        offset_frac = floor(position_in);
        whole_revs = 0;
    }

    position_out = position_in - offset;
}

The idea is that you connect three signals like this to get rigid tapping to work:
  • position-in <= stepgen.?.position-fb
  • index-enable <=> spindle.0.index-enable (part of the motion hal component)
  • position-out => spindle.0.revs (also part of the motion hal component)

And also connect position-out to a pid control loop for spindle orient to work (see later for a fully working example):
  • position-out => pid.s-pos.feedback

The reset input resets position-out to be zero and also 'moves' the index pulse that a real encoder would have to the current angle.

Anyway, it feels to me that something like stepgenencoder could be added to linuxcnc proper and possibly help a few people out.


In the meantime, what's in this post works (in v2.8.2) and should be a useful reference for anyone in a similar position.

For completeness, here is the relevant parts of the hal file I use with my machine.
in addition to rigid tapping and spindle orient this also controls a spindle-brake and creates a spindle-vel-rpm net.
spindle-brake is only applied when then spindle is almost stopped.
spindle-vel-rpm net is useful for a virtual control panel display showing the spindle-speed
# snip
loadrt pid names=pid.s-pos
loadrt orient
loadrt stepgenencoder
loadrt mux2 names=mux2.s
loadrt near names=near.s-vel,near.s-brake
loadrt and2 names=and2.s-brake
loadrt scale names=scale.s-vel

addf hm2_7i76e.0.read          servo-thread
# snip
addf pid.s-pos.do-pid-calcs   servo-thread
addf orient.0                 servo-thread
addf stepgenencoder.0         servo-thread
addf near.s-vel               servo-thread
addf near.s-brake             servo-thread
addf and2.s-brake             servo-thread
addf scale.s-vel              servo-thread
addf mux2.s                   servo-thread
addf hm2_7i76e.0.write         servo-thread

# snip

# --- spindle velocity stuff ---

setp scale.s-vel.gain 60              # rpm = 60 * rps
setp near.s-vel.difference 1          # spindle-at-speed is within 1rps (i.e. within 60rpm)
setp near.s-brake.difference 0.1      # can apply brake when spindle rps < 0.1 (i.e. rpm < 6)
setp near.s-brake.in2 0               # brake should be applied near 0rps / 0rpm

net spindle-vel           hm2_7i76e.0.stepgen.04.velocity-fb  => spindle.0.speed-in near.s-vel.in1 near.s-brake.in1 scale.s-vel.in
net spindle-vel-rpm       scale.s-vel.out
net spindle-vel-stepgen   mux2.s.out                          => hm2_7i76e.0.stepgen.04.velocity-cmd
net spindle-vel-cmd       spindle.0.speed-out-rps             => near.s-vel.in2 mux2.s.in0
net spindle-vel-cmd-rpm   spindle.0.speed-out
net spindle-at-speed      near.s-vel.out                      => spindle.0.at-speed
net spindle-can-brake     near.s-brake.out                    => and2.s-brake.in0
net spindle-want-brake    spindle.0.brake                     => and2.s-brake.in1
net spindle-brake         and2.s-brake.out


# --- spindle position stuff ---

net spindle-index-enable  spindle.0.index-enable             <=> stepgenencoder.0.index-enable
net spindle-pos-raw       hm2_7i76e.0.stepgen.04.position-fb  => stepgenencoder.0.position-in  
net spindle-pos           stepgenencoder.0.position-out       => spindle.0.revs pid.s-pos.feedback orient.0.position
net spindle-pos-cmd       orient.0.command                    => pid.s-pos.command
net spindle-angle         spindle.0.orient-angle              => orient.0.angle
net spindle-pos-pid       pid.s-pos.output                    => mux2.s.in1
net spindle-in-pos        orient.0.is-oriented                => spindle.0.is-oriented


# --- switch between modes ---

net spindle-velocity-mode spindle.0.on
net spindle-orient-mode   spindle.0.orient                    => orient.0.enable pid.s-pos.enable mux2.s.sel
net spindle-orient-dir    spindle.0.orient-mode               => orient.0.mode


# -- stepgen setup ---

setp   hm2_7i76e.0.stepgen.04.dirsetup        [SPINDLE]DIRSETUP
setp   hm2_7i76e.0.stepgen.04.dirhold         [SPINDLE]DIRHOLD
setp   hm2_7i76e.0.stepgen.04.steplen         [SPINDLE]STEPLEN
setp   hm2_7i76e.0.stepgen.04.stepspace       [SPINDLE]STEPSPACE
setp   hm2_7i76e.0.stepgen.04.position-scale  [SPINDLE]STEP_SCALE
setp   hm2_7i76e.0.stepgen.04.step_type       2 # quadrature output
setp   hm2_7i76e.0.stepgen.04.control-type    1 # velocity mode
setp   hm2_7i76e.0.stepgen.04.maxaccel        [SPINDLE]MAX_ACCELERATION
setp   hm2_7i76e.0.stepgen.04.maxvel          [SPINDLE]MAX_VELOCITY

# keep the stepgen always on so that the spindle always respects MAX_ACCELERATION and doesn't try to stop instantly
# (this probably means that the physical drive enable should be attached to the estop signal for safety)
setp   hm2_7i76e.0.stepgen.04.enable           true


# --- setup the position PID ---

setp   pid.s-pos.Pgain     [SPINDLE]P_POS
setp   pid.s-pos.Igain     [SPINDLE]I_POS
setp   pid.s-pos.Dgain     [SPINDLE]D_POS
setp   pid.s-pos.bias      [SPINDLE]BIAS_POS
setp   pid.s-pos.FF0       [SPINDLE]FF0_POS
setp   pid.s-pos.FF1       [SPINDLE]FF1_POS
setp   pid.s-pos.FF2       [SPINDLE]FF2_POS
setp   pid.s-pos.deadband  [SPINDLE]DEADBAND_POS
setp   pid.s-pos.maxoutput [SPINDLE]MAX_OUTPUT_POS
setp   pid.s-pos.error-previous-target true
# This setting is to limit bogus stepgen
# velocity corrections caused by position
# feedback sample time jitter.
setp   pid.s-pos.maxerror 0.012700
Attachments:
The following user(s) said Thank You: arvidb, drummond, beefy

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

More
07 Jul 2022 16:13 #246817 by mattroberts
Sorry, I shoudl have said that you need to run something like "sudo halcompile --install stepgenencoder.comp" for things to work.

linuxcnc.org/docs/html/man/man1/halcompile.1.html
linuxcnc.org/docs/html/hal/comp.html

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

More
11 Jul 2022 16:39 #247083 by drummond
I gather you are running your spindle servo without feedback from an encoder? Please correct me if I am mistaken.

If I am correct would you take the time to post your complete HAL and INI files? Examples like this are difficult to find, and this is just the information that I'm looking for. Thanks

I'm also enjoying your postings so far, please keep them coming

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

More
11 Jul 2022 17:51 #247090 by mattroberts
I thought that my unfinished complete configuration wouldn't be that interesting. Obviously I am mistaken, the attached zip file contains my complete configuration at the moment.

The standard disclaimer of 'here be dragons' applies.

In particular: I haven't wired a physical estop circuit yet. So if the spindle stalls: it will trash the part and probably the tool as well. That said, I've been using the machine for the last year with only two broken endmills - so I guess the trick is not be bone-headed!
(I only swapped the spindle from the original DC motor to a servo a couple of weeks ago, so that bit is tested much less than the rest of the config).

I gather you are running your spindle servo without feedback from an encoder?


Yes-ish. I have wired the encoder outputs of the servo drive to my 7i76e, but halscope shows very noisy signals. The longer term plan is attach my real oscilloscope to the 7i76e input pins and see what's going on. But in the meantime the stepgen position is good enough (and potentially useful to others - hence the original post).

A youtuber has had problems with noise on the encoder output from a servo, so maybe this is common problem (he talks about it at about 9:40):


For what it is worth: my spindle servo is a 750W Pro-Net ESTUN one, so different to one in that youtube video. 750W sounds small, but it is around 2x-3x the power the original DC motor on the machine (a, now edited, Boxford VMC 280) so it is probably good enough.
Attachments:

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

More
11 Jul 2022 18:28 #247093 by mattroberts
Clarifications:
The hardware encoder is wired to the these three nets: spindle-encoder-pos, spindle-encoder-vel, spindle-encoder-vel-rpm
and they are not used (except to display spindle-encoder-pos in the virtual control panel).

The commented out section starting "# ---digital potentionmeter output signals/setup---" was used to drive the old spindle, which used a traditional 0-10v speed signal.

I have two hardware manual-pulse-generators that I use for jogging.  But the movement per pulse (and which axis is attached to the jog wheel) is controlled by virtual control for time being.

The A axis stuff has only been tested with manually written gcode - so there may well be something silly about the A axis config that I haven't found yet.

Correction:
The machine is a Boxford VMC 260.  Not that it matters, because there is almost no information about it online.
 
The following user(s) said Thank You: drummond

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

More
11 Jul 2022 23:05 #247111 by drummond
First let me say thanks for posting those.

What you have done is admirable because a work in process is just that. I have seen many references to using a velocity mode servo or stepper and switching that to a position mode to perform other operations, lots of mentions but no examples (maybe my google-fu just sucks <lol>)

6 months from now perhaps you have your encoder noise problems sorted out, and you just don't think it's worth documenting what you did before that because "no-one will be interested".

I'm glad you decided to do it the way you did.

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

More
12 Jul 2022 07:53 #247125 by mattroberts
Just a couple of words to anyone stumbling by in the future...
  • All five stepgens are in velocity mode always.  There is one stepgen each of the X, Y, Z, and A axis.  The fifth stepgen drives the spindle.
  • The stepgens for the various axes have a pid loop each to take position targets and tell the stepgens what to do (which is how PnCconf would set them up - so this shouldn't be controversial).
  • The stepgen for the spindle has a pid loop for orientation (or position if you like), once again the output of the pid loop is a velocity.  Which is optionally used depending on the what the motion controller says (spindle.0.orient).
  • Otherwise the stepgen velocity target is taken straight from the motion component (spindle.0.speed-out-rps).
  • The switching of sindle velocity (pid output or spindle.0.speed-out-rps) is done by a mux2.
  • The spindle stepgen has acceleration and velocity limits so that those are enforced even when switching modes.  (with a low enough acceleration, this could certainly work with a lathe spindle).
 
The following user(s) said Thank You: Clive S

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

More
13 Jul 2022 09:01 #247216 by mattroberts

I have seen many references to using a velocity mode servo or stepper and switching that to a position mode to perform other operations, lots of mentions but no examples.


The thing that I found that helped me was this example config from linuxcnc itself (in particular the spindle.hal file):
github.com/LinuxCNC/linuxcnc/tree/master...smach/VMC_toolchange
github.com/LinuxCNC/linuxcnc/blob/master...olchange/spindle.hal

For what it is worth, I had to look in my browser history to find this - a fresh internet search came up blank. I feel your pain.

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

More
14 Jul 2022 22:04 #247326 by drummond
So, a search for "linuxcnc spindle orient" does not find that github page. A search for "linuxcnc orient" finds (4th hit) your second link.

Wait that's a sim development thing, let me go check........

Yes it's in the sample configs under (surprise, surprise) sim, axis, vismach, vmc, toolchange. Pick that and it will write the files into your linux config folder.

It's funny how you can find things when you know what to look for, so I've now got the spindle HAL to look at along with a couple of ini files and gingerbread.
The following user(s) said Thank You: tommylight

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

Time to create page: 0.081 seconds
Powered by Kunena Forum