About a week ago, I was toying around with the idea of running our autonomous code in another task. I quickly had the thread itself up and running, and looked up synchronization in VxWorks, so as to properly control our own motion code from the task, resolving to a Mutex Semaphore. When it compiled and ran without instantly dying, i was elated.
I set about adding in some simple drive code, intending for the robot to move forward for a second, rotate, then move forward again. Simple enough, right? Well, not really as it turns out! When you’re using CANJaguars, there’s always something to trip you up, or so it seems. On her maiden voyage, Serenity (My Team’s Ultimate Ascent robot) lurched to life, and things seemed to work. So i disabled Serenity, dragged her back to the starting position, and enabled into Autonomous again. To my dismay, nothing happened. The Autonomous Task did indeed start, and the printfs were accurately timed, but no movement. (Despite synchronization being wrapped around every possible CAN message.)
For about three days, i tried to figure it out, each attempt yielding the same sketchy it-works-about-one-tenth-of-the-time result. Then, it struck me! What if the CANJaguar class is Task-initialization sensitive? (As in, you have to control it from the same task-context you’re going to use it in)
I moved the initialization code of our CANJaguar objects to the Autonomous Task main routine, just before drive code, and VOILA! It worked. SO, from what I can tell, You can only (consistently) use CANJaguars from the task you initialized the object in. As a result, i present to you, the CANJaguarServer class. It’s a handy little bit of code that runs a command loop for controlling CANJaguars, as well as offering nice things like CANBus bandwidth limiting and brown-out detection.
It’s currently in my team’s 2014 Test Code Repository. The relevant code is in the CANJagServer directory, and a usage example with our MecanumDrive class is shown in RobotMainTask.cpp. (There’s also plenty of other stuff you can ignore/peruse to your liking in there.)
The easiest way to use the CANJaguarServer is through the AsynchCANJaguar class, which inherits from SpeedController for ease of use.
EDIT: I’m finding plenty of bugs as i go, so if you’re using it please try updating to the current version before sending me a bug! Thanks. I’ll try to only push functioning commits once i have a robot to test them on.