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 02-09-2015 11:09 PM

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 02-09-2015 11:33 PM

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 02-09-2015 11:38 PM

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 02-10-2015 09:01 AM

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 02-10-2015 09:50 AM

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 02-10-2015 11:10 AM

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 02-10-2015 03:10 PM

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 02-10-2015 03:16 PM

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 02-10-2015 05:12 PM

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 02-10-2015 09:31 PM

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 02-11-2015 08:51 AM

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 02-11-2015 09:02 AM

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 02-11-2015 10:37 AM

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 02-11-2015 10:48 AM

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 02-11-2015 10:53 AM

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?




All times are GMT -5. The time now is 08:44 AM.

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