View Single Post
  #7   Spotlight this post!  
Unread 17-03-2010, 16:39
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 8,101
Ether has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond repute
Re: encoder for cam-driven kicker?

Quote:
Originally Posted by Chris Hibner View Post
If WPI and NI did things properly, it really doesn't matter if the FPGA counter overflows or not.

Let's assume they did things correctly. One possible implementation is that the FPGA services the encoder interrupts and keeps track of the counter in a signed 16-bit register. Then the WPI interface samples that register at a given time interval. The WPI code would be like the following:

Code:
// variable declarations
s16 encoderCnt = 0;
s16 encoderCntPrev;
s16 encoderDiff;
double encoderOut;

// ...

// in the loop

encoderCntPrev = encoderCnt;
encoderCnt = getFPGAencoderCnt();
encoderDiff = encoderCnt - encoderCntPrev;

encoderOut = encoderOut + encoderDiff*inchesPerCount;

// etc.
(by the way, s16 is a typdef'd variable type for a signed 16 bit integer variable. The actual declaration will depend on your micro)


With the above code, it does not matter if the FPGA encoder counter overflows. If you don't believe me, try the following code:

Code:
s16 counter1, counter2, counter3;

counter1 = 32765;
counter2 = counter1 + 5;

cout << "counter1 = " << counter1 << "\n";
cout << "counter2 = " << counter2 << "\n";

counter3 = counter2 - counter1;

cout << "counter3 = " << counter3 << "\n";
If you don't like C/C++, you can do the same thing in LabVIEW. You'll notice that the two's compliment math handles the wraparound flawlessly and counter3 will equal 5. With the subtraction, you'll never know an overflow occurred - and it doesn't really matter.

This is actually a very slick way of handling angles to avoid having to do a lot of wrap-around math and checking. If you always scale your angles such that 360 degrees is equal to the overflow point, the two's compliment math automatically takes care of all of the wrapping for you.
What you suggest will likely work for this non-critical application whose running time is less than three minutes.

However, for the benefit of those reading this thread who are just learning about realtime control, and who may go on to program other realtime applications, the following caveat should be pointed out:

The 2010 FRC LabVIEW framework is most definitely NOT hard-real-time. Using code running in cRIO to re-set the FPGA counter is not a robust solution if high accuracy is required and you do not want to introduce errors that may accumulate over time.

At the very least, the reading and re-setting of the FPGA counter should probably be protected by a critical section to minimize the occurrence of accumulated errors.


~
Reply With Quote