Joint vel-cmd for torque PID loop and linear encoder PID

16 Jul 2018 13:29 - 16 Jul 2018 13:29 #114299 by PCW
I would not expect D term to make sense in a velocity loop

The PIDs component command derivative calculation looks correct to me (of course FF1 in a velocity loop
is the rough equivalent of FF2 in a position loop)

So if the command is a velocity, FF1 is acceleration feed forward:


Which is what the PID component calculates

In a cascaded loop the velocity loop is typically P+I+FF1 (where FF1 is inertia dependent) and the position loop is just P and FF1
Last edit: 16 Jul 2018 13:29 by PCW.
17 Jul 2018 08:13 #114355 by Glite
Using D term I start to get noisy response like in image below

but adding only it to the velocity loop when tuning position loop helps to cancel out oscillations. Adding more D term in velocity loop makes motor whine.

I understand how derivatives are calculated, and what do they mean in each case. What I want to say that for the FF1 term command-deriv pin is not used at all. And it doesn't matter if command-deriv connected or not. FF1 and then FF2 calculation is done from the command pin. I don't know if this has to be like that. But there is a problem which I will describe below.

I also don't see any problems in code with derivative calculations, but it looks like some kind of error is present here. Because on last images you can clearly see that derivative calculated from the position command (velocity command) and velocity command from the TP are not the same. I can't see any other explanation, because the only thing that changes when you disconnect the command-deriv pin, is a command source for the D term to calculate the error. All FFs are using command pin to make calculations.
17 Jul 2018 12:44 #114373 by PCW
in your velocity loop, command derivative (the source for the FF1 term) should not be connected (or if it is connected it should be connected to the TPs commanded acceleration pin which is only available in LinuxCNC master)

Note that if you use the TPs derivatives they will be slightly different than the PIDs D/DT numbers because they will be delayed one servo thread cycle
17 Jul 2018 13:06 #114379 by Glite
What I want to say is that you can't change source for the FF1 in PID, look at the code again and you will see that, FF1 is always calculated from command.
*(pid->cmd_d) = (command - pid->prev_cmd) * periodrecip;
... *(pid->cmd_d) * *(pid->ff1gain)  ...

Servo delay may explain why I get constant following error during acceleration/decceleration when not using TPs commanded velocity for the position-torque loop. It was strange that it ceased to tune at all, I couldn't get rid of that.
17 Jul 2018 13:32 #114386 by PCW
Both the PID's feedback derivative and command derivative can be overridden by external inputs. that is they are calculated by D/DT if left unconnected
This appears to be done by some pointer magic:

pid.N.command-deriv float in
The derivative of the desired (commanded) value for the control
loop. If no signal is connected then the derivative will be
estimated numerically. float in
The derivative of the actual (feedback) value for the control
loop. If no signal is connected then the derivative will be
estimated numerically. When the feedback is from a quantized
position source (e.g., encoder feedback position), behavior of
the D term can be improved by using a better velocity estimate
here, such as the velocity output of encoder(9) or hostmot2(9).
17 Jul 2018 21:37 #114417 by Glite
Pointer magic is only working for the D term calculations, FF1 is still calculated from the command in any case.
17 Jul 2018 23:35 - 17 Jul 2018 23:36 #114437 by PCW
That's odd the code seems to be the same for both
So that looks like a bug with the PIDs command-deriv handling
Last edit: 17 Jul 2018 23:36 by PCW.
18 Jul 2018 05:37 #114446 by Glite
I reviewed the code not once and here what I saw:
On line 366-368 derivatives are calculated to dummy sigs:
if(!(pid->prev_ie && !*(pid->index_enable))) {
    *(pid->commandvds) = (command - pid->prev_cmd) * periodrecip;
    *(pid->feedbackvds) = (feedback - pid->prev_fb) * periodrecip;
On line 371 D term error is calculated:
*(pid->error_d) = *(pid->commandv) - *(pid->feedbackv);
Here where pointer magic comes to play, if command-deriv pin is not connected, pid->commandvds and pid->commandv have the same adress, and when you calculate the derivatives, in *(pid->commandv) you will have the same value as in *(pid->commandvds). If it's connected they won't have the same adress, and dummy sigs calculation will not make impact on value of *(pid->commandv).
But when it comes to calculate feed-forward derivatives instead of assigning the *(pid->commandv) value
if(!(pid->prev_ie && !*(pid->index_enable))) {
    // not falling edge of index_enable: the normal case
    *(pid->cmd_d) = (command - pid->prev_cmd) * periodrecip;
*(pid->cmd_d) is calculated again from the command. To really use the command-deriv pin for the feed-forward it should look like this:
*(pid->cmd_d) = *(pid->commandv);
18 Jul 2018 14:09 #114473 by PCW
Right, so it looks like when the index detect fixups were added to command-deriv the dummysig magic was left out
19 Dec 2018 03:26 - 19 Dec 2018 03:26 #122588 by Nitram
Just wondering if this has been fixed as yet?

On an interesting but slightly different note:
1. on setup, PnC config lists all the PID pins including pid.N.command-deriv, but never and
2. z-vel-fb gets connected to hm2..encoder..velocity, but the z-vel-fb signal does not connect to any other pins (and certainly not as it is not listed).

Also, is this why in some other threads there has been some advice to comment out the pid.N.command-deriv and simply let the default algorithm handle this given:

so it looks like when the index detect fixups were added to command-deriv the dummysig magic was left out

Last edit: 19 Dec 2018 03:26 by Nitram.
Time to create page: 0.102 seconds
Powered by Kunena Forum