Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Java (http://www.chiefdelphi.com/forums/forumdisplay.php?f=184)
-   -   PID control help (http://www.chiefdelphi.com/forums/showthread.php?t=134276)

KosmicKhaos 09-02-2015 23:09

PID control help
 
So I'm a new programmer on my team and I'm not very familiar with PID loops/controls. We have two motors on our robot and were trying to run them both at the same speed. of course there will be some minor differences in speed but we're trying use a PID to keep them equal in case one gets off. We also have encoders on each motor. Any help appreciated thanks!

cstelter 09-02-2015 23:33

Re: PID control help
 
Quote:

Originally Posted by KosmicKhaos (Post 1441039)
So I'm a new programmer on my team and I'm not very familiar with PID loops/controls. We have two motors on our robot and were trying to run them both at the same speed. of course there will be some minor differences in speed but we're trying use a PID to keep them equal in case one gets off. We also have encoders on each motor. Any help appreciated thanks!

Do you need the position of each encoder to map, or just their rate? In other words, is it OK if one gets up to 100 clicks per second a little ahead of the other and then the two even out to 100 clicks a second? Or do you want the distance on each encoder to be as identical as possible?

KosmicKhaos 09-02-2015 23:38

Re: PID control help
 
Quote:

Originally Posted by cstelter (Post 1441050)
Do you need the position of each encoder to map, or just their rate? In other words, is it OK if one gets up to 100 clicks per second a little ahead of the other and then the two even out to 100 clicks a second? Or do you want the distance on each encoder to be as identical as possible?

We are trying to have each motor at the same speed and if the encoder notices that the speeds aren't the same we would like for the slower one to speed up or the faster one slow down so the speeds are equal. We were thinking that the motors start at the same speed but after a little while of running the speeds my get off, if they do we want to make them equal again. The loop essentially keeps the motors the same speed These motors are controlled by the driver and both with one button.

cstelter 10-02-2015 09:01

Re: PID control help
 
Quote:

Originally Posted by KosmicKhaos (Post 1441053)
We are trying to have each motor at the same speed and if the encoder notices that the speeds aren't the same we would like for the slower one to speed up or the faster one slow down so the speeds are equal. We were thinking that the motors start at the same speed but after a little while of running the speeds my get off, if they do we want to make them equal again. The loop essentially keeps the motors the same speed These motors are controlled by the driver and both with one button.

Then I would recommend you run each motor/pid as a separate subsystem. You can make each a PIDSubsystem that will automatically set things up with functions for usePIDOutput and returnPIDInput. But the enabling/disabling of PIDSubsystems has been observed to be a bit odd (the pids run when disabled it seems, causing i to build up).

Alternatively you can use two PIDCommands which will also then have methods onthem for usePIDOutput and returnPIDInput. You can set those to access return values from the subsystems. (i.e. usePIDOutput in one command sets the motor on one subsystem and returnPIDInput in that same command returns the encoder rate on that same subsystem.

However you do it, you end up with a PIDController object (either managed by the PIDSubsystem super class or by the PIDCommand super Class).

Once the PIDControllers are tuned (if the mechanisms are largely similar, they will likely have the same PID vaues), you can call setSetPoint() on the PIDController/PIDSubsystem and when they are enabled, they will drive at a particular rate. Each will function independent of the other, but both will rely on the respective encoder to maintain the rate.

Note, there are two approaches for usePIDOutput for a rate PID. One is to treat it like a positional PID in which case as you approach your set rate, you try to apply 0V, which of course will actually be trying to slow down your motor, rather than drive it at a constant value. Also in the application of something like a shooter where the motor may be spinning very fast as opposed to a very geared-down application, if the rate gets a bit large, you may try to apply negative voltage to a motor with a very strong forward momentum.

The other approach iirc is to change usePIDOutput to maintain a last value sent and add/decrease that last value sent by the output. If you search CD you can find some good articles and all the math behind them to support
something along the lines of

Code:

class PIDCommand {

double m_output;
...
public void usePIDOutput(double output)  {
    m_output += output;
    motor.set(m_output)
}

I'm going off memory for the above, but you can still tune PID, but now as you arrive at your setpoint, you just send the accumulated value for m_output.

I'll be honest, we use encoder/talon pairs for our drive train this year and did so all last season. Last year we originally used positional and the discovered the rate formulation mid-season. We tried it, but either we implemented it poorly or didn't take enough time to properly tune it, but it did not seem to behave as nicely for us as the original positional formulation.

I think the rate formulation is more correct, but I can only say that the positional formulation got our team through an entire season with no observable problems, though after driving 10 minutes or more our cims did get quite hot. That was more due though to poor cooling-- when the cims were exposed to air on the practice chassis it was not a problem, but when they were somewhat enclosed by electrical above and a pan below, they would get hot. I suspect a rate formulation may have helped with this.

But regardless of how you do this-- PIDController, PIDSubsystem, rate formulation or positional formulation, the concept is the same. Drive each motor based on feedback from its respective encoder to adjust the motor speed. You will find that each independently will then maintain the same rate. We did find that some small tweaks to DistancePerPulse might be necessary to tune the two encoders to one another, but even without such adjustments the rates will be relatively equal-- much better than otherwise.

Ether 10-02-2015 09:50

Re: PID control help
 
Quote:

Originally Posted by KosmicKhaos (Post 1441053)
We are trying to have each motor at the same speed and if the encoder notices that the speeds aren't the same we would like for the slower one to speed up or the faster one slow down so the speeds are equal. We were thinking that the motors start at the same speed but after a little while of running the speeds my get off, if they do we want to make them equal again. The loop essentially keeps the motors the same speed These motors are controlled by the driver and both with one button.

You didn't answer cstelter's question: Do you want the positions of the two actuators to be synchronized also? This would be the case if your application is, for example, two independent linear actuators lifting an elevator.



cstelter 10-02-2015 11:10

Re: PID control help
 
Quote:

Originally Posted by Ether (Post 1441186)
You didn't answer cstelter's question: Do you want the positions of the two actuators to be synchronized also? This would be the case if your application is, for example, two independent linear actuators lifting an elevator.



Fair point-- I took the reply to mean the *only* concern was rate and not position, but it is not entirely clear that the question was properly answered. My reply is only relevant (or at best only half relevant) if one does not care about position. If one is trying to keep two forks at the same height, position is critical, not just rate.

Ether 10-02-2015 15:10

Re: PID control help
 
Quote:

Originally Posted by KosmicKhaos (Post 1441039)
So I'm a new programmer on my team and I'm not very familiar with PID loops/controls. We have two motors on our robot and were trying to run them both at the same speed. of course there will be some minor differences in speed but we're trying use a PID to keep them equal in case one gets off. We also have encoders on each motor. Any help appreciated thanks!

What motor controllers are you using? CAN bus or PWM? Are the encoders wired to the RIO or the encoders?



Ether 10-02-2015 15:16

Re: PID control help
 


@ CD control gurus:

Assuming it is desired to synchronize position (both the steady-state position and while the actuators are moving), what control method(s) would you recommend
a) if the driver is issuing a position command, and

b) if the driver is issuing a speed command


MrRoboSteve 10-02-2015 17:12

Re: PID control help
 
You'll need to make sure that the commanded rate doesn't drive one of the motors to 100% power.

It's common to have one drive be slightly more efficient than the other, and the slower one can't catch up.

cstelter 10-02-2015 21:31

Re: PID control help
 
Quote:

Originally Posted by Ether (Post 1441346)


@ CD control gurus:

Assuming it is desired to synchronize position (both the steady-state position and while the actuators are moving), what control method(s) would you recommend
a) if the driver is issuing a position command, and

b) if the driver is issuing a speed command


I wouldn't claim to be a guru (far from it), but I can share our experience last year. We wrote a 'drive straight' algorithm for tank drive. I believe we drove the left side only at a requested rate. The left side set the right side power to the same as the current side was using. It then compared positions and put in a proportionally slower speed to the amount of error on the leading side. It seemed to work-- it went as straight as we could calibrate the distance on the encoders. At a set point though I would think each on an independent pid would work well.. our drive straight did poorly when we tried to stop at a distance... in retrospect, thinking through it in light of this conversation, I think once we were within some distance of a position point, we should have released the master/slave relationship and let each one arrive at the correct distance to their own devices.

Year before we tried to drive 2 mechanisms completely in sync on PIDs (had very low tolerance for getting out of sync. But the code was climbing the robot and the pid could not react quickly enough if force on one side increased. In the end they fused the right/left together mechanically and it was much easier to code. So when in doubt, a hardware fix may be the best option.

Looking forward to hearing what the gurus suggest.

cstelter 11-02-2015 08:51

Re: PID control help
 
After reflecting on the code from last year a bit, I'm thinking the same thing could have been accomplished (more simply) simply by writing a PID command along the lines if

Code:

public void returnPIDValue()
{
    return leftEncoder.getDistance()-rightEncoder.getDistance();
}

public void returnPIDOutput(double output)
{
    driveTrain.tankDrive(baseSpeed+output, baseSpeed-output);
}

the setpoint of the PID would always be zero (a zero difference between left and right distance).

Our code did something similar, but not entirely identical.

Thoughts?

notmattlythgoe 11-02-2015 09:02

Re: PID control help
 
Quote:

Originally Posted by cstelter (Post 1441704)
After reflecting on the code from last year a bit, I'm thinking the same thing could have been accomplished (more simply) simply by writing a PID command along the lines if

Code:

public void returnPIDValue()
{
    return leftEncoder.getDistance()-rightEncoder.getDistance();
}

public void returnPIDOutput(double output)
{
    driveTrain.tankDrive(baseSpeed+output, baseSpeed-output);
}

the setpoint of the PID would always be zero (a zero difference between left and right distance).

Our code did something similar, but not entirely identical.

Thoughts?

The same thing can also be accomplished by doing something like this:

Code:

public void returnPIDValue()
{
    return leftEncoder.getDistance()-rightEncoder.getDistance();
}

public void returnPIDOutput(double output)
{
    driveTrain.arcadeDrive(baseSpeed, output);
}

The original question that never got answered needs answered to really give a good answer for the best way to do this.

Ether 11-02-2015 10:37

Re: PID control help
 
1 Attachment(s)
Quote:

Originally Posted by Ether (Post 1441346)
@ CD control gurus:

Assuming it is desired to synchronize position (both the steady-state position and while the actuators are moving), what control method(s) would you recommend
a) if the driver is issuing a position command, and

b) if the driver is issuing a speed command

For case (a), would something like this work? Is there a better way?



notmattlythgoe 11-02-2015 10:48

Re: PID control help
 
Quote:

Originally Posted by Ether (Post 1441749)
For case (a), would something like this work? Is there a better way?



Ether, could you explain in layman's terms what that means?

Ether 11-02-2015 10:53

Re: PID control help
 
Quote:

Originally Posted by notmattlythgoe (Post 1441754)
Ether, could you explain in layman's terms what that means?

Please don't take this the wrong way, but I need to know before answering: did you see the attachment?



notmattlythgoe 11-02-2015 11:31

Re: PID control help
 
Quote:

Originally Posted by Ether (Post 1441756)
Please don't take this the wrong way, but I need to know before answering: did you see the attachment?



Yes.

Ether 11-02-2015 11:58

Re: PID control help
 

Motor1 is controlled by a PID whose setpoint is the driver's position command and whose process variable is position feedback from encoder1. The output of this PID is limited to 90% to allow for motor tolerances as suggested by Steve in post#9.

Motor2 is controlled by a closed-loop controller whose output is the sum of two terms:
1) the output from an Integral controller whose setpoint is encoder1 position and whose process variable is encoder2 position, and

2) the output from a Proportional controller whose setpoint is the driver's position command and whose process variable is encoder2 position


notmattlythgoe 11-02-2015 12:26

Re: PID control help
 
Quote:

Originally Posted by Ether (Post 1441801)

Motor1 is controlled by a PID whose setpoint is the driver's position command and whose process variable is position feedback from encoder1. The output of this PID is limited to 90% to allow for motor tolerances as suggested by Steve in post#9.

Motor2 is controlled by a closed-loop controller whose output is the sum of two terms:
1) the output from an Integral controller whose setpoint is encoder1 position and whose process variable is encoder2 position, and

2) the output from a Proportional controller whose setpoint is the driver's position command and whose process variable is encoder2 position


Would this be better or more efficient than having your motor1, and a motor2 that just uses a positional PID controller and the setpoint is always the position of motor1?

Ether 11-02-2015 13:02

Re: PID control help
 
1 Attachment(s)
Quote:

Originally Posted by notmattlythgoe (Post 1441816)
Would this be better or more efficient than having your motor1, and a motor2 that just uses a positional PID controller and the setpoint is always the position of motor1?

...and the process variable for Motor2 is encoder2 position, like this?

The problem I see with that is the transient response to large step changes in driver position command. Motor1 responds immediately to the large change, but Motor2's controller must wait for the error to form between encoder1 & encoder2. Granted, you could crank the P gain way up for Motor2, but it's not immediately clear how well that would work in practice.




gpetilli 11-02-2015 13:06

Re: PID control help
 
Quote:

Originally Posted by notmattlythgoe (Post 1441816)
Would this be better or more efficient than having your motor1, and a motor2 that just uses a positional PID controller and the setpoint is always the position of motor1?

Yes. If motor2 is only a slave to motor1, then motor2 will not move until a sufficient error in position has occurred (due to a change in command to motor1).

What Ether suggested is basically to send the same command to both motors simultaneously, and use the Integrated error between the positions to fine tune motor2. The Integrated error has high DC gain but slow "step response".

The settled response for both systems should be similar, but the match while changing position should be much better with Ether's system.

notmattlythgoe 11-02-2015 13:07

Re: PID control help
 
Quote:

Originally Posted by Ether (Post 1441840)
...and the process variable for Motor2 is encoder2 position, like this?

The problem I see with that is the transient response to large step changes in driver position command. Motor1 responds immediately to the large change, but Motor2's controller must wait for the error to form between encoder1 & encoder2. Granted, you could crank the P gain way up for Motor2, but it's not immediately clear how well that would work in practice.




Yes like that.

Yeah, that could definitely cause some problems. Depending on the system you might be able to tune it to react correctly, but it could difficult. The more you limit the speed of motor1 the better the system would react I'd imagine.

The more I think about it, the more I like your original proposal. I wish I had a system I could try it out on.

cstelter 11-02-2015 13:09

Re: PID control help
 
Quote:

Originally Posted by Ether (Post 1441749)
For case (a), would something like this work? Is there a better way?



I'll play :-).

Would this work? I don't know.

Is there a better way? I don't know.

This seems to be taking me back to one or two courses I had in college regarding stability and Laplace transforms I think-- but I'm not sure about that. That work was all based on electrical circuits, but I think the math translates to any system of differential equations. Either that or I'm way off in the weeds. I've had no need to revisit that part of my education in the past 25 years, so it's not just rusty, it's frozen/locked up.

The part I find curious is using different error terms for P and I on the 'slave' motor. I have absolutely no idea what effect that might have, nor how to solve for it. Thus proving my inability to claim any guru status whatsoever. But I am finding the discussion fascinating, so I really appreciate it.

Intuitively it seems it could work, but whether or not in practice the system could keep up with it, or if another formulation would be more effective, I don't know.

notmattlythgoe 11-02-2015 13:12

Re: PID control help
 
Quote:

Originally Posted by cstelter (Post 1441849)
I'll play :-).

Would this work? I don't know.

Is there a better way? I don't know.

This seems to be taking me back to one or two courses I had in college regarding stability and Laplace transforms I think-- but I'm not sure about that. That work was all based on electrical circuits, but I think the math translates to any system of differential equations. Either that or I'm way off in the weeds. I've had no need to revisit that part of my education in the past 25 years, so it's not just rusty, it's frozen/locked up.

The part I find curious is using different error terms for P and I on the 'slave' motor. I have absolutely no idea what effect that might have, nor how to solve for it. Thus proving my inability to claim any guru status whatsoever. But I am finding the discussion fascinating, so I really appreciate it.

Intuitively it seems it could work, but whether or not in practice the system could keep up with it, or if another formulation would be more effective, I don't know.

I'd imagine your P values would be very similar if not identical. The I value would definitely be different. I'd imagine you'd need a larger I value on motor2 to react fast enough to the differences in distance.

notmattlythgoe 11-02-2015 13:16

Re: PID control help
 
One thing we decided to do differently this year was control our autonomous drivetrain distances by using a speed controlled PID with a P controller setting the setpoint based on the distance to target. We've had some major success with it so far.

What if you used identical speed controlled PID loops and used the I controller from Ether's proposal to adjust the setpoint of motor 2?

gpetilli 11-02-2015 13:19

Re: PID control help
 
Quote:

Originally Posted by cstelter (Post 1441849)
I'll play :-).

Would this work? I don't know.

Is there a better way? I don't know.

This seems to be taking me back to one or two courses I had in college regarding stability and Laplace transforms I think-- but I'm not sure about that. That work was all based on electrical circuits, but I think the math translates to any system of differential equations. Either that or I'm way off in the weeds. I've had no need to revisit that part of my education in the past 25 years, so it's not just rusty, it's frozen/locked up.

The part I find curious is using different error terms for P and I on the 'slave' motor. I have absolutely no idea what effect that might have, nor how to solve for it. Thus proving my inability to claim any guru status whatsoever. But I am finding the discussion fascinating, so I really appreciate it.

Intuitively it seems it could work, but whether or not in practice the system could keep up with it, or if another formulation would be more effective, I don't know.

This is a bit more complicated than even most college courses (although the concepts are all there). Most courses only deal with one system of equations at a time, not two slaved systems. Don't feel bad about being lost in the weeds.

Basically any servo control loop "attenuates" the error. Three things about this statement -
1) it needs error to work
2) the error is never zero
3) far better reduce the systematic error before entering the loop

By sending the same command to both motors simultaneously, you reduce the error before it even develops. The servo has less work to do, is easier to tune and responds faster.

Ether 18-02-2015 22:22

Re: PID control help
 
1 Attachment(s)
Quote:

Originally Posted by Ether (Post 1441749)
For case (a), would something like this work? Is there a better way?

This might be a better way. Hat tip to Jared Russell at this thread.




All times are GMT -5. The time now is 11:15.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi