How do you combine different motors in pid control?

Excuse me again,everyone

I was tuning my pid constants these days,but i found smoe questions which i want to ask for advice.

I had tried many times,and there’re two graphs that i was satisfied with.

I’m not sure which kind is better,one has small oscillations while the other dosen’t.

In the graphs,the encoder didn’t exactly reached 300.I have a small tolerance for about 10.What’s your acceptable tolerance when using encoder?

Another thing is that my pid controller includes 2 encoders for each side(one is green and the other is blue in the graph).I thought might to use diffierent pid constants for each side.But when tuning,i found it’s easy to influence the other side when i only changed the constant of one side.The robot turned to twist and seems really strange.Like the following graphs.

Any advice for tuning different pid constants for different motors?These constants are so easily to influence each other and the whole seems strange.

What is breaking my heart is that when I only made the kp=1,the robot behaves accurate enough,even the tolerance is smaller than afterwards.

Well,if i couldn’t find a good enough constant,this would be a good choice.

On the second graph, the ‘D’ might be high, I am not sure. I personally don’t like much oscillation. If a PID controller is used for driving, I suggest little or no ‘I’. If a PID controller is used for line following, using ‘I’ is probably a good idea.
Here is a good reference for PID controllers (it was made for FLL students using the Lego NXT, but it is very applicable to vex. Unfortunately the article is for line following, not driving.)

Consistency is what you want. If you get a PID controller that consistently goes 12 ticks over the target and a PID controller that goes -5 to 5 ticks of the target, which is better? The consistent 12 over, in my opinion. When watching your robot execute a routine over and over, you can see when it is consistent. You can not see how objectively close it is to the target.

Also, I would think that 10 ticks away is pretty good, but others might not settle for 5 ticks…

I don’t suggest using different values for each side.
The reason one affects the other might be because if the left side goes farther, the right encoder moves a tiny bit.

Well,if i couldn’t find a good enough constant,this would be a good choice.

In a different thread:

It seems that a team from the #2 alliance in the world had the same thoughts on the kp. :stuck_out_tongue:

EDIT: Saw this post in the “Favorite Autonomous Routines” thread:

Checking if the error has been in the tolerance for a certain amount of time, would probably work, and be quite effective. I personally just program the robot to set a timer when the error is within a certain amount, and I don’t check the error at all after that. Then when the time is up, the robot moves on to it’s next move.

I was using the Ziegler–Nichols method to deduce the constants.Maybe i made some miscalculations because of the oscillation period.Although kd is obviously too high, the graph is still good enough.That’s why i was struggle with these 2 different kinds of graph.

Because the motors are different,their speed is also quite different in same pwm.As a result,the difference between two sides is nearly to 10 IME counts.But using different constants,the difference in the end is certainly decreased,but the process seems twisting.It mightt because I didn’t find good enough constants.I will keep working.But the tolerance above the state error is small enough,so I’ll just try.

Yep,that might be the most acceptable method.By now i was still tuning my constants,when it cames to transplant the controller to the program,I will try this method.

Thanks,JoeTPR. I had read your code,that’s really awesome.I was using easyc before,your code helped me a lot to switch to robotc.I have a small question on using the pid control with line followers to reposition.If the lights change,the value of different line followers would change a different extant.Will this affect the reposition lightly?Still thaks for replying me!

What is your sample rate (how long is the wait in the loop)? That might throw off the period slightly since you can not detect the actual period of time below that sample rate threshold. The second graph you posted is pretty close to what you want but may not work consistently for other values.

In your code, what is your max integral value set to? Do you let the integral continue to grow? That may be why your derivative value is so high.

These are also pretty small distances if it’s the IME going to 300 counts. Your tuned PID for the small distance may not seem so tuned for longer distances as momentum will try and carry your robot more or if your integral is not capped it will continue to grow out of control. So you may want to set a target for a larger IME count.

To see how it works even further, did you log the resultant values of the contribution of the proportional, integral, and derivative values? (for instance Kp* error that is being added to get the motor power for the proportional part, Ki * integral for the integral part and the Kd * derivative for the D part). You may see that the effects of the integral are contributing too much to the drive even very close to the target. Setting a maximum intergral value can assist with this. The integral contribution maxing out at 25% - 35% of motor power is a general guideline. Otherwise you are probably going to see overshoot.

When kp=1 and the rest 0 your are 400-500 milliseconds slower to your target than the tuned PID. That is the real advantage of PID over proportional. It not only gets you to your target but it also gets you there faster.

Is this on an arm or a robot drive? Does not matter just interested.

I wait for 10ms per loop. In contrast to pid control,I think my ki= normal_ki*delta_time,and kd=normal_kd/delta_time,so i recalculated when using Ziegler–Nichols method.And what i’m not sure is the oscillation period.Is it the time of a complete oscillation? But in the graph there ins’t a complete oscillation.And i thought the period is decreasing.Or is it the time until the robot stopped?I’m not sure about this.

I started to count integral when the error is below the threshold,and reset to 0 when the error=0.We used quite different ways to limit integral values.

I’m still thinking about reducing tolerance.What I’m thinking is to decrease the integral threshold and increase ki.I’m really curious about your tolerance,because I’m not sure when I should be satisfied with my controller.

Arcade.It’a pity when I attend the Worlds I didn’t have time to try pid controller,I’m not very satisfied with my program at Worlds.Hope i can achieve my target.Thanks!

I tried to decrease the tolerance by increase ki,but it seems to take twice as much time to finish.

Before it only takes 0.6s to finish,althrough the tolerance is high,but now I had to wait 1.1s to finish turning.It’s too slow.It doesn’t worth waiting,I think.

10ms is sometimes a bit hard for the debugger stream to keep up with and the motors are not really responding well below 20ms. But if you can do it great! The smaller the more accurate you will see the peaks in oscillation.

To get the critical oscillation point used in Ziegler Nichols method of tuning, you need to keep increasing the P until it does not decay any more - it just keeps thrashing about never reaching the goal. Your robot will look pretty spastic doing this and it can break things so please be careful.

The period is measured peak to peak. Looking at the debug in excel you can pick it out when the values stop going up or down and then look at the time.

Setting the integral to zero when you cross the 0 threshold is sometimes not the way to go. I know others do it this way, but try limiting the overall integral contribution to be 30-50 and see how you like that.

By wiping out the integral, the calculations suddenly start over once you cross over the error line. If the integral was having a big effect on the drive value, you now threw it a curve and a step change in reaction happens versus a smooth one. Look at the debug stream and see the sudden difference the motor value is once you cross 0 error (the target value).

Oh,I see.Well,I’m quite surprised that my curve seems pretty although I made terrible mistakes.Thanks,I’ll try it as soon as possible.

I’ll try it as well.What I was thinkng is that if you don’t clear integral when you reached the target,maybe it will still have a strong enough power to force overshooting,and produce oscillation.So I wanted to both clear the integral and limit its range.

Not sure if this is right or not, but I think the derivative takes away from the integral contribution and the proportional is going to 0 anyway. So the D counteractinng I helps you “quickly glide” (if that is even a proper term) into the target value as P goes to 0.

The resultant left over I in a lifting arm I think helps with the arm’s hold strength. On the forward movement for a drive it’s not as helpful as you really don’t want any power left over. But it all works out in the end and you can make some minor tuning even after the base Zeigler Nichols variables.

Have fun. And try for some further IME targets so you are at full speed going in.

I have thought about it before.But my problem is that in the end the derivate extend to 0.So the derivate’s influence is getting smaller and smaller.Well,as I don’t have enough time to continue trying,I’ll think about it later.I mostly use the integral to zoom very small error,so it doesn’t much affect the complete routine.

Well,i am also thinking about line calibration.What i was using before is to go forward,detecting which side met the white line,and made that side keep still,only move the other side until the line follower detected the line as well.But ist’s really not accurate enough,especially when the needed degree is very small.Any advice for line calibration?I’m so embarrassed for asking so many questions.I really want to increase my programming skills.Thanks a lot!

You have nothing to be embarrassed about, your questions indicate that you have already progressed far beyond a lot of veteran teams. Keep asking and you will continue to learn.

Thank you! I will keep learning~