Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PID coeff in conversion for xl-320 #176

Open
jjehl opened this issue May 2, 2016 · 4 comments
Open

PID coeff in conversion for xl-320 #176

jjehl opened this issue May 2, 2016 · 4 comments

Comments

@jjehl
Copy link
Contributor

jjehl commented May 2, 2016

Maybe there is an explanation, but for me the coeff. for the PID gain is a little bit weird :

def dxl_to_pid(value, model):
    return (value[0] * 0.004,
            value[1] * 0.48828125,
            value[2] * 0.125)


def pid_to_dxl(value, model):
    truncate = lambda x: int(max(0, min(x, 254)))
    return [truncate(x * y) for x, y in zip(value, (250, 2.048, 8.0))]

Because PID are all beetween 0 and 254 means that when you set in pypot range of :
P (value[2]) is between 0 and 31,75
I (value[1]) is between 0 and 124,0234375
D (value[0]) is between 0 and 1,016

A good PID in pypot could be (8.0, 15.625, 0.064), I find this not really "readable"

@sonelu
Copy link
Contributor

sonelu commented Mar 27, 2017

There is an issue withe the treatment of the PID parameters. The "external" PID values are supposed to be passed in a list [P, I , D] -- at least that is the expectation. But after conversion the values are passed to the "internal" values and to the registers in the XL320 as D, I, P because this is the order in which the registers are listed in the motor.
If I look closely at the coefficients they are correct when the pid member is handled as a [D, I, P]. As long as you are aware of this the calls will be fine.
In other words a call like this:

m.pid = [4,2,0]

(that is quite often in the various robots initialisation code) will actually end up setting the registers as follows (for an XL320):

Reg 27(D): 4 x 250 = 1000 => 254 (will be truncated from 1000)
Reg 28(I): 2 x 2.048 = 4.096 => 4
Reg 29(P): 0 => 0

As you can see the result will be a very weak motor (P parameter is 0!) but also extremely unstable (D parameter is 254 which will make it very reactive to position errors). That is very different from the expected behaviour of a medium stiff motor (P = 4 x 8 = 32) and with 0 D coefficient that will make it less likely to oscillate. So the actual call would need to be:

m.pid = [0,2,4]

It's unfortunate that the member is called pid and the conversions pid_to_dxl and dxl_to_pid suggesting that that external format is PID.
I would suggest changing the way the values are converted as follows:

def dxl_to_pid(value, model):
    return (value[2] * 0.125,
            value[1] * 0.48828125,
            value[0] * 0.004)


def pid_to_dxl(value, model):
    truncate = lambda x: int(max(0, min(x, 254)))
    return [truncate(x * y) for x, y in zip(value, (250, 2.048, 8.0))].reverse

This way the calls to the PID members will be natural.

@pierre-rouanet
Copy link
Contributor

Good catch! Do not hesitate to submit a PR with the modification, we'll gladly integrate it.

@show0k
Copy link
Member

show0k commented Mar 31, 2017

Fixed in #238.

@show0k show0k closed this as completed Mar 31, 2017
@jjehl jjehl reopened this Apr 1, 2017
@jjehl
Copy link
Contributor Author

jjehl commented Apr 1, 2017

Coeff are always strange for me.

show0k pushed a commit to show0k/pypot that referenced this issue Apr 19, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants