Encoder fixed in WPILib 2011?

Hi,

Our team is planning to use Encoders and PID for our robot this year. According to this thread, there was a bug in how the Encoder class worked last year. I have already looked through the Encoder.java source code from this year and it appears to have been changed from what was reported in the thread. I just wanted to confirm that Encoder.getRate() indeed has been fixed for this year.

Thanks!

We believe we have fixed it. Please let us know if you have any problems.

-Joe

We tried it saturday and had problems.

We had defined two encoders, one encoder would get both rate and distance properly, the second encoder would only get distance.

I’ll confirm with my team that we were using the newest encoder block.

wow. I had that EXACT SAME ISSUE, in LabVIEW. I switched one from 1x to 4x (so it uses an FPGA encoder instead of an FPGA Counter) and it worked, until I rebooted, and it happened again.

Can any of you try changing the averaging setting on the timer for the Counter or Encoder that you’re using (with the ConfigureTimer VI). I’d really like to know what effect if any that has.

Thanks,
-Joe

We had a similar issue yesterday in java. We have a “left” encoder and a “right” encoder and only the right encoder would get rate correctly. The left encoder would return NAN. After testing a few other possibilities, we feel that we’ve solved the problem by only using an “even” encoder. This probably won’t make sense without some pseudo code.

Encoder leftEncoder = new Encoder(args); //this will return NAN
leftEncoder = new Encoder(args); //this will return a good rate
Encoder rightEncoder = new Encoder(args); // returns NAN rate
rightEncoder = new Encoder(args); //this will return a good rate

So the reason why our right encoder was working before was because it was the second encoder we constructed…

Jhersh- Is there anything we can do to help you work/understand this issue?

Wonder if this code might work for you to cling onto hope you don’t need to have that pseudo code.

Encoder leftEncoder;
leftEncoder = new Encoder;
Encoder rightEncoder;
rightEncoder = new Encoder;

I think I understand you are saying you need to initialize the encoders twice for each one.

I’d describe just a little differently. I don’t think it has to do with the variable initialization. It is more like every other “new’ed” encoder’s getRate method doesn’t work right. So you have to new one and throw it away, to new the next one which will work. It is like something in the construction of one encoder has side effects that impact the construction of the next one.

Hmm, maybe it has something to do with the channels the encoders use and how they are programmed to be used? I kind of see it as you are making a “space” or else there will be a conflict like possibly of an address being taken by one encoder from another.

Unless, you are implying that it is a problem with the program to receive data.

I think I might be implying something along those lines. It seems like something might be going wrong in the lower level wpilibj or fpga software running on the crio. So I am just trying to do a mental dump of everything I have seen so one of our resident masters of the low level code might see a pattern in the behavior we are seeing that points at something in that code or gives them more questions to ask us so we can help get to the root of this “getRate returns NaN” thing

It you did not already open up the source code for the encoder inside of the WPIlib. That probably will help you. I will try and analyze possible areas that could be the problem before Monday. Will try testing the encoders then. Hopefully someone will be able to find the solution, though I would have confidence in a person that understands low level programming rather than me.

We encountered the same issue – I worked around it by simply differentiating myself.

While it was stopped, it returned 0.0. While moving, it returned NaN.

That’s an interesting pattern you’re seeing there. I’ll try to reproduce it tomorrow.

On thing you can tell me is if you think it’s related to the order in which they are constructed or the specific hardware that gets allocated. For instance, if you were to allocate one, delete it, then allocate it again, would it work? Or does it only work because the 2nd hardware resource is allocated due to the first one being in use?

Thanks,
-Joe

I’m not sure about the deletion. We aren’t doing anything to explicitly delete the first one we construct before constructing the next one, and it is probably unlikely the garbage collector runs between those two lines every time.

For your testing, all the encoders will look ok at rest, returning 0.0. It isn’t until they are pulsing that getRate starts to give NaN on the bad ones.

Also, the second encoder we construct works for us even if the digital IO ports are unrelated. We first noticed the pattern by doing the following with two completely separate encoders.

Encoder rightEncoder = new Encoder(rightArgs);
Encoder leftEncoder = new Encoder(leftArgs);

With the above code only the left encoder getRate worked. So we tried swapping the order of construction.

Encoder leftEncoder = new Encoder(leftArgs);
Encoder rightEncoder = new Encoder(rightArgs);

After doing the swap the right encoder getRate started working and the left’s started returning 0.0 or NaN. After that, we tried the double construction for each encoder, that I described in the first post, which gave us two encoders with working getRate’s!

I’ll have access to the code this evening so if there might be anything interesting about the specific args we use they can get posted then.

How did you create the first (dummy) encoder? Instantiating using the same arguments gives channel in use errors, no?

I wrote a (fairly quick) VI that takes A phase, B phase, and count scaler and outputs a working encoder. It creates the dummy using the same channels on slot 6, then creates the real one on slot 4. It assumes 1x decoding since that’s what we use.

I haven’t tested it heavily (still working on mechanism tuning, we haven’t tuned the drivetrain yet), so I am hesitant to post it here.

Quick answer:
Create one on slot 6 and one on slot 4. Since we don’t use slot 6, that solves all of our problems.

If you instantiate the DigitalInputs first, then pass those into the encoder constructors, you will not get the errors. The errors happen when the encoder tries to construct DigitalInputs for the same channels more than once.

By the way, I found that it is not always the second (odd) decoder that works.

See this thread.

In 4x mode, the 2 odd ones work. In 2x or 1x mode, the first 3 even ones work and the last one (odd) works.

-Joe

Joe,
We got it. It was encoders #1, 3, 5 and 8 that worked. Should have checked this thread before trial and error! This is so illogical, but good it is consistent.

We did have to use different distinct channels for all four dummy encoders. But that’s ok.

Is it possible to set the dummy to a slot besides 6 or 4 that are meant for the Digital Side Car? This year my team is using 2 digital side cars so it would be nice to set it to an unused slot.

You don’t need to use a different slot at all… read this post. Construct the DigitalInputs first.

-Joe