![]() |
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 |
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(). |
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?
|
Re: Consistent Encoder RPM Issues
Quote:
|
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. |
Re: Consistent Encoder RPM Issues
Quote:
- 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 |
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? |
Re: Consistent Encoder RPM Issues
Quote:
|
Re: Consistent Encoder RPM Issues
Quote:
|
Re: Consistent Encoder RPM Issues
Quote:
|
Re: Consistent Encoder RPM Issues
2 Attachment(s)
I am using c++
Here are the pictures. |
Re: Consistent Encoder RPM Issues
Quote:
Does your camera have a macro setting? |
Re: Consistent Encoder RPM Issues
1 Attachment(s)
Using my phone. First time was me being too quick.
|
Re: Consistent Encoder RPM Issues
Quote:
Quote:
|
Re: Consistent Encoder RPM Issues
Quote:
|
Re: Consistent Encoder RPM Issues
Quote:
Encoder mounting looks better than I imagined. |
Re: Consistent Encoder RPM Issues
Quote:
This link might help: http://firstforge.wpi.edu/sf/go/artf...v=1&_pagenum=1 |
Re: Consistent Encoder RPM Issues
Quote:
|
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!
|
Re: Consistent Encoder RPM Issues
Quote:
|
Re: Consistent Encoder RPM Issues
Quote:
|
Re: Consistent Encoder RPM Issues
Quote:
|
Re: Consistent Encoder RPM Issues
Quote:
|
Re: Consistent Encoder RPM Issues
Quote:
|
Re: Consistent Encoder RPM Issues
Quote:
|
Re: Consistent Encoder RPM Issues
Quote:
|
Re: Consistent Encoder RPM Issues
Quote:
|
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.
|
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. |
Re: Consistent Encoder RPM Issues
Quote:
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) |
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. |
Re: Consistent Encoder RPM Issues
Quote:
http://www.chiefdelphi.com/forums/sh...8&postcount=28 |
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.
|
Re: Consistent Encoder RPM Issues
Quote:
If you make sure to manage it then pulling out the files id likely the better solution. |
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. |
Re: Consistent Encoder RPM Issues
Quote:
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. |
Re: Consistent Encoder RPM Issues
Quote:
|
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.
|
Re: Consistent Encoder RPM Issues
Quote:
|
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 |
Re: Consistent Encoder RPM Issues
Quote:
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. |
Re: Consistent Encoder RPM Issues
Quote:
|
Re: Consistent Encoder RPM Issues
Quote:
|
Re: Consistent Encoder RPM Issues
Quote:
What's the response time of that Rockwell photosensor? |
Re: Consistent Encoder RPM Issues
Quote:
|
Re: Consistent Encoder RPM Issues
Quote:
|
| 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