I wasn’t going to post this until later, but the insane CPU usage I’ve seen this season has prompted me to release this now. I’ll do a more formal write up of this in a few days.
Basically, we found ourselves with robot code running near 97% all the time, and it was really messing with our timing. I looked through some of the deep internals of LabVIEW, and found that it’s actually quite inefficient in VI scheduling (assuming RT is the same; the documentation did not indicate any differences between LV desktop and LV RT) - In a nutshell, LabVIEW is running a tasking system for each VI, and queuing VI’s to run and such.
There are ways to improve efficiency (for example, simple VI’s can be set to Subroutine mode which optimizes the call, or you can optimize it further by setting re-entrant VI’s to be inlined into calling VI’s at compile time). Since you can’t use Subroutine priority for any call that causes the VI to be taken off of the execution queue because it locks the thread, you can’t contain any asynchronous statements (FPGA write, Wait, loops, etc.).
In my experience with the WPI library, I found that some specific systems were horribly unoptimized, requiring as many as 11 VI calls (in addition to the high-level call which the user sees) to set a motor. Times 10 motors, that’s over 120 VI executions every 20ms to handle the acts of scaling a decimal to U8 and passing it to the FPGA. The Motor library was the worst, as the MotorControl library passed data down into the PWM library which passed data down into the FPGA-PWM library, and every action contained a VI who’s only purpose was to change the dev ref bundle to match the lower level library’s bundle type.
I optimized the WPI Motor Set to remove all unnecessary VI calls, and inlined all of the scaling math into the top-level VI. In the process, I removed all of the CAN code, as we don’t use CAN. The new VI only has two VI calls. I did the same with the Analog Read and Servo Set VI’s, but the gains are marginal for those compared to the Motor Set VI.
The big picture: With the modifications of this VI, we saved approx. 25% CPU load. With the Analog and Servo (not posted), we saved an additional 6% CPU. All numbers were taken with temporarily running code, with the same VI front panels open, using the RT Get System CPU Loads VI called every 1000ms and displaying the information to the front panel.
This VI is a drop-in replacement for WPI Set Motor for all teams using PWM. No CAN support exists or is planned. Use at your own risk; we ran this at Kettering without issue.
SimpleSetMotor.vi (33.4 KB)
SimpleSetMotor.vi (33.4 KB)