PID tuning: one vs multiple loops, gain scheduling

More
01 Nov 2014 06:35 - 01 Nov 2014 06:39 #52638 by DaBit
Note upfront: I think the best method to document all this is to put in on the wiki.

Thanks for posting this thread DaBit! It is as others have said a very interesting thread.

If possible could you go through each of the parameters you are using? I have a rudimental idea on what each one means, but if I'm to implement this myself I would prefer to have a detailed knowledge on what each of the parameters do.


No, you do not. You need to fully understand how the system works in order to be able to tune it and make it work the way you want it to work. These kind of configurations are not as versatile as a parport stepper config. The best way to do that is start the HAL file from scratch and build it from the ground up for your situation. It seems a lot of work, but that makes you think twice about every decision, forces you to understand what's going on, and saves you a lot of time killing gremlins in the long run. Whenever you get stuck you peek in various sample files like my configuration to see how someone else solved it. There really is no substitute for 'doing' I'm afraid.

But a flying start never hurts, does it?

I'll take the Y-axis:
[AXIS_1]
TYPE =                  LINEAR				# linear axis
MAX_VELOCITY =          300.0				# max velocity 300mm/min
MAX_ACCELERATION =      2500.0				# max acceleration 2500mm/sec^2
BACKLASH =              0.000				# no backlash compensation. Whenever you start with scales, make sure the mechanics contain as little lost motion as possible
FERROR =                5					# maximum allowable deviation between commanded and actual position. 5mm is a 'debugging value'
MIN_FERROR =            1
INPUT_SCALE =           -1227.6				# There are a measured 1227.6 rotary (servo) encoder pulses in a millimeter. depends on average screw lead, transmission ratio and numver of lines of the servo encoder
INPUT_SCALE_LINEAR_Y1 = -1000				# linear scale resolution for left Y joint. Scale is a 1um-reslution device. 
INPUT_SCALE_LINEAR_Y2 = -1000				# linear scale resolution for right Y joint. Scale is a 1um-reslution device. 
OUTPUT_SCALE =          3					# My servo amps produce 300% overtorque when fed with 10V, so whent he Mesa analog out is set to 1.0 the servo produces nominal torque
OUTPUT_SCALE_NEG =	-3
OUTPUT_OFFSET =         0.0
VEL_MAX_OUTPUT =        3					# Velocity loop may use all available torque.
MIN_LIMIT =             -630.0				# axis limits
MAX_LIMIT =             25.0
HOME =                  0.000				# homing
HOME_OFFSET =           0.0
HOME_SEARCH_VEL =       200.0
HOME_LATCH_VEL =        -2.0
HOME_USE_INDEX =        NO					# I'd love to use index pulses, but I haven't been able to get multiple encoders (rotary and linear) and index pulses working reliably
HOME_IGNORE_LIMITS =    YES
HOME_SEQUENCE = 	1
VEL_P =                 0.045				# Velocity loop Kp coefficient
VEL_I =                 8					# Velocity loop Ki coefficient.
VEL_D =                 0.000012			# Velocity loop Kd coefficient. This one is important; tune this one first. 
VEL_FF0 =               0.005				# Velocity feedforward to compensate for friction
VEL_FF1 =               9e-05				# Acceleration feedforward to compensate for mass to be accelerated.
VEL_MAX_OUTPUT = 		3					# Oops, we had that one already...
VEL_FILTER_FC = 		1000				# Velocity signal filter cutoff. Especially at low rotational speeds with 'little' encoder resolution the velocity signal is noisy. This smooths out the noise a little. Start at half the servo frequency, and decrease from there but don;t go overboard
POS_P_LO =              250					# Position loop Kp, used when the servo is close to the commanded position. Keeping this slightly on the low side prevents servo hunting
POS_P_HI = 				900					# Position loop Kp, used when the servo is 'far away' from the commanded position. This causes a agressive response to disturbances, stiffening the positioning
POS_P_ERR =				0.03				# When the error is 0, POS_P_LO is used. The Kp is increased up to POS_P_HI, and reaches that point when the error reaches this number.
POS_I =                 0					# Position loop Ki. Not used in my case since the integrator action is in the scale loop. 
POS_D =                 0
POS_FF0 =               0
POS_FF1 =               1					# We do a 1-on-1 feedforward of the required velocity to the velocity loop
POS_FF2 =				0
POS_DEADBAND= 			0.0015				# to make sure that the servo reaches a position where it is happy, we need a dead band slightly larger than 1 or 2 encoder pulses
POS_MAX_OUTPUT = 		700					# Cap on the velocity command to the velocity loop. Set higher than actual maximum velocity to make sure the loop can do corrections.
SLAVEAXES_MAXDEVIATION=	1					# The two Y joints on the gantry cannot be allowed to deviate; that would destroy the gantry. Here is the maximum error; 1mm. Which is actually -0.5mm .. +0.5mm
SCALE_P =		0							
SCALE_I = 		20							# Scale correction loop coefficients. The scale uses only a fairly slow integrating action to slowly correct errors that creep in the system. Accumulated lead error, temperature, etc.
SCALE_D = 		0
SCALE_DEADBAND = 	0.0015					# See POS_DEADBAND
SCALE_MAXCORR = 	2						# The scale is allowed to make a maximum correction of 2mm. If it breaks, nothing bad happens since it can only move 2mm. Now, 2mm is much higher than the actual error over the travel range, but a slightly higher number gives the loop more authority to correct errors.

It's a good thing you share your config files, but to be honest they are growing so big it's hard to keep track on all the involved parts in there. And for ease of access would you mind posting them all as a zip (or tar) file so we can download them and look at them side by side in our favorite editor?


Sure. I will prepare an archive without too much clutter (the config directory is also full with .halscope files etc. )

Just to clarify a few things first, you are using 3 PID loops here? One for the velocity, one for position and one for scale?


Yes.

And you are using the rotary encoder feedback (mounted on the motor shaft) as input to the first two loops, then use the linear scale as input for the last (the scale) loop?


Yes. The rotary encoder on the servo does the actual positioning, split over two loops. The scale only says 'Hey, you think you are at the correct position, but I measured it and you are 0,04mm off. Would you please move 0,04mm slowly?'

And you are scaling the units so your output are scaled to mm (and mm/s and mm/s^2)?


Yes, indeed. The exception is torque output; that one is scaled so that an output of 1.0 means 'maximum continuous torque'.

I'm not sure I'm able to follow you on how you scale the different PID loops. Could you please break down each one of the loops and clarify what each do, where they get their data from, where they feed their outputs to and how each one is scaled?

I notice you have set num_encoders=8. I suppose that is the correct way to tell it the number of encoder inputs to use. But how do I know what encoder inputs are what number? The 7i77 have only 6. I have a 7i85 card to increase the number of encoders. Will it work for me to just increase the number of encoders as long as I have the hardware to support it? I would hope it's that easy.


It is that easy. I am currently running 7i76+7i77 firmware in the 6i25 FPGA board. The 7i77 provides 6 encoders, the 7i76 allows two more.
I do not have an actual 7i76; the breakout board on the second port is custom. I ordered a 7i85S to replace it with some nicely made hardware instead of a bunch of wires and components on a breadboard.

The output of a dmesg command tells you where the encoders are located. I'll leave the exact answer to PCW (or wait until my 7i85S arrives)

I took a look at the build thread you started about this mill. It's very good. Too bad it's in Dutch though..... I have to use Google translate to read it, but it has big problems with Dutch it seems. The words come out in the wrong order for some reason. I guess Dutch have a different way of putting the order of the words in a sentence.


Well, sorry. The Dutch forum is also the best place to get local help, so it hardly makes sense to create a topic on cnczone.com or so.
Luckily for you there are plenty of pictures. :)

I'm in the middle of attaching the rotary encoders on my motors as we speak. I'm planning to do most of what you are doing here. But for my part I'm still planning on using the original drives with speed input. So therefore I don't need to implement the inner speed PID loop. That means I need to edit out everything involving that loop. This is why I need to be able to understand in detail where each loop takes it's signals from and where they send them.
I do have a 8i20 amplifier that I plan on implementing soon as well. With that I will need to implement the velocity loop again.

From what I understood you had some problems with homing and index mentioned in your thread. The translation was so bad I wasn't able to understand fully what you were saying. But I think it was something like LinuxCNC doesn't understand there are multiple encoders, and don't know what encoder to take index from when homing. I hope there is an easy way to solve this? And I hope it's fairly straight forward to make it use the linear scale index as homing reference? I have homing working as it should now (with linear scales only). But I would hate to have the rotary encoder index come in and messing this up.
Did you find a solution to this?


No, not reliable, and this is something still on the list but not with a very high priority.
I had a situation where all I got was a single following error, and when I 'powered the machine back on' I could restart the homing sequence and all was fine.
But I also had a severe crash. During homing my limit switches are disabled (they work as limit switch until the machine is homed, then I switch over to soft limits), and somehow the resetting caused a fullspeed move toward the mechanical stop. The crash was hard enough to bend a 20mm thick piece of aluminium out of shape. :whistle:
The second problem is that the index pulses of the 1um scale happen at very inconvenient locations. With the Z axis 80mm down, for example. With 200mm travel that is almost half the range.

All in all I don't like the 'reset counters on index pulse' method LinuxCNC uses although I understand why they do it. Being able to just latch the position when an index pulse occcurs would suit me better. then it would be easy to say 'hey, you think you are at machine coord -100.00, but I measured it and you're 0.02mm off. Can you correct that position for me?'. This could be done at any location when the axis passes that location.

The hostmot2 encoder components seem to offer latch-xxx pins for a function like that, but they are not documented in the manpage (maybe in the source, didn't check that) and in the 5 minutes I played with them I was not able to capture a position. Probably user error. As I said before: index homing is a bit low on the priority list since homing to switches is quite accurate too.
Last edit: 01 Nov 2014 06:39 by DaBit.

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

More
01 Nov 2014 06:50 - 01 Nov 2014 06:55 #52639 by PCW
At a technical note here, the hostmot2 firmware can reset on index but that function is not used by
the hotsmot2 driver, the latch-on-index function is used instead. The driver simulates clear on index via an offset

(This is necessary because clearing the hardware counter on index would break velocity estimation)

I actually think the driver should always enable latch on index and do the rest of the index logic
in software (the latched count can be valuable as a encoder sanity check if always available)

I think its also arguable that low level (servo) positions should be separate from machine positions
so that no low level position is ever cleared (right now there are a number of ugly work-arounds for index related steps in position)
Last edit: 01 Nov 2014 06:55 by PCW.

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

More
01 Nov 2014 19:02 #52650 by akb1212
On the homing.
I understand you have a problem with index on the linear scales not being at the end of travel. That is one of the downsides of using inexpensive gear not particularly made for your use. Many of them come with an index pulse at the mid travel point only, don't they?

On my mill homing is only possible with index on the linear scales though.... the only hardware switches in there are the hard limit switches. These physically switches off the enable signal going to the servo drives. So it's not possible for me to use these when homing. There is an override switch in the cabinet to bypass these switches in case I trip them. But there is no way to use them as part of homing.
This is why it is a showstopper for me if homing to index doesn't work with dual encoders. Installing extra hardware switches in there will involve a lot of work, and if it's not absolutely needed I would prefer not to. I do have several switch blocks normally used for this lying around. It's just not possible to install them on 2 of the 3 axes. No room to replace the single switch block with a 3 of 4 way switch (which I already have several of).

But I don't understand why it's impossible to exclude the index pulse of the rotary encoder from being used.... In my case I don't even need them. So for me it would be a possibility to not connect them in the first place..... That way it would not be a problem to use all index pulses for each axis as a reference to homing. The only index pulse the controller ever will see is the one from the linear scales, which is the one I want it to use.

Is there a situation where I will ever need the index pulse of the rotary encoders for my system? I can't think of any situation where I need it. Even if I convert one of more of my axes to torque mode I can't think of situations where this index is needed. At least not is needed in a way I can't use the index from the linear scales.

If anyone know a situation I will definitely need the index pulses from the rotary encoders please tell me now. If not I will not connect them.
I don't think it's a good idea to take the index pulse from the linear scales and feed that to the index input of the rotary encoder inputs. Or is it? It could be done as an alternative....

I'm fortunate enough to have high end Heidenhain 20 ua p/p scales with index on each side. That way I'm able to set my machine up to home in the most convenient position no matter how I configure my machine.
I can even increase the resolution on my scales by replacing the standard analogue to digital interpolator unit (also known as EXE boxes) with one with higher interpolation factor. For now I have two EXE boxes with higher interpolation rate lying on the bench waiting to be installed. These are available quite cheap on eBay. I think this will increase the resolution with a factor of 5, giving me a resolution of 0.0002 mm/pulse instead of the present 0.001 mm/pulse.

There is backlash in my system now, and increasing resolution will in a way increase that. I actually found it a lot harder (or in fact impossible) to tune the system with this increased resolution when trying to use a different controller. This was single PID loop only.
But with a dual PID loop system I expect this to be solved. Or I hope the dual loop system is able to use the increased resolution to an advantage instead of it being a problem as it was with single PID loop system.

I agree it's a good idea to get local help like you do on that Dutch forum DaBit:-) I would do the same if I had the opportunity. It's also evident you do get good advice there! The only downside is that us others who would very much like to see what you were talking about aren't able to understand what you are saying. From looking through it there is in fact loads of things you discuss in that long thread I find very interesting! So it's too bad about google translate not being able to understand Dutch sentence building rules then..... as it is now it's more or less completely unreadable, unfortunately. It's translating word for word, but what comes out is more or less completely gibberish.......

BTW, a wiki is obviously the place to put the detailed info on this. If someone can start it I can contribute when I see the need (and feel confident I know enough to contribute).

I will go through each of the constants in detail, and possibly poke in your comments on them to get better understanding when it's something I don't get. I appreciate you are willing to comment and provide insight to us other users in this. It's very valuable!

I agree it's possibly best if I build a complete HAl file and configuration myself from scratch. But the thing is that Other systems are able to make dual PID loop systems as part of the standard package. So I think it's a good idea to make a standard template for it available. After all there are not so many of the LinuxCNC users that have a degree in control technique. And to be honest that is what is needed of you are to make one yourself with no help.
For now it will probably be only people with a more than basic understanding of it that will know enough to understand the benefit of using it. And the skills needed to tune a dual PID loop is probably also higher than most users have.
But the increased capabilities of a system like this is a clear advantage. And it can be an important factor in making LinuxCNC the best choice!

One of the obvious uses for dual PID loop systems is to compensate for backlash, This is a link to a tutorial video made by the manufacturer of the other controller I have explaining the advantages of using dual PID loop to compensate for mechanical backlash: www.galil.com/learn/online-videos/dual-l...compensation-methods.

Unfortunately you have to register as a user to access it (so I didn't include a direct link). That is straight forward, and there is no approval time of delay when registering. But you will have to provide a valid email as normal on sites like this.
But the video is quite informative, and it explains all the thinking behind dual loop and why it works. So it's recommended watching for everybody interested in dual loop systems. He is also giving examples on the possible improvements possible on systems with backlash. And it's quite evident it's possible to get a real benefit if your system have backlash.

I've seen discussions elsewhere (don't remember where) that the benefit of dual loop is lower on a highly stable and tight system. But I guess that isn't an issue for most of us since we can't afford high end machines with little or no wear.....
So to me this way of overcoming mechanical inaccuracies and non ideal solutions due to low budget in an elegant and effective way. And the cost of the involved hardware is decreasing so fast it's no longer a major issue. Decent rotary encoders are quite cheap now, and used industrial grade ones with very good data can be had for next to nothing. Input cards to read them are also very cheap now.

There is a trend towards going for lesser demands on accuracy in the mechanical parts. And then instead compensate for this in electronics and controllers. This is a very good example of this. And it will contribute in to making better and more accurate machines available to users with lower budgets.

Anders

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

More
01 Nov 2014 20:28 #52654 by DaBit

At a technical note here, the hostmot2 firmware can reset on index but that function is not used by
the hotsmot2 driver, the latch-on-index function is used instead. The driver simulates clear on index via an offset


Can the position of an index pulse be found using latch-polarity/latch-enable/count-latched/position-latched pins? Or only through a workaround using rawcounts for example?
(I didn't do my homework BTW, other than finding out that these pins are not documented in the manpage)

I think its also arguable that low level (servo) positions should be separate from machine positions
so that no low level position is ever cleared (right now there are a number of ugly work-arounds for index related steps in position)


I fully agree. Everything has to now that a reset occurred, including the PID controllers etc.
LinuxCNC can do this offset thing perfectly well by the way; at homing it sets the motor offset.

It would be even better to take the referencing logic out of the LinuxCNC core and make it a separete HAL component. If it suits you use it, if it doesn't replace with custom component, ClassicLadder program, whatever. It would also make the use of absolute encoders easier. But that's another topic.

On the homing.
I understand you have a problem with index on the linear scales not being at the end of travel. That is one of the downsides of using inexpensive gear not particularly made for your use. Many of them come with an index pulse at the mid travel point only, don't they?


Mine produce an index pulse every 100mm. The pulse itself is available on the Mesa encoder component BTW, but capturing that pulse in software is close to impossible. It lasts only 1 micrometer.

I am indeed using fairly cheap components. My mill is for hobby only so i have to keep the cost in 'hobby range' otherwise the household CEO makes me sleep on the couch.
So far I am succeeding well in keeping cost low while maintaining accuracy and speed.

On my mill homing is only possible with index on the linear scales though....


LinuxCNC hardly imposes any limits, so it is not impossible. I just didn't spent enough effort to make it work yet. That is a matter of priorities; until now using the index pulses proved to be not trivial and the proximity sensors are fairly accurate so I am better off doing more urgent things first.

The only index pulse the controller ever will see is the one from the linear scales, which is the one I want it to use.


Yes, and that resets the encoder position which causes a deviation between scale and rotary encoder positions and a lot of trouble.
It's not impossible to account for that. The 'rawcounts' pin is not reset, btw. It is just some work.

I don't think it's a good idea to take the index pulse from the linear scales and feed that to the index input of the rotary encoder inputs. Or is it? It could be done as an alternative....


I did that as a quick test, without much luck. Again, I didn't dive deeply into it.

But with a dual PID loop system I expect this to be solved. Or I hope the dual loop system is able to use the increased resolution to an advantage instead of it being a problem as it was with single PID loop system.


Scale feedback + lost motion = trouble.
Get rid of that backlash. It doesn't only cause trouble with the controller, but also with milling itself.

The only downside is that us others who would very much like to see what you were talking about aren't able to understand what you are saying. From looking through it there is in fact loads of things you discuss in that long thread I find very interesting!


It is. I am an electronics engineer, not a mechanical engineer, and I started that thread when I was as green as grass.
That part of engineering is pretty new to me. But since I can read datasheets and understand math, I can figure things out, and that thread answers a lot of questions someone else might have.

So it's too bad about google translate not being able to understand Dutch sentence building rules then..... as it is now it's more or less completely unreadable, unfortunately. It's translating word for word, but what comes out is more or less completely gibberish.......


I can answer specific questions, but a complete translation is not going to happen. My English is not good enough for that anyway :)

I agree it's possibly best if I build a complete HAl file and configuration myself from scratch. But the thing is that Other systems are able to make dual PID loop systems as part of the standard package.


With LinuxCNC you basically get a box filled with Lego blocks, and you use that to construct your system. That is exactly the very best part of the system.
Having a couple of standard 'building instructions' to build something with those lego blocks is a good thing, but for more complex situations such as machines with a toolchanger, nontrivial kinematics, special servo needs, etc. you really have to study and understand otherwise you will keep on chasing gremlins.

So I think it's a good idea to make a standard template for it available. After all there are not so many of the LinuxCNC users that have a degree in control technique. And to be honest that is what is needed of you are to make one yourself with no help.


It would be possible to create a sample configuration just like all the others you get when you install LinuxCNC.

For now it will probably be only people with a more than basic understanding of it that will know enough to understand the benefit of using it. And the skills needed to tune a dual PID loop is probably also higher than most users have.


I tuned using trial and error, just like you would tune a single PID. Not difficult at all, even easier. But a little 'howto' would help of course.

One of the obvious uses for dual PID loop systems is to compensate for backlash, This is a link to a tutorial video made by the manufacturer of the other controller I have explaining the advantages of using dual PID loop to compensate for mechanical backlash: www.galil.com/learn/online-videos/dual-l...compensation-methods.


I will watch that video later, but the idea of compensating for backlash makes me shudder. If I can choose only one thing that is totally undesirable in a CNC machine it would be lost motion and especially backlash. You can compensate a gazillion of mechanical issues in software, but lost motion is not one of them. Yes, in a stationary situation you can. But not when the teeth of an endmill are chewing through a block of material. It is dangerous when climb milling, and when interpolating a circle there is a finite time needed to do the compensation and during that time the joints are not in sync.

backlash is A Very Bad Thing.

I've seen discussions elsewhere (don't remember where) that the benefit of dual loop is lower on a highly stable and tight system. But I guess that isn't an issue for most of us since we can't afford high end machines with little or no wear.....


Use fat temperature-stabilised C3-class (or better) ballscrews, preloaded nuts, high quality bearing blocks equipped with P4A (or better) bearings, put the machine in a conditioned space, and linear scales do not add much benefits unless they are of a very high resolution.

But one of such a linear drive system would cost more than my entire machine does (still below EUR 3000 and the spindle+VFD took about half of that amount), so I chose lower quality and pre-used parts and more hard work for the electronics. Seems to work out well.
The following user(s) said Thank You: Todd Zuercher

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

More
01 Nov 2014 20:56 #52660 by andypugh

If anyone know a situation I will definitely need the index pulses from the rotary encoders please tell me now. If not I will not connect them.
I don't think it's a good idea to take the index pulse from the linear scales and feed that to the index input of the rotary encoder inputs. Or is it? It could be done as an alternative....


If the motors are brushless and you are using software commutation and you want to use the encoder index as the commutation reference rather than a Hall-signal transition, then it might be useful.
It only costs a wire anyway. The index pin of the encoder isn't available for any other use if you are using hardware counters.

To use the mid-travel index for homing to you could use a long strip of metal and a prox sensor which tells the system which side of the index it, is. That becomes the home switch. If it is on the strip it backs off slowly looking for an index, if it is off the strip it rapids towards the strip until it finds it, then backs off slowly looking for an index. (the strip needs to stop just short of the index). Prox sensors are very cheap from eBay, I recently bought half a dozen just to have them in stock. An example is www.ebay.co.uk/itm/LJ8A3-1-Z-BX-1mm-Tubu...-300mA-/190836678225 There are cheaper ones but those are unshielded, the ones that have the screwed body all the way to the sensing end are shielded and much easier to work with.
I have been tending to bury them in the machine slides where they can sense a shallow hole drilled in the mating part. This wouldn't work for your mid-position index as you need a long target.

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

More
03 Nov 2014 23:42 #52722 by andypugh
Just out of interestm has anyone experimented with:
www.linuxcnc.org/docs/html/man/man9/at_pid.9.html

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

More
04 Nov 2014 00:06 #52724 by DaBit
I have seen it, and noticed that it uses Ziegler-Nichols to determine coefficients. I am not a fan of Ziegler-Nichols to setup motor control coefficients; they often turn out to be quite agressive, and then you still have to 'cram in' the feedforwards.

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

More
04 Nov 2014 00:22 #52726 by andypugh

I have seen it, and noticed that it uses Ziegler-Nichols to determine coefficients. I am not a fan of Ziegler-Nichols to setup motor control coefficients; they often turn out to be quite agressive, and then you still have to 'cram in' the feedforwards.


I was more curious about whether it works at all, really.

ZN aims for fastest settling with 1/4 period overshoot, and that is probably not what you want on a machine tool either.
Still it might be useful for people starting absolutely from scratch.

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

More
04 Nov 2014 00:44 #52729 by DaBit
It does work. Tried it once when I was using LinuxCNC (well, halrun actually) as a simple temperature controller for an experiment (using a Microchip TC77 sensor and SSR on the parallel port). Took some fiddling with number of cycles and tune effort though, and I didn't actually check whether the PID coefficients were really good; it did the job and that was all I cared about during that 'had to be finished yesterday' rush job.

If I need a bit of play time I'll try it on my X axis just for fun and see what it does.

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

Time to create page: 0.189 seconds
Powered by Kunena Forum