CANbus Jaguar control

We are finding several problems with CANbus control. There is no adequate documentation for the WPI lib code - this is a major failing on the part of FIRST.


  1. We used set(), setX(), and then get() and the get() results drift from what we have set! espaecially pronounced if we vary the set() values. Immediately after a set() or setX() the get() value is the same, but a few ms later it will drift quite significantly ~+/-0.1-0.3.
  2. After a while (~10-100ms) the get() value goes to 0.0. We tried to use
    CANjaguar.setExpiration() but that didn’t do anything - following the source code it appears WPlib does not even use this parameter nor the
    DEFAULT_SAFETY_EXPIRATION that is supposedly set at 0.1.
  3. It seems that each call to CANbus takes ~10ms so our (very small) code that updates the motors grinds to a crawl, which we think is causing the set() to expire.
  4. UpdateDashboard in the main loop - is just unusable due to the delay it causes. We used Timer to run updateDashbord only every second and the motors have a very visible slowdown every second!
  5. The Timer “documentation” says it is in microseconds while it is actually in seconds. -minor issue but just highlights the quality and effort that was put into documentation (when there is any). Remember the purpose here is to educate kids, and not to teach them to give up in life!

So any pointers to:

  1. perfrmance aspect of comands that use CANbus, updateDashboard, and
  2. How to get the set/setX() values to stay set (a) no drift, and (b) increase timeout.

Would be greatly appreciated so we can focus on the real code.


I agree that some parts of the documentation are lacking, or even completely incorrect in some instances, but most of it isn’t a giant issue (imho) that would “teach them [kids] to give up in life”. Besides, even if FIRST is primarily about education (hint: it’s not), not everything in life comes with a nicely written manual meticulously error-checked by a university professor.

  1. Regarding CAN, are you guys using PID control and encoders? The problems you’re describing sound a lot like issues with your PID values. I’m only asking because most teams only use CANs for its PID control features. If yes, then perhaps you should read the Wikipedia article on PID control loops and how to tune them. BDC-Comm is a good program to use for the black jaguars provided by FIRST.

  2. You should not need to setExpiration for CAN. Place it in a thread so that other code don’t interfere with its operations.

  3. Same with updateDashboard, put that in a separate thread.

Thanks for the feedback. I am curious to hear your opinion on what is the primary mission of FIRST ?

Really when I look at the thread on the bent pins on the Jaguars - that is criminal - there is no way TI would get away selling that into a supply chain - are they dumping sub-spec stuff into kids programs? At the very least the FIRST suppliers should deliver commercial grade goods. I would actually expect that the engineers behind this would give it an extra effort since it is for kids trying to follow in their footstep.

Back to the code: Yes we implemented our own PID since the built-in one we couldn’t get stable. As a result it is not running in a separate thread. Sounds like you are advising us that if we put something into a thread (PID, Dashboard, DriveStation, etc.) then we should get much better performance for the rest of the code? we’ll look into that thanks - though this is getting a bit advanced for our kid programmers…

How about the drift we see between set() and get() ? Maybe threading will solve that too as we can “flood” the Jag with keep alive CAN messages.

Basically we want to achieve fine motion control so we can rotate the whole robot to the target (no need for a lazy susan), and use the same for bridge balancing. We should be able to do better than a human driver - alas doing it in code is worse!

Thanks for the help!

You seem to be a bit confused about what PID does.

A PID control loop tries to make the jaguars go a certain speed. For example, if you set it to make the motor spin at 1600RPM, that’s not going to make the motor actually spin at 1600RPM (due to the fact that we do not live in a frictionless, air resistance-less, ideal world).

What the PID does is it takes the current speed, and tries to make the jaguars reach what YOU want it to be. So, there will be problems with overshooting, undershooting…etc unless you adjust the PID values.

To tune the PID values, I suggest looking into using BDC-Comm. That’s what we’re using to tune ours.

On an off-note: Primary mission of FIRST = For **Inspiration **and **Recognition **of Science and Tech. Education is a convenient biproduct of that. Or something like that. Hey, give me credit for sitting through Dean’s entire speech.

Seems to me like you have the wrong attitude towards this whole thing. I’m one of the “kid programmers” and so far I’ve already figured out PID loops, distributed image processing across multiple platforms and languages across a wireless network, among much else. So you have a bent pin on the Jaguar, fix it and move on. You’re going to run into a whole lot bigger problems than that at the competition.

Thanks for the feedback. JesusRambo - great name & great to hear you are conquering all obstacles - way to go!

I’m not confused with PID but with the set/get functions. We are using
and implementing our own PID code in our main program. It all works fine and rather cool at MotorPowerLevels>0.2. The reason we went to our own PID is primarily because we have an old 2CIM on one gearbox robot and couldn’t get either the Jag based PID nor the cRio based PID functions to work nicely.

The issue we have is at MotorPowerLevels <0.2 its erratic and the get() drifts away from what we set().

For the competition robot we have one CIM per side, so may try again with built-in PIDs.

Two Qs:

  1. What do you recommend: using the Jaguar’s PID, or the cRIO’s?
  2. How low RPM can one expect to get to with reasonable stability using a Jag & CIM?
  1. Ive used the PID on the Jags, I couldn’t figure out how to run the WPI PID.
  2. I got about 450 rpm with the KOP US encoders, setting them to 360 degrees per turn

How we initialized our Jags

      //Left Master, 360 Encoder 
        left_wheel1 = new CANJaguar(2);
        left_wheel1.setPID(drive_p, drive_i, drive_d);

      //Left Slave
        left_wheel2 = new CANJaguar(3);

How we ran our jags

    	catch(Exception ex){

master, slave style, works like a charm!

Thanks for the code sample - great idea to do Master-Slave via Voltage.
I am confused about Voltage vs. kPercentVbus. The latter is I assume the PWM duty cycle, the former surely cannot be analogue voltage driving the motor, as that would generate immense heat in the Jag. Again very inadequate documentation on this.

Q: why did you use 360 and not the full 1440 counts per revolution (the QuadEncoder max of the KOP encoder)?

I will try your approach and report back. It sure would be great to use the LM3S2616 puppy in the Jag!


Ether, thanks for the useful pointer. FYI I will search for existing or open a new thread on Voltage vs. kPercentVbus as it is still unclear and may benefit others under its own thread.