- Configuring LinuxCNC
- Advanced Configuration
- Spindle Step/Dir servo ramp down before stop on M stop command.
Spindle Step/Dir servo ramp down before stop on M stop command.
I did change :
net c-enable => pid.c.enable
net c-pos-cmd => pid.c.command
net spindle-revs => pid.c.feedback
net c-output pid.c.output => mux2.0.in1
# ---closedloop stepper signals---
net c-pos-cmd <= joint.2.motor-pos-cmd joint.2.motor-pos-fb
net c-vel-cmd <= joint.2.vel-cmd
to:
#net c-enable => pid.c.enable
net c-pos-cmd => pid.c.command
net spindle-revs => pid.c.feedback
net c-output pid.c.output => mux2.0.in1
# ---closedloop stepper signals---
net c-pos-cmd <= joint.2.motor-pos-cmd joint.2.motor-pos-fb
net c-vel-cmd <= joint.2.vel-cmd
Then, the P gain was way too high - was 1000 in that file, and I went down to P=4 and it is completely stable. P=10 is to high, large overshoot and then returns to position. P=1 works fine, but takes long to get to position ( seconds). I increased D to 10 - made no difference, so left it ( this on a change of G01 C0 F1000 to G01 C1 F1000, ie, one rotation).
Then I played with FF1 ( is 1 in the file) - increasing to 5, unstable, to 0.5, stable but slow to approach final angle.
P=1, D=0, FF1=1 is stable, but overshoots a little, and then returns to correct angle - this happens slowly
P=4, D=0, FF1=0.8 is good, very slight slight overshoot and return to position.
In operation, from startup -
I home all axes, C included. Then M100. Then if I jog ( on AXIS, set jog increment to 0.5, ie 0.5 X 360deg = 180deg) , the very FIRST jog will rotate to the 180deg position, 'almost' come to a halt, then run on past , fast, 360deg, and reach the 180deg position and stop smoothly. Thereafter a jog to any position goes where intended without moves past the point.
In MDI mode, G01 Cxx Fxx commands move the axis to the angular position OK, but also the very FIRST C axis move command ( WITHOUT having done the jog movement above first) also rotates to commanded position, then runs past 360deg to get to the position again. And G01 Cxx commands thereafter move to the correct position directly.
Almost as though some counter is not cleared on the very first move/jog?
Having done a few MDI C axis moves, if I then do M101, and do a MDI spindle on for a few seconds, then spindle OFF again, then do a M100, the spindle moves to the last C_Axis position it was at before the M101 command. Very Nice!
Andy, this looks very promising indeed. Scaling the C axis next I guess..
I only wish I had a tenth of your abilities with HAL!
Thanks Andy - very nice to watch the lathe do its thing like this!
Joe
Please Log in or Create an account to join the conversation.
This is because the m100 script sets the index-enable. Think of it as re-homing every time you go back to C-axis mode.the very FIRST jog will rotate to the 180deg position, 'almost' come to a halt, then run on past , fast, 360deg, and reach the 180deg position and stop smoothly. Thereafter a jog to any position goes where intended without moves past the point.
This might not be all that hard.Scaling the C axis next I guess.
#modify an existing line
loadrt scale names=scale.spindle,scale.degrees
...
#insert _before_ the pid-calcs addf
addf scale.degrees servo-thread
...
# delete net spindle-revs pid.c.feedback
# replace with
net spindle-revs scale.degrees.in
# = 1/360
setp scale.degrees.gain 0.0027777777777777778
net spindle-degrees scale.degrees.out => pid.c.feedback
You will need to re-tune the PID, and I would always anticipate a bit of I=gain in any PID controller to pull out any static error.
Please Log in or Create an account to join the conversation.
The spindle starts spinning fast right away with M100 - seems to be reducing RPM very slowly.
loadrt [KINS]KINEMATICS
loadrt [EMCMOT]EMCMOT servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS
loadrt hostmot2
loadrt hm2_eth board_ip="10.10.10.10" config=" num_encoders=1 num_pwmgens=0 num_stepgens=4 sserial_port_0=01xxxx"
setp [HMOT](CARD0).watchdog.timeout_ns 5000000
loadrt pid names=pid.x,pid.z,pid.s,pid.c
loadrt abs names=abs.spindle
loadrt lowpass names=lowpass.spindle
loadrt scale names=scale.spindle,scale.degrees # Modified line
loadrt near
loadrt mux16 names=jogincr,foincr,soincr
loadrt mux2 count=1
addf [HMOT](CARD0).read servo-thread
addf motion-command-handler servo-thread
addf motion-controller servo-thread
addf scale.degrees servo-thread #added this
addf pid.x.do-pid-calcs servo-thread
addf pid.z.do-pid-calcs servo-thread
addf pid.s.do-pid-calcs servo-thread
addf pid.c.do-pid-calcs servo-thread
addf mux2.0 servo-thread
addf jogincr servo-thread
addf foincr servo-thread
addf soincr servo-thread
addf scale.spindle servo-thread
addf abs.spindle servo-thread
addf lowpass.spindle servo-thread
addf near.0 servo-thread
addf [HMOT](CARD0).write servo-thread
setp [HMOT](CARD0).dpll.01.timer-us -50
setp [HMOT](CARD0).stepgen.timer-number 1
Then in AXIS C Joint 2:
#*******************
# AXIS C JOINT 2
#*******************
setp pid.c.Pgain [JOINT_2]P
setp pid.c.Igain [JOINT_2]I
setp pid.c.Dgain [JOINT_2]D
setp pid.c.bias [JOINT_2]BIAS
setp pid.c.FF0 [JOINT_2]FF0
setp pid.c.FF1 [JOINT_2]FF1
setp pid.c.FF2 [JOINT_2]FF2
setp pid.c.deadband [JOINT_2]DEADBAND
setp pid.c.maxoutput [JOINT_2]MAX_OUTPUT
setp pid.c.error-previous-target true
#Changes here:
net c-pos-cmd => pid.c.command
net spindle-revs scale.degrees.in
# = 1/360
setp scale.degrees.gain 0.0027777777777777778
net spindle-degrees scale.degrees.out => pid.c.feedback
net c-output pid.c.output => mux2.0.in1
# ---closedloop stepper signals---
net c-pos-cmd <= joint.2.motor-pos-cmd joint.2.motor-pos-fb
net c-vel-cmd <= joint.2.vel-cmd
Please Log in or Create an account to join the conversation.
See if they are, at least, converging.
The spindle should (might) stop when they do.
The P-gain probably needs to be 360x smaller. Or 360x larger. But I would try smaller first.
Please Log in or Create an account to join the conversation.
First, I think the scaling is inverted - to my mind it should be :
# = 360/1
setp scale.degrees.gain 360
# Not 0.0027777777777777778
That seems to get the spindle to the correct angles.
However, its very unstable with odd behaviour.
Pgain is set to 0.1 - anything above 0.5 or so oscillates. Pgain of 0.05 is painfully slow, and does not change the behaviour below.
I set MAX Velocity to 10 and MAX Accel to 50 ( I tried 5 and 5, and 40 and 200 - the latter makes the response worse).
After homing, using MDI -
G01 C90 F1000 moves slowly to 90 deg, past, continues way past, then return to 90 suddenly..
G01 C0 F1000, ditto, the other direction.
Halmeters show: ( For PID.C.Command and PID.C.Feedback)
Feedback starts at big value, and decreases rapidly to 0, and continues -Ve, while Command changes value much more slowly, and when it reaches final value, Feedback has a large -Ve value, which unwinds quickly to converge to the same value as command.
Likewise, the spindle moves from old position, say 0deg, to new, say 90deg, slowly, continues past 90deg, and when command reaches terminal value, feedback and spindle unwind rapidly to the 90deg position.
I played with Pgain, added some Igain, etc made things slower or unstable.
What makes PID.C.Command change so slowly? The C_Axis DRO changes value in tune to the change in the command - the spindle overshoot while feedback grows in the other direction is not reflected in the C_Axis DRO.
What fun...
Thanks Andy!
Joe
Please Log in or Create an account to join the conversation.
What makes PID.C.Command change so slowly?
F1000
1000 degrees / minute is about 3 minutes for a full revolution.
I would try a max vel of about 360 degrees / sec and accel of 3000 degrees/s/s
Then use G0 for positioning moves, or G1 F-numbers in the region of 10,000 degrees/min
Please Log in or Create an account to join the conversation.
What makes PID.C.Command change so slowly?
F1000
1000 degrees / minute is about 3 minutes for a full revolution.
Now you are playing with me...
1000degrees/minute is about 1/3 minute for full revolution - (360deg in 21sec..)
Problems here with 3/1 and 1/3 and 1/360 and 360/1....!
I will try tomorrow - I know though when I set Max Vel to 40 and Max Accel to 200, the thing went unstable, with Pgain - 0.5.
The Max Vel and Max Accel exists in two places under the C axis in the ini file, once for C_Axis and again for JOINT_2
[AXIS_C]
MAX_VELOCITY = 40.0
MAX_ACCELERATION = 100
MIN_LIMIT = -3600
MAX_LIMIT = 3600
[JOINT_2]
TYPE = ANGULAR
HOME = 0
FERROR = 1.0
MIN_FERROR = .1
MAX_VELOCITY = 40.0
MAX_ACCELERATION = 350.0
Could you explain how this works please? And which ones do I change to your suggested test values?
Please Log in or Create an account to join the conversation.
Now you are playing with me...
1000degrees/minute is about 1/3 minute for full revolution - (360deg in 21sec..)
Problems here with 3/1 and 1/3 and 1/360 and 360/1....!
Err, yes. I could try claiming that maths wasn't my strong point, but actually it always has been. I just seem to have made the same mistake twice for some reason. Sorry.
Don't worry about the magnitude. What's right is right. Currently it looks like the right P-gain for the idle speed controller of a car that you might buy next year is 0.014. That's because you get a relatively large number of RPM for one Nm of extra torque. And in your situation you get a relatively large number of degrees for one unit of rps. Your P-gain is likely to need to be somewhere between 1000/360 and 1/360. (And I am 50% sure that I have the numerators and denominators right there)I will try tomorrow - I know though when I set Max Vel to 40 and Max Accel to 200, the thing went unstable, with Pgain - 0.5.
In this case JOINT_2 and AXIS_C are effectively identical, so the numbers in both sections should match. There are situations where you might not want to do it that way, but I don't think that this is one of them.The Max Vel and Max Accel exists in two places under the C axis in the ini file, once for C_Axis and again for JOINT_2
Please Log in or Create an account to join the conversation.
I believe I have the PID control working well, but still need to test with varying inertial mass ( workpiece) in the spindle.
Max Vel and Accel are set to 360 and 3000 resp.
Initially any setting of Pgain between 3 and 0.001 was still unstable, with P>1 being very bad. Small changes in angle <5deg were 'reasonbly' quick and almost stable, so this had to be related to the magnitude of the position change.
Looking at how the PID controller output is structured, the Feedforward term (FF1) would appear to be the culprit since it is multiplied by the command derivative - this forms part of the PID output, and since the change in command is large and instantaneous ( say from 0deg to 360deg), the contribution could be excessive.
I set FF1 = 0 to verify, and it works...the angular changes are rapid, stable, with no discernable overshoot at all.
There was a slight wobble around setpoint, but Deadband was set to 0.0 - since I have a 4096 ppr encoder = 0.088deg/encoder line, I set Deadband to 0.05 and now it is dead still around setpoint.
I will have to optimise the PID later as I am due to replace the integral 5C spindle with a new spindle with a 4" 5C chuck fitted - a long story, but basically a problem with the current spindle design resulting in oil leaks that I cannot resolve, and that the tool plate in the ATC will have to be excessively large in diameter for boring bars/drills to clear the headstock..
Anyway, the 5C chuck will add inertial mass to the spindle so PID may need some work then.
The issues I have..
The behaviour is thus:
Home all Axes, in MDI M100 - all is stable and still.
Then G0 C360 > rotates to 360deg, stops momentarily, then does a fast 360deg rotation and stops at 360deg position and is stable
After that, any C_axis move is stable and correct.
Then do M101, M03 S500 > spindle powers up and is at 500rpm.
Then M05 > spindle stops.
Then M100, and spindle rotates back to the last angular position it was at before the last M101, BUT-
it does this rotate very fast and oscillates heavily - past the point, stops, back again, past the other way, etc - takes a few seconds to stabilise, and thereafter all C_axis moves are fine again. This is repeatable, ie, do M101>M03 S100>M05>M100 and it repeats.
It is as though there are some PID parameters not being used in that initial move to setpoint angle?
For testing ease, is there a way I can setup the INI/HAL so that I only have to home the C axis before doing these tests? Homing X and Z and then C many many times while tuning is boring..
And again, Thanks for all your assistance. Much Appreciated. I do think this topic should somehow be starred as 'important' on the forum as when I started I searched the forum for many hours on the C_axis issue - I found many posts, many attempts, lots of frustration, and seemingly not many solid results - all the variants, using the orient component, and many other ways...Your solution is elegant , simple ( if you know how..) and brilliant!
Thanks
Joe
Please Log in or Create an account to join the conversation.
this forms part of the PID output, and since the change in command is large and instantaneous ( say from 0deg to 360deg), the contribution could be excessive.
The input to the PID should be the C-axis position command, and this is limited by the [JOINT_2]MAX_VELOCITY in G0 and by the F rate in G1 mode and also by the MAX_ACCEL. So it isn't a step-change as such.
[/quote]Then M100, and spindle rotates back to the last angular position it was at before the last M101, BUT-
it does this rotate very fast and oscillates heavily - past the point, stops, back again, past the other way, etc - takes a few seconds to stabilise, and thereafter all C_axis moves are fine again. This is repeatable, ie, do M101>M03 S100>M05>M100 and it repeats.
It is as though there are some PID parameters not being used in that initial move to setpoint angle? [/quote]
Yes, that's right. When you switch to C-mode the position-feedback to the PID will be (for example) a million degrees, and the PID output will be correspondingly very high. This _is_ a step change in input to the PID.
Then the index-enable does it's thing and the position-feedback becomes zero, which is a second step-input.
You can probably calm this down by using pid.c.maxoutput, set that to 400 (it wants to be just a bit more than the max velocity in C axis mode). linuxcnc.org/docs/2.8/html/man/man9/pid.9.html
This method works here largely because you are using step/dir drives with an internal position loop. It wouldn't generally work so well for a VFD or similar.I found many posts, many attempts, lots of frustration, and seemingly not many solid results - all the variants, using the orient component, and many other ways..
It is possible that the orient comp would give a better result here too (it would remove the need for re-indexing every switchover) and with a parallel port system I think one would be looking at running two stepgens and arbitrating between them in HAL. But HAL is too far "upstream" to do that with a Mesa card.
Please Log in or Create an account to join the conversation.
- Configuring LinuxCNC
- Advanced Configuration
- Spindle Step/Dir servo ramp down before stop on M stop command.