PDA

View Full Version : PID Velocity Control


j.cole
02-15-2012, 02:12 PM
Should this code work to get the velocity of the motor using an encoder. (See pictures they should explain better than I could). Plug that number into the process variable and see if it works. I'm going to increase the refresh rate to get a more accurate reading.

Ether
02-15-2012, 02:57 PM
Should this code work to get the velocity of the motor using an encoder. (See pictures they should explain better than I could). Plug that number into the process variable and see if it works. I'm going to increase the refresh rate to get a more accurate reading.

Does the "50" in Capture1.PNG mean 50 milliseconds? If so you are copying CurrentRotations into PreviousRotations every 50ms, which is 0.05 seconds not 0.5 seconds (as stated in Capture.PNG).

Can't you just use a feedback node to compare CurrentRotations to the previous value?

EricVanWyk
02-15-2012, 03:20 PM
Try to avoid global variables whenever possible, especially in LabVIEW.

In this case, they severely chop up your data flow, which makes it hard to see exactly what your order of operations is. As written, you do not guarantee the order or timing of when Cur. Rotations and Prev Rotations are read going in to the RPM calculation - You may end up with them being grabbed such that Cur is read too soon or too late, so your output can bobble between zero, expected, and multiples of expected. It could even go negative if you were attempting to update faster and you had a lot of other stuff going on.

Also, it looks like your while loop grabs the value from Cur Rotations once at the start of the owning VI, and then writes that same value to Prev Rotations every 50 milliseconds. Is this the intended behavior?

As Ether said, a feedback node or a shift register is likely what you are looking for here.

RufflesRidge
02-15-2012, 03:44 PM
The Encoder Get VI has a Rate output at the bottom that takes care of quite a bit of that for you. The output is in pulses per second so you will have to scale appropriately if you want RPM.

j.cole
02-15-2012, 03:47 PM
The intended operation is to get the RPM of the motor. Now what I expected to happen was that every half a second the program would take the current value and write it to the previous value. And then take the previous value and subtract it from the current value. Giving me my total rotations for that half second.
I've never used shift registers because I have no understanding of them at all and it was easier to do it a different way than learn something, which I should have done in the first place. 5 weeks in is a little bit late eh?

j.cole
02-15-2012, 03:54 PM
The Encoder Get VI has a Rate output at the bottom that takes care of quite a bit of that for you. The output is in pulses per second so you will have to scale appropriately if you want RPM.

Wow its good that I didn't see that before and waste a few hours trying to figure this out.

So it gives me the rate of the encoder perfectly?

RufflesRidge
02-15-2012, 04:15 PM
Wow its good that I didn't see that before and waste a few hours trying to figure this out.

So it gives me the rate of the encoder perfectly?

Yes, you can look inside the Encoder Get VI to see (kind of) how this works. The help for the VI (what I checked before posting the first time) says that it is in pulses per second, put that does not appear to be correct based on looking at the internals and usage/comments in some previous team code.

The rate returned is actually Distance Per Count (set when opening) * Pulses/sec. So if you are just using rate for this encoder and not distance you can set your distance per count such that the rate returns in RPM.

To do this take Revs/min = the formula I wrote above and solve for the Distance Per Count term.

EricVanWyk
02-15-2012, 04:20 PM
The intended operation is to get the RPM of the motor. Now what I expected to happen was that every half a second the program would take the current value and write it to the previous value. And then take the previous value and subtract it from the current value. Giving me my total rotations for that half second.

For future reference, most of the things on the robot operate somewhere in the 5 to 20 millisecond region. The next time you need to pick an amount of time to wait between calculations, start in this range. Much faster, and the motor controllers can't update as quickly as you are asking them to. Much slower, and things begin to lag or jerk.


I've never used shift registers because I have no understanding of them at all and it was easier to do it a different way than learn something, which I should have done in the first place. 5 weeks in is a little bit late eh?

We've all been there: the hardest part of learning a new language is vocabulary.

You might be interested in http://www.frcmastery.com/ - They have some great videos specific to LabVIEW for FRC.

Ether
02-15-2012, 04:54 PM
The Encoder Get VI has a Rate output at the bottom that takes care of quite a bit of that for you. The output is in pulses per second so you will have to scale appropriately if you want RPM.

For very high RPMs (such as a shooter wheel) you might be better off reading counts every 20ms and then scaling delta_counts to RPM.

http://www.chiefdelphi.com/forums/showpost.php?p=1115596&postcount=19

j.cole
02-15-2012, 05:29 PM
For very high RPMs (such as a shooter wheel) you might be better off reading counts every 20ms and then scaling delta_counts to RPM.

http://www.chiefdelphi.com/forums/showpost.php?p=1115596&postcount=19




I see what thats for because I'm doing some testing right now and the encoder rate is really jumpy. My lead adviser mentioned he saw someone else posting the same issue so I'm gonna look for that form and test this out to see if it works. Thanks for all your help so far guys.
I looked up shift registers by the way and I understand the concepts now.

Ether
02-15-2012, 05:54 PM
I see what thats for because I'm doing some testing right now and the encoder rate is really jumpy.

Yup. Try delta_counts and you should see a much less noisy signal. Did you see the little drawing I attached to the previous post? It shows a feedback node.

j.cole
02-15-2012, 06:00 PM
Didn't work. I tested it at 1/4 voltage and the value I was getting from the encoder was jumping from 2.6 max to 1.8 min. Is there any way to average that number and stay in the middle? I've been our programmer for 3 years but I'm new to advanced programming techniques.

j.cole
02-15-2012, 06:34 PM
Alright I think I found the problem. I changed the Decoding Rate in the begin from 4x to 2x. That dropped the variation from +-.5 to +-.05 . I'm going to try 1x now and see what it looks like.

Ether
02-15-2012, 07:08 PM
Didn't work.

What "didn't work" ?? There's no context available for disambiguation.

j.cole
02-16-2012, 01:17 PM
Doing the delta counts didn't fix the problem which was the jumpyness of the encoder values at a constant voltage. I think that properly tuned I could negate the effects of that variation.

Ether
02-16-2012, 01:31 PM
Doing the delta counts didn't fix the problem which was the jumpyness of the encoder values at a constant voltage.

At what encoder speed (RPM) were you seeing jumpyness of the encoder values using the delta_counts method?

j.cole
02-17-2012, 10:55 AM
(I just took the delta counts so I'd say it's RPS not RPM) But I tried everywhere between .5 RPS and 5 RPS and the variance is still the same. I want to say it has something to do with the rate TeleOp runs but I don't know.

Ether
02-17-2012, 11:07 AM
(I just took the delta counts so I'd say it's RPS not RPM) But I tried everywhere between .5 RPS and 5 RPS and the variance is still the same. I want to say it has something to do with the rate TeleOp runs but I don't know.

If there's excessive jitter in TeleOp, try dividing delta_counts by the actual elapsed time instead of the assumed 20ms.

Is this for a shooter wheel or something else?