Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   C/C++ (http://www.chiefdelphi.com/forums/forumdisplay.php?f=183)
-   -   Consistent Encoder RPM Issues (http://www.chiefdelphi.com/forums/showthread.php?t=115699)

meltbox360 01-04-2013 23:37

Consistent Encoder RPM Issues
 
Hi all. I am trying to figure out how to get encoders to read consistent values for speed. We have 250 count encoder (e4p) on there and using getRate() they read correctly at low RPMs but once it starts hitting 6000 rpm then we start seeing variations of around 15 revolutions per second. These are mounted on a mini cim. I don't really know what to do at this point. I have tried varying them from k4X to k1X with no real difference. My other thought was doing some kind of

reset
wait
get elapsed ticks
get elapsed time
calculate rpms

as I am under the impression that the variation could be due to the miniscule time frame between ticks that WPIlib uses to calculate the rate? I couldn't figure out how to spawn a new task to do this is and I do not want to block my code. Essentially I have run out of experience and I couldn't find much in the way of code examples or a clear solution to my problem.

So here is my goal:
Get a clean rpm reading useable in PID or other algorithm to ramp up a frisbee shooter to the desired speed.

My problem:
Highly variable readings at higher wheel speeds.

Thanks,
Team 4302

Tom Bottiglieri 01-04-2013 23:41

Re: Consistent Encoder RPM Issues
 
Use a lower CPR encoder. We were running into resolution issues with the timer once the square wave's period got extremely small. Less ticks = bigger period = more resolution.

We get fairly good results with a retro reflective optical sensor pointed at a piece of tape on the shooter wheel. We got terrible results with a 32 CPR encoder. We are calculating RPM with Counter::getPeriod().

meltbox360 01-04-2013 23:48

Re: Consistent Encoder RPM Issues
 
So the problem is that the Crio is randomly dropping ticks or is it that the timer is trying to measure immensely small time periods and failing to do so accurately?

Tom Bottiglieri 01-04-2013 23:50

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by meltbox360 (Post 1255975)
So the problem is that the Crio is randomly dropping ticks or is it that the timer is trying to measure immensely small time periods and failing to do so accurately?

The second one. Once the period of the ticks gets sufficiently small, you may only be able to measure in buckets of 5-10% of your RPM.

meltbox360 01-04-2013 23:55

Re: Consistent Encoder RPM Issues
 
Well that is encouraging. In that case is there a way to start another thread as I have not been able to with startTask. Function pointers in classes are beyond me as of right now which made it impossible for me to use startTask properly. I then wanted to use

(tickGet() * 1000) / sysClkRateGet())

To calculate time however "tickLib.h" doesn't want to compile either.

Ideally I do not want to impact responsiveness. I do not think we will be able to modify to a different encoder at this point. If you think it is worth switching encoders could you link to the one you have purchased. I am not familiar with retro-reflective encoders. Thanks.

EDIT: The idea is to create another thread, sleep in it for some time, then measure the rpm. That way I should allow the other thread to run while getting reasonably accurate speed. I think this is correct.

Ether 02-04-2013 00:01

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by meltbox360 (Post 1255966)
Hi all. I am trying to figure out how to get encoders to read consistent values for speed. We have 250 count encoder (e4p) on there and using getRate() they read correctly at low RPMs but once it starts hitting 6000 rpm then we start seeing variations of around 15 revolutions per second. These are mounted on a mini cim. I don't really know what to do at this point. I have tried varying them from k4X to k1X with no real difference.

A 250 count encoder should work if you set it up properly.

- Physically disconnect Channel B. Don't use it. Use Channel A only

- Create an up/down Counter object (not encoder) on the Channel A signal, and set it to count rising edges only

- Set the FPGA sample ring buffer to 125 samples1.

- Use Counter getPeriod() method. RPM = 60/(250*getPeriod())


Can you provide some more detail about your shooter design?

- what motor controller(s) are you using?

- what motor(s) are you using?

- how are those motor(s) connected to the wheel(s)?

- where and how is your encoder mounted?

Depending on the answers, you may be able to use the very simple bang-bang speed controller algorithm.


1if you don't know what this means, ask



meltbox360 02-04-2013 00:10

Re: Consistent Encoder RPM Issues
 
Oh oh. It is wired to use channel B. I will disconnect that then and try as you say. The encoders are mounted on a shaft extension coming out of a cim in one case and a mini cim in another. The wheels are on this same shaft. It is supported at two points. The encoder is right over the end of the shaft extension. I saw mention of bang-bang but never really delved too much into it as the readings were a little iffy.

So essentially wheels, encoder, motor all spin same speed. The encoder is mounted with screws and sits on the end of the shaft. We are using Victor 888 speed controllers.

I will post back shortly with results.

EDIT: Is it really necessary to disconnect the B channel or can it remain plugged in some arbitrary spot? The ground and power are wired to separate wires unfortunately so unplugging it entirely is not really an option without modifying the wires.

EDIT 2: I do not know how to set the FPGA sample ring buffer. I think that in order to set the rest up I need to make the counter and do the following

SetUpSource([channel A]);
SetUpSourceEdge(true, false);

Except then I don't know what channel I drop in when I am making the instance of the Counter class. Also channel A?

Ether 02-04-2013 00:14

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by meltbox360 (Post 1256001)
The encoders are mounted on a shaft extension coming out of a cim in one case and a mini cim in another. The wheels are on this same shaft. The encoder is mounted with screws and sits on the end of the shaft.

Could you post a picture? I'm concerned about vibration.



Ether 02-04-2013 00:17

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by meltbox360 (Post 1256001)
EDIT: Is it really necessary to disconnect the B channel or can it remain plugged in some arbitrary spot? The ground and power are wired to separate wires unfortunately so unplugging it entirely is not really an option without modifying the wires.

Can you post a simple hand-drawn sketch? I'm not sure I follow you.



Ether 02-04-2013 00:18

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by meltbox360 (Post 1256001)
I will post back shortly with results.

What programming language are you using?



meltbox360 02-04-2013 00:30

Re: Consistent Encoder RPM Issues
 
2 Attachment(s)
I am using c++

Here are the pictures.

Ether 02-04-2013 00:31

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by meltbox360 (Post 1256016)
Here are the pictures.


Does your camera have a macro setting?



meltbox360 02-04-2013 00:36

Re: Consistent Encoder RPM Issues
 
1 Attachment(s)
Using my phone. First time was me being too quick.

Ether 02-04-2013 00:36

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by meltbox360 (Post 1256016)
I am using c++

Since you didn't ask, I assume you already know what this means and how to do it:

Quote:

Originally Posted by Ether (Post 1255992)
- Set the FPGA sample ring buffer to 125 samples1.

1if you don't know what this means, ask



meltbox360 02-04-2013 00:38

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by Ether (Post 1256020)
Since you didn't ask, I assume you already know what this means and how to do it:





I asked in a second edit earlier. Not sure at all. Sorry I checked the docs and then I realized I have no idea how to do this stuff correctly without some experimentation.

Ether 02-04-2013 00:39

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by meltbox360 (Post 1256016)
Here are the pictures.

I see what you mean about the wiring.

Encoder mounting looks better than I imagined.



Ether 02-04-2013 00:42

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by meltbox360 (Post 1256023)
I asked in a second edit earlier. Not sure at all. Sorry I checked the docs and then I realized I have no idea how to do this stuff correctly without some experimentation.

I don't have any C++ examples.

This link might help:

http://firstforge.wpi.edu/sf/go/artf...v=1&_pagenum=1



meltbox360 02-04-2013 00:53

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by Ether (Post 1256028)
I don't have any C++ examples.

This link might help:

http://firstforge.wpi.edu/sf/go/artf...v=1&_pagenum=1



I may not be understanding but do i have to recompile WPIlib to change that? Thanks.

meltbox360 02-04-2013 01:02

Re: Consistent Encoder RPM Issues
 
Without recompiling, just setting everything up I am getting a spread of 1100 rpm at max speed. Between 5200 and 6300 rpm so the same issue as the encoder class with pretty much the same spread. I am unsure of how to handle the FPGA but I will keep digging around. Thanks to everyone who has helped out so far. You guys showed up quick!

Ether 02-04-2013 01:04

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by meltbox360 (Post 1256036)
do i have to recompile WPIlib to change that?

You have to recompile the parts you change, I guess. I've not done this with C++. Do you have a guru you could ask?



Ether 02-04-2013 01:08

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by meltbox360 (Post 1256040)
Without recompiling, just setting everything up I am getting a spread of 1100 rpm at max speed. Between 5200 and 6300 rpm so the same issue as the encoder class with pretty much the same spread.

I think setting the FPGA sample ring buffer will bring that down to an acceptable level without introducing undue phase lag. If you can get a good signal you may be able to use the very simple bang-bang control.



meltbox360 02-04-2013 01:08

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by Ether (Post 1256041)
You have to recompile the parts you change, I guess. I've not done this with C++. Do you have a guru you could ask?



I do not at this moment but yes if I am to change the C++ I will have to recompile. Lets see how difficult this is. I'll post back as soon as I figure something out. I'm sure there's at least a semblance of a guide on compiling it. The link you posted is immensely helpful. The changes will be simple.

Ether 02-04-2013 01:11

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by meltbox360 (Post 1256043)
I'll post back as soon as I figure something out.

I may be gone shortly, it's past 1am here.



meltbox360 02-04-2013 01:11

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by Ether (Post 1256045)
I may be gone shortly, it's past 1am here.



Not a problem. Check back tomorrow if you could. Appreciate the help. :)

Ether 02-04-2013 11:49

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by meltbox360 (Post 1256046)
Not a problem. Check back tomorrow if you could. Appreciate the help. :)

I'm here. How's it going?



Tom Bottiglieri 02-04-2013 12:28

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by Ether (Post 1256028)
I don't have any C++ examples.

This link might help:

http://firstforge.wpi.edu/sf/go/artf...v=1&_pagenum=1



Cool trick, I wasn't aware we could poke the FPGA in that manner. This should work for the OP, but a "slower" sensor shouldn't do anything but help.

Ether 02-04-2013 12:44

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by Tom Bottiglieri (Post 1256175)
This should work for the OP, but a "slower" sensor shouldn't do anything but help.

Indeed. At frisbee shooter wheel speeds, many teams have had excellent results with one-count-per-rev sensors (optical and magnetic). One-count-per-rev sensors don't require changing the FPGA sample ring buffer default size.



Kevin Sevcik 02-04-2013 15:28

Re: Consistent Encoder RPM Issues
 
If you're having issues recompiling WPILib, you can do this more simply by grabbing copies of Counter.cpp and Counter.h and renaming the files and class from "Counter" to something like "AvgCounter". Then add them to your workspace and make a code change similar to the java one in the FirstForge link. In fact, I'd recommend doing it this way since it's a lot simpler than recompiling WPILib. It's what I did when I wanted a modified version of the PIDController and the PIDSubsystem classes.

Tom Line 02-04-2013 16:42

Re: Consistent Encoder RPM Issues
 
We saw the same problem in LabView last year (you'll find many threads about it). The getrate (or period) only calculates between the last 2 ticks. So if you have many many ticks between loops, it actually hurts you because the time used between the ticks is very small, and creates a large amount of error. The benefit of using the counter is that you can set it to average a certain number of results to minimize the error.

If you can't follow what others are saying, there is a quick and dirty way that we used in LabView.

Each time your code loops, take the total number of counts from each loop and divide it by the total amount of time between loops.

You'll get some inaccuracies, but it should give you all the accuracy you really need for a frisbee firing PID loop. They're not nearly as sensitive to speed as the basketballs were last year. We're using this method on our first shooter wheel (only because we already had it wired up and didn't want to swap sensors) and have had acceptable results.

We're using 341's method of the 2011 photosensor and reflective material that results in 1 count per RPM. The resolution that we see on that wheel is superior to the first method.

Ether 02-04-2013 17:05

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by Tom Line (Post 1256316)
Each time your code loops, take the total number of counts from each loop and divide it by the total amount of time between loops.

Just a heads-up. The above method has some issues of its own to be aware of:

1) the answer is only as good as the method you use to get (or control) the elapsed time

2) any task swaps or lengthy interrupts which occur between reading the counts and getting the elapsed time will create signal spikes.

3) the faster you run your code, the more RPM jitter you get due to count quantization (for example, at 10ms and 6000 RPM with a 250 counter, the jitter would be ~24 RPM)

4) the slower you run your code, the more phase lag you get in the sensor signal (for example, at 20ms there'd be ~10ms lag)



meltbox360 02-04-2013 17:47

Re: Consistent Encoder RPM Issues
 
I'm back. About to get to testing the code but I recompiled WPILib with the Java code diffs you gave me translated to C++

I will post back as soon as I have a result. I'll also post up what I changed if it works.

Ether 02-04-2013 17:51

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by meltbox360 (Post 1256348)
I recompiled WPILib...

See Kevin's recent post:

http://www.chiefdelphi.com/forums/sh...8&postcount=28



Kevin Sevcik 02-04-2013 17:54

Re: Consistent Encoder RPM Issues
 
To follow up on my post, the single best reason for pulling out a copy of Counter.cpp and Counter.h is so you can easily stay up to date with WPILib releases that don't affect the Counter class. If you're recompiling WPILib, then you'll have to re-modify it and recompile it every time there's a new release.

meltbox360 02-04-2013 18:23

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by Kevin Sevcik (Post 1256356)
To follow up on my post, the single best reason for pulling out a copy of Counter.cpp and Counter.h is so you can easily stay up to date with WPILib releases that don't affect the Counter class. If you're recompiling WPILib, then you'll have to re-modify it and recompile it every time there's a new release.

I was not aware that was possible. Thanks. You would however have to be careful to track any changes in files you pull out to ensure you have the latest version of those files. For example pulling out networkTables I think would have resulted in you not getting some of the updates in the latest release. It unfortunately works two ways.

If you make sure to manage it then pulling out the files id likely the better solution.

meltbox360 02-04-2013 18:30

Re: Consistent Encoder RPM Issues
 
Wonderful it is fixed. I am seeing jitters of around 30 rpm now. This is absolutely wonderful. Should I go and try to smooth it further before attempting bang-bang or should I dive into that now. Thanks for the help couldn't have done it without you guys!

EDIT: My error is about .5% right now which I believe is good enough.

Ether 02-04-2013 18:39

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by meltbox360 (Post 1256379)
Should I go and try to smooth it further before attempting bang-bang

Do not filter the signal going to bang-bang. Bang-bang does not like phase lag.

If you haven't seen it already, you might want to peruse this paper.

If bang-bang doesn't work for you, try Take Back Half.





meltbox360 02-04-2013 18:46

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by Ether (Post 1256384)
Do not filter the signal going to bang-bang. Bang-bang does not like phase lag.

If you haven't seen it already, you might want to peruse this paper.

If bang-bang doesn't work for you, try Take Back Half.





Thank you. I will post back when I have results along with the modified WPILib source files.

meltbox360 02-04-2013 19:30

Re: Consistent Encoder RPM Issues
 
Looks like a simple way to do it however I am wondering if anyone knows of a simple way in vxWorks of starting a thread that does some task every some miliseconds. iterativeRobot is a little late to switch to at the moment (I think). I know platforms like QNX can do this with timers. Perhaps it is not necessary but it is nice to ensure consistent performance.

Tanaythan 03-04-2013 02:10

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by meltbox360 (Post 1256413)
Looks like a simple way to do it however I am wondering if anyone knows of a simple way in vxWorks of starting a thread that does some task every some miliseconds. iterativeRobot is a little late to switch to at the moment (I think). I know platforms like QNX can do this with timers. Perhaps it is not necessary but it is nice to ensure consistent performance.

There is a notifier class in wpilib that you can use. It spawns a new thread every few milliseconds. To reference the code it is used in the pidcontroller class.

DjScribbles 03-04-2013 12:55

Re: Consistent Encoder RPM Issues
 
In my bang-bang controller, I used a task (specifically jankyTask, courtesy of Bob.Wolff in this thread: http://www.chiefdelphi.com/forums/sh...ght=Tasks+in+C)

I setup the SetTargetRPM of our shooter, to use the RPM to compute a target_period, and in the task I read the period from the counter class, and compare it to the computed target period, if the period is above target set the motor to 100%, if the target is below I set 0%. I only call motor.Set if the motor command has changed from the previous run (since the set carries a good bit of overhead).

In addition, I've added some code akin to the take-back-half suggested by Ether. When we trigger our shot, I disable the bang-bang control and set a constant 50% power for a short time; this addition seemed to help our shot consistency, but it's a bit of a hack :)

Edit: I can provide source code if you like, but I didn't want to spoil the fun

nightpool 05-04-2013 12:58

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by Ether (Post 1256187)
Indeed. At frisbee shooter wheel speeds, many teams have had excellent results with one-count-per-rev sensors (optical and magnetic). One-count-per-rev sensors don't require changing the FPGA sample ring buffer default size.



Indeed. Our team dodged a bullet this year as our physical shooter design made it impossible to put a traditional encoder on and we had to figure out an alternative earlier in the season. It turned out to be very easy to use a normal Rockwell photoeye and a piece of white tape to measure shooter speed. The only biggish change we had to make was our own subclass of Counter to make it work with the WPILib PID controller, but that was pretty trivial, just like 15 lines of code.

The one thing to watch out for is the size of your flag (the tape or what have you). Too small and you might not see it as it flashes past. We had good results with about 30 degrees of coverage.

Ether 05-04-2013 15:04

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by nightpool (Post 1257480)
The one thing to watch out for is the size of your flag (the tape or what have you). Too small and you might not see it as it flashes past. We had good results with about 30 degrees of coverage.

At what RPM?



nightpool 05-04-2013 15:05

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by Ether (Post 1257513)
At what RPM?



Around 3600. We're probably going to be replacing the 5:1 bb on our shooter with either a 4:1 or a mini-cim though, so I'll update you guys on how that works.

Ether 05-04-2013 15:11

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by nightpool (Post 1257515)
Around 3600.

That's about 1.3ms (with 30 degree coverage).

What's the response time of that Rockwell photosensor?



nightpool 05-04-2013 15:12

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by Ether (Post 1257518)
That's about 1.3ms (with 30 degree coverage).

What's the response time of that Rockwell photosensor?



About 1ms IIRC. This is mainly estimates though.

Ether 05-04-2013 15:17

Re: Consistent Encoder RPM Issues
 
Quote:

Originally Posted by nightpool (Post 1257521)
About 1ms IIRC. This is mainly estimates though.

You could paint half the wheel flat black and the other half glossy white, as some teams have done




All times are GMT -5. The time now is 12:42.

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