Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   C/C++ (http://www.chiefdelphi.com/forums/forumdisplay.php?f=183)
-   -   New to 2CAN and Jaguar (http://www.chiefdelphi.com/forums/showthread.php?t=99685)

mikets 10-01-2012 01:53

New to 2CAN and Jaguar
 
Our team has been using Victors for a number of years. We finally want to embrace Jaguar and try CAN bus for this year. We've got 4 Black Jaguars and a 2CAN (not V2 though). I quickly written some simple code to test the Jaguars but it doesn't work. There must be some sample code written somewhere for CANJaguar on 2CAN. Would somebody point me to it? To summarize what my simple code does:
Code:

class MyRobot: public SimpleRobot
{
private:
    CANJaguar m_jagLeft;
    CANJaguar m_jagRight;
    Joystick m_leftStick;
    Joystick m_rightStick;
 
public:
    MyRobot():
        m_jagLeft(CANID_LEFT_JAG, CANJaguar::kSpeed),
        m_jagRight(CANID_RIGHT_JAG, CANJaguar::kSpeed),
        m_leftStick(JOYSTICK_LEFT),
        m_rightStick(JOYSTICK_RIGHT)
    {
        m_jagLeft.SetSpeedReference(CANJaguar::kSpeedRef_QuadEncoder);
        m_jagRight.SetSpeedReference(CANJaguar::kSpeedRef_QuadEncoder);
 
        m_jagLeft.SetPositionReference(CANJaguar::kPosRef_QuadEncoder);
        m_jagRight.SetPositionReference(CANJaguar::kPosRef_QuadEncoder);
 
        m_jagLeft.SetPID(DRIVE_KP, DRIVE_KI, DRIVE_KD);
        m_jagRight.SetPID(DRIVE_KP, DRIVE_KI, DRIVE_KD);
 
        m_jagLeft.ConfigEncoderCodesPerRev(DRIVE_ENCODER_CODES_PER_REV);
        m_jagRight.ConfigEncoderCodesPerRev(DRIVE_ENCODER_CODES_PER_REV);
 
        m_jagLeft.EnableControl();
        m_jagRight.EnableControl();
    }
 
    ....
    ....
    ....
  void OperatorControl(void)
  {
        while (IsOperatorControl())
        {
            m_jagLeft.Set(-m_leftStick.GetY());
            m_jagRight.Set(-m_rightStick.GetY());
            Wait(0.005);
        }
    }
};

I printed the joystick values to dsLCD and I got reasonable values when reading the sticks. So it means the m_jagXXXX.Set() is not doing anything. All the jags are assigned correct IDs (2 and 3) and have firmware version 92 on them. The 2CAN has a green light and I can access its web page in my browser on http://10.4.92.10. I even plugged in the serial cable directly to one of the jags and ran bdc-comm-92.exe tool. The tool enumerated saw the jag ID 2 and 3 and I was able to set some values on each of the jags and made them turn. That means the CAN bus is wired properly and the 2CAN interface with the CAN bus successfully (through the web interface). The only thing I am unsure is if the cRIO can communicate with the 2CAN. I assume the cRIO knows how to communicate with the 2CAN since I have imaged the cRIO with "2CAN" selected, so the 2CAN driver should be running. And I am also assuming the cRIO will communicate with the 2CAN using 10.xx.xx.10 as its IP address. What else did I miss?

linuxboy 10-01-2012 01:56

Re: New to 2CAN and Jaguar
 
What version image are you running on the cRIO? I don't think the cRIO will talk to Jags with out the latest FRC image for safety reasons. I would check this link. On the side it has BDC-COMM v100, as well as FRC firmware v100. Try flashing that firmware and see if your results change.

Oliver

mikets 10-01-2012 02:32

Re: New to 2CAN and Jaguar
 
Thanks for the info. I have flashed all the Jags with firmware version 100 but it is still not working. The NetConsole has a lot of messages about timing out waiting for the Jag.
Quote:

<Code>-44087 ERROR: status = -44087 (0xFFFF53C9) sendMessage ...in setTransaction() in C:/WindRiver/workspace/WPILib/CANJaguar.cpp at line 406
FRC: JaguarCANDriver timed out waiting to receive a response from a Jaguar.
<Code>-44087 ERROR: status = -44087 (0xFFFF53C9) sendMessage ...in setTransaction() in C:/WindRiver/workspace/WPILib/
What else did I miss?

Mike Copioli 10-01-2012 22:05

Re: New to 2CAN and Jaguar
 
Quote:

Originally Posted by mikets (Post 1101363)
The only thing I am unsure is if the cRIO can communicate with the 2CAN. I assume the cRIO knows how to communicate with the 2CAN since I have imaged the cRIO with "2CAN" selected, so the 2CAN driver should be running. And I am also assuming the cRIO will communicate with the 2CAN using 10.xx.xx.10 as its IP address. What else did I miss?

The 2CAN acts as a gateway to CAN the cRIO simply passes the CAN frame over UDP, the 2CAN has no other interaction with the CRIO.

What you see in the web dash is the result of interactions between the 2CAN and the JAG's over CAN, this and the green led on the 2CAN means you are successfully communicating with the jaguars over CAN and you are successfully communication with the 2CAN plugin on the cRIO. Your problem is most likely in your code.

I noticed that you are calling the closed loop functions. If you are trying to just control the Jag in voltage control mode you do not need to to do this. Also I do not see where you init the Jaguars.

The functions used in CAN are the same regardless of the gateway used (serial or 2CAN). The only difference is the plugin. Make sure you have the most recent plugin and 2CAN firmware (version 2.18).

A couple questions:

1. What is the state of the Jaguar LED? blinking orange or solid orange.
2. What version of 2CAN firmware and plugin are you running?

The -44087 is a timeout error.

http://www.chiefdelphi.com/forums/sh...ad.php?t=91102
http://www.chiefdelphi.com/forums/sh...ad.php?t=91825
http://www.chiefdelphi.com/forums/sh...ad.php?t=91704
http://www.chiefdelphi.com/forums/sh...ad.php?t=91047

mikets 11-01-2012 00:58

Re: New to 2CAN and Jaguar
 
Quote:

Originally Posted by Mike Copioli (Post 1102105)
I noticed that you are calling the closed loop functions. If you are trying to just control the Jag in voltage control mode you do not need to to do this.

What do you mean? The loop is reading the joystick values and programming the Jaguar in speed mode accordingly. If that's not the proper way to program the Jaguar, please show me the proper way.
Quote:

Originally Posted by Mike Copioli (Post 1102105)
Also I do not see where you init the Jaguars.

How do you initialize the Jags? Wouldn't the CANJaguar constructor initialize it for me? I looked at the source code for the CANJaguar module and it calls the InitCANJaguar method. In the InitCANJaguar method, it checks the firmware version to make sure it's between 92 and 3329. Then it send a transaction to the Jag to enable the specified operating mode. That should be enough to initialize the Jags, right?
Quote:

Originally Posted by Mike Copioli (Post 1102105)
The functions used in CAN are the same regardless of the gateway used (serial or 2CAN). The only difference is the plugin. Make sure you have the most recent plugin and 2CAN firmware (version 2.18).

When I imaged the cRIO, I selected 2CAN. According to documentation, this will automatically add the 2CAN driver to the cRIO plug-in list.
Quote:

Originally Posted by Mike Copioli (Post 1102105)
A couple questions:

1. What is the state of the Jaguar LED? blinking orange or solid orange.
2. What version of 2CAN firmware and plugin are you running?

The Jaguar LEDs are blinking either Yellow or Green depending on which angle you are looking at them. According to the Diagnostic page of the 2CAN web dash:
Quote:

Version: 2.5

Build Date: Mar 13 2011 04:56:34
Is it the latest? If not, please point me to the latest firmware. It's not easy to determine which version I should download. According to the web site:
I picked version 2.5 because the other seems to be for 2CAN V2. So I am not sure if I picked the correct version.

Thanks for your help.

mikets 11-01-2012 01:34

Re: New to 2CAN and Jaguar
 
1 Attachment(s)
I took a risk and tried flashing the latest date firmware which is v2.18 (12/21/2011). It looks like the old 2CAN can take this firmware as well. After the firmware update, I can still access the 2CAN dashboard and can see the jags and their data. But unfortunately, the cRIO is still timing out waiting for the Jags to respond. I must be missing something simple. :(

I have attached the whole code since it is highly likely I missed something in the code.

jhersh 11-01-2012 03:39

Re: New to 2CAN and Jaguar
 
As long as you are getting a timeout from a send message call, there is something wrong with either your wiring or your configuration. Once you get past that, then you'll need to make sure you are calling all the right methods to enable the closed-loop control. Your first code snippet was much closer than this most recent post.

Calls like this are needed:

speedJag.SetSpeedReference(CANJaguar::kSpeedRef_Qu adEncoder);
speedJag.ConfigEncoderCodesPerRev(360);
speedJag.SetPID(P, I, D);
speedJag.EnableControl();
speedJag.Set(stick.GetAxis(axis) * 150.0);

Try using the jag in speed mode outside of RobotDrive first.

-Joe

mikets 11-01-2012 03:46

Re: New to 2CAN and Jaguar
 
Quote:

Originally Posted by jhersh (Post 1102404)
As long as you are getting a timeout from a send message call, there is something wrong with either your wiring or your configuration.

Wiring should be fine. I have tested it with the bdc-comm-100.exe tool and was able to see and run all motors. So it means the CAN bus is good. I am also able to see the 2CAN and all the Jags on the network (i.e. can access the 2CAN dashboard on 10.4.92.10 and see the status of all the jags). So it means the ethernet connection to the 2CAN is good. What other wiring could be wrong?
Quote:

Originally Posted by jhersh (Post 1102404)
Once you get past that, then you'll need to make sure you are calling all the right methods to enable the closed-loop control. Your first code snippet was much closer than this most recent post.

Yeah, I decided to redo the program with standard template and thinking I don't care about the encoders yet so I skipped the encoder related initialization. So you are saying they are still required?

jhersh 11-01-2012 04:03

Re: New to 2CAN and Jaguar
 
Quote:

Originally Posted by mikets (Post 1102405)
Wiring should be fine. I have tested it with the bdc-comm-100.exe tool and was able to see and run all motors. So it means the CAN bus is good. I am also able to see the 2CAN and all the Jags on the network (i.e. can access the 2CAN dashboard on 10.4.92.10 and see the status of all the jags). So it means the ethernet connection to the 2CAN is good. What other wiring could be wrong?

Probably nothing. Are you checking for errors or messages on the console being printed by the 2CAN plugin? Have you tried a BlackJag bridge?

Quote:

Originally Posted by mikets (Post 1102405)
Yeah, I decided to redo the program with standard template and thinking I don't care about the encoders yet so I skipped the encoder related initialization. So you are saying they are still required?

They are required for closed loop mode... without some process variable, the controller does nothing. You may want to try simple PercentVbus mode first. Start simple and all. Verify you can talk to the Jags at all. Make sure your device numbers in the constructors match what you configured.

mikets 11-01-2012 04:27

Re: New to 2CAN and Jaguar
 
1 Attachment(s)
I changed the program as you suggested (new code attached). Notice that I added the jag.Set(30.0) in there outside of the loop. When running it, I heard the motor noise like it had moved but then stopped. When I looked, nothing happened. Then I noticed my voltage is getting low and the Jags are no longer powered. I think my battery is now exhausted. Unfortunately, the mechanical mentor has the charger. So I guess I am done for tonight. But I am excited, it may mean the motor really moved but then the battery died because of the current drawn. If that's the case, it means the jag.Set() outside of the loop worked. If so, the next step is to find out why the ArcadeDrive inside the loop did not work. Since you suggested "speedJag.Set(stick.GetAxis(axis) * 150.0);", does it mean the full range of the Jag is -150.0 to 150.0? How about the ArcadeDrive call? Would the RobotDrive object do the scaling to 150, or do I need to call SetMaxOutput myself? I can't find anywhere in CANJaguar that it scales the outputValue. If that's the case, that explains why the motors didn't move because the outputValue will be below or equal to 1.0 in a full scale of 150.0. I thought everything in WPILib scaled to 1.0. Why is it that we need to multiply 150.0 in jagSpeed.Set()? If the speed mode is really in the range of -150.0 to 150.0, is there documentation somewhere telling me what range is the motor in which mode?

mikets 11-01-2012 04:48

Re: New to 2CAN and Jaguar
 
Wait, I found the scaling code in CANJaguar. It is in packFXP16_16. It means the full range is actually +/- 65536. So like I suspected, the outputValues in jag.Set() should always be in the range of +/- 1.0 and the CANJaguar module will scale it to +/- 65536 and send it to the jags. Then why do we need to multiply 150.0? I am confused.

Mike Copioli 11-01-2012 09:57

Re: New to 2CAN and Jaguar
 
Quote:

Originally Posted by mikets (Post 1102310)
Is it the latest? If not, please point me to the latest firmware. It's not easy to determine which version I should download.

The latest release is indicated by the most recent release date and the version number. version 2.18 is higher than version 2.5.

2.18 .crf for the 2CAN

http://www.crosstheroadelectronics.c...2_18_FIRST.crf

As for the plugin a new one will be released shortly but the SVN rev 66 should work fine.

http://www.crosstheroadelectronics.c...01-29-2011.zip

The latest version is back wards compatible with version 1 2CAN hardware. The only difference between 2.5 and 2.18 is 2.18 supports the device id for a different version of Ethernet silicon inside the 2CAN. All new versions of 2CAN firmware will support both devices.

One thing to note if the 2CAN has a Green LED your problem is not on the CAN side(wiring, termination) the LED can only be green when at least one Jaguar is present on the BUS and responding to enumeration requests from the 2CAN and the the plugin has successfully loaded. If you had bad termination or faulty wiring you would see a red strobing LED and the Jags would not appear in the web dash. Since you are able to see all of your jags in the web dash and the 2CAN LED is green your problem is not in the CAN wiring or termination. This is a very useful tool that can be used to provide quick diagnostics when setting your robot up on the field. Green is good red is dead.

Follow Joe's advice regarding your code as it seems you already have.

Mike Copioli 11-01-2012 13:24

Re: New to 2CAN and Jaguar
 
A couple observations:

It appears that at this point all you want to do is control your Jags using voltage control mode, this is the mode that provides the same functionality as pwm and is the default mode in the CANJaguar constructor.

CANJaguar (UINT8 deviceNumber, ControlMode controlMode=kPercentVbus)
Constructor.

You pass in a throttle value between -1 and 1 into Set(). To simplify things I would remove all but one Jaguar from the CAN bus. Make sure you are only calling Set() for the Jag that is on the CAN bus as this will also cause the
-44087 error to appear. Open the web dash to verify the Jag ID. Using only one JAG eliminates the possibility of having more than one jag on the BUS with the same ID, this will also cause the -44087 error as well.

Make sure the 2CAN LED is green if it is RED power cycle the Jag and the LED should turn Green. (FYI if you remove the CAN cable from the JAG the 2CAN led should turn red, removing the Ethernet cable should cause the LED to turn orange, removing both will cause a red LED.)

If the LED is green and you have the correct ID's and you are not sending requests to any other JAG's that are not on the BUS your code should work.

mikets 11-01-2012 13:34

Re: New to 2CAN and Jaguar
 
Thanks for the info. I will try that tonight. One question though, if I run the Jags in Voltage mode (kPercentVbus), it means it doesn't need encoder (as versus Speed mode or Position mode). Can I skip the encoder related initializations just to make it even simpler? For example, SetSpeedReference, SetPositionReference, SetPID and ConfigEncoderCodesPerRev?

Mike Copioli 11-01-2012 14:47

Re: New to 2CAN and Jaguar
 
Quote:

Originally Posted by mikets (Post 1102642)
Thanks for the info. I will try that tonight. One question though, if I run the Jags in Voltage mode (kPercentVbus), it means it doesn't need encoder (as versus Speed mode or Position mode). Can I skip the encoder related initializations just to make it even simpler? For example, SetSpeedReference, SetPositionReference, SetPID and ConfigEncoderCodesPerRev?

Correct, those function calls are only necessary if you want to use the closed loop modes or request encoder/potentiometer position.

jhersh 11-01-2012 16:08

Re: New to 2CAN and Jaguar
 
Quote:

Originally Posted by mikets (Post 1102410)
Wait, I found the scaling code in CANJaguar. It is in packFXP16_16. It means the full range is actually +/- 65536. So like I suspected, the outputValues in jag.Set() should always be in the range of +/- 1.0 and the CANJaguar module will scale it to +/- 65536 and send it to the jags. Then why do we need to multiply 150.0? I am confused.

The actual range depends on the mode. Look at the documentation for CANJaguar::Set.

Code:

/**
 * Set the output set-point value. 
 *
 * The scale and the units depend on the mode the Jaguar is in.
 * In PercentVbus Mode, the outputValue is from -1.0 to 1.0 (same as PWM Jaguar).
 * In Voltage Mode, the outputValue is in Volts.
 * In Current Mode, the outputValue is in Amps.
 * In Speed Mode, the outputValue is in Rotations/Minute.
 * In Position Mode, the outputValue is in Rotations.
 *
 * @param outputValue The set-point to sent to the motor controller.
 * @param syncGroup The update group to add this Set() to, pending UpdateSyncGroup().  If 0, update immediately.
 */

Everything you see inside the CANJaguar class is to convert from the WPILib API formats (such as -1.0 to 1.0) into the binary format to send to the Jag. Since in speed mode, the units are RPM, I don't want to control my motor +/- 1 RPM... that's too slow. I set the RPM range in my example to +/- 150 RPM cause it made sense for the mechanism I was sensing with that encoder.

In the case of RobotDrive, it computes a motor output +/- 1.0 based on joystick inputs. If you are not using motors in Percent Vbus mode, then that's probably not a good range. The RobotDrive class allows you to specify a scale value by calling SetMaxOutput(); with a floating point number to multiply by the +/-1.0 values that it computes before they are passed into the Set(); call on each motor.

Hope that's clearer.

-Joe

mikets 11-01-2012 16:18

Re: New to 2CAN and Jaguar
 
Ah, I missed the comments in the code. It must be too late in the night. Thanks. That's much clearer.

mikets 11-01-2012 20:05

Re: New to 2CAN and Jaguar
 
Actually, few more questions: is the kPercentVbus mode essentially kVoltage but just scale to the range of -1.0 and 1.0? Only kSpeed and kPosition modes use encoder/potentiometer? Are kVoltage and kCurrent modes also considered close-loop modes? To me, close-loop means feedback. Monitoring output voltage and current so it can maintain constant values seem close-loop to me too even though it is not using any "external sensors" such as encoder and potentiometer.

Thanks.

jhersh 11-01-2012 20:57

Re: New to 2CAN and Jaguar
 
Quote:

Originally Posted by mikets (Post 1102979)
Actually, few more questions: is the kPercentVbus mode essentially kVoltage but just scale to the range of -1.0 and 1.0? Only kSpeed and kPosition modes use encoder/potentiometer? Are kVoltage and kCurrent modes also considered close-loop modes? To me, close-loop means feedback. Monitoring output voltage and current so it can maintain constant values seem close-loop to me too even though it is not using any "external sensors" such as encoder and potentiometer.

Thanks.

Voltage mode is different. Lets take two cases:

If your battery voltage is 12V and you specify 0.5 in PercentVbus mode, you get 6V and if you specify 6V in Voltage mode, you get 6V.

If your battery voltage is 9V and you specify 0.5 in PercentVbus mode, you get 4.5V and if you specify 6V in Voltage mode, you get 6V.

Position, Speed, and Current (the sensor is inside the Jag, but external to the controller) are closed loop modes that use a PID algorithm with feedback. The Voltage mode is not closed loop because the setting is simply scaled based on the bus voltage, not corrected based on the resulting output. This is because unlike the other modes, the voltage can be controlled directly.

-Joe

mikets 12-01-2012 03:36

Re: New to 2CAN and Jaguar
 
I got it to work now. Here is what I learned:
- My encoders are not working, it could be the cable. We will figure that out later.
- Apparently, if I do kSpeed mode, the motors jerk back and forth violently. Sort of vibrating loudly. That gave me the hint that the encoders are not working. I added a call to GetPosition and saw only zeros.
- So I changed the code to use kVoltage mode and scale the joystick values by multiplying with 12.0. This doesn't work either.
- Then I thought since the encoders are not working, I would disable all the encoder related initialization. To my surprise, that works. I would have thought the encoder is ignored when doing kVoltage mode, but apparently not.
- With the encoder initialization disabled, I changed the code to use kPercentVbus mode and removed the 12.0 multiplier. That also worked.

So the robot is totally tele-operating. Next step is to figure out what's wrong with the encoders.

jhersh 12-01-2012 03:52

Re: New to 2CAN and Jaguar
 
Quote:

Originally Posted by mikets (Post 1103339)
So the robot is totally tele-operating. Next step is to figure out what's wrong with the encoders.

Congrats! About the encoders affecting the Voltage mode, that should not be the case. Usually when something like that happens it means you got an error other than a timeout and the object has given up talking to the Jaguar until you either fix your code and rerun, or you call ClearError() on the object. Check for errors.

-Joe

mikets 17-01-2012 05:57

Re: New to 2CAN and Jaguar
 
Now that the Jags run successfully in kPercentVbus mode as well as kVoltage mode as long as all the Encoder related initializations are commented out, I am investigating what exactly caused this. I have isolated the culprit. It looks like all the encoder initializations are fine except for the SetPID calls. So basically, the following code doesn't work until I comment out the CULPRIT_CODE lines. Note that the Jags are initialized to kPercentVbus mode. Kp is 15.0, both Ki and Kd are zeros. What could have caused this?
Code:

class MyRobot: public SimpleRobot
{
private:
    CANJaguar m_jagLeft;
    CANJaguar m_jagRight;
    Joystick m_leftStick;
    Joystick m_rightStick;
 
public:
    MyRobot():
        m_jagLeft(CANID_LEFT_JAG, CANJaguar::kPercentVbus),
        m_jagRight(CANID_RIGHT_JAG, CANJaguar::kPercentVbus),
        m_leftStick(JOYSTICK_LEFT),
        m_rightStick(JOYSTICK_RIGHT)
    {
        m_jagLeft.SetSpeedReference(CANJaguar::kSpeedRef_QuadEncoder);
        m_jagRight.SetSpeedReference(CANJaguar::kSpeedRef_QuadEncoder);
 
        m_jagLeft.SetPositionReference(CANJaguar::kPosRef_QuadEncoder);
        m_jagRight.SetPositionReference(CANJaguar::kPosRef_QuadEncoder);
 
#ifdef _CULPRT_CODE
        m_jagLeft.SetPID(DRIVE_KP, DRIVE_KI, DRIVE_KD);
        m_jagRight.SetPID(DRIVE_KP, DRIVE_KI, DRIVE_KD);
#endif

        m_jagLeft.ConfigEncoderCodesPerRev(DRIVE_ENCODER_CODES_PER_REV);
        m_jagRight.ConfigEncoderCodesPerRev(DRIVE_ENCODER_CODES_PER_REV);

        m_jagLeft.EnableControl();
        m_jagRight.EnableControl();
    }
 
    ....
    ....
    ....
    void OperatorControl(void)
    {
        while (IsOperatorControl())
        {
            m_jagLeft.Set(-m_leftStick.GetY());
            m_jagRight.Set(-m_rightStick.GetY());
            Wait(0.005);
        }
    }
};


jwakeman 17-01-2012 13:46

Re: New to 2CAN and Jaguar
 
I don't know if this is your problem but kp=15 doesn't seem right. I was doing current control mode with the jags last night and i was using Kp=0.01 and Ki = 0.05. Regardless if you are in percent vbus mode I would think the PID gains should have no effect.

mikets 17-01-2012 17:26

Re: New to 2CAN and Jaguar
 
Quote:

Originally Posted by jwakeman (Post 1107764)
if you are in percent vbus mode I would think the PID gains should have no effect.

That's exactly my point. I was using PercentVbus mode, PID constants should be totally irrelevant and should be ignored. It is true that I could just comment out the SetPID calls and call it good since PercentVbus mode doesn't need them. But there are cases where I need to call ChangeControlMode and change to a close-loop mode. When that happens, I must call SetPID to set the constants. And later on, I may switch back to PercentVbus mode. If calling SetPID would make non close-loop mode not working, that's not very intuitive.
BTW, I set Kp to 15 because I tested the Jag with bdc-comm tool using Position mode and found that if the value is higher than 15 (e.g. 20), the wheel will oscillate before stopping at the target position. If it is less than 15 (e.g. 5), it takes a long time to get to the set target. I am not familiar with the internal PID algorithm of the Jags, but from my point of view, K should be different in different modes. For example, Kp is multiplied to the "error" to get the output voltage. Different modes have different units (Amp in current, rev in Position and rev/sec in Speed). So the error will be in different ranges and so the K multiplier could be quite different. Since I am new to Jags, I could be totally wrong but this is my understanding. Regardless, even if my K's are wrong, as you said, PercentVbus mode should ignore them anyway. So why would it not work if I called SetPID?

jhersh 17-01-2012 17:39

Re: New to 2CAN and Jaguar
 
Can you confirm that you are not getting any errors from the set pid call?

mikets 17-01-2012 18:41

Re: New to 2CAN and Jaguar
 
SetPID is a void function. How do I check the "error"? GetFault()? If so, I did print out the value returned by GetFault in the loop. As far as I can tell, it's returning 0.

jwakeman 17-01-2012 19:03

Re: New to 2CAN and Jaguar
 
I will be working with the Jags tomorrow night. I can try to see if I see the same issue as you.

Quote:

Originally Posted by mikets (Post 1107864)
I am not familiar with the internal PID algorithm of the Jags...

The source code for the Jags is open. Here is the PID algorithm for fun:

Code:

//*****************************************************************************
//
// This function will execute another iteration of the PID algorithm.  In
// order to get reliable results from this, the sampled values passed in must
// be captured at fixed intervals (as close as possible).  Deviations from a
// fixed capture interval will result in errors in the control output.
//
//*****************************************************************************
long
PIDUpdate(tPIDState *psState, long lError)
{
    long long llOutput;
    long lOutput;

    //
    // Update the error integrator.
    //
    if((psState->lIntegrator & 0x80000000) == (lError & 0x80000000))
    {
        //
        // Add the error to the integrator.
        //
        psState->lIntegrator += lError;

        //
        // Since the sign of the integrator and error matched before the above
        // addition, if the signs no longer match it is because the integrator
        // rolled over.  In this case, saturate appropriately.
        //
        if((lError < 0) && (psState->lIntegrator > 0))
        {
            psState->lIntegrator = psState->lIntegMin;
        }
        if((lError > 0) && (psState->lIntegrator < 0))
        {
            psState->lIntegrator = psState->lIntegMax;
        }
    }
    else
    {
        //
        // Add the error to the integrator.
        //
        psState->lIntegrator += lError;
    }

    //
    // Saturate the integrator if necessary.
    //
    if(psState->lIntegrator > psState->lIntegMax)
    {
        psState->lIntegrator = psState->lIntegMax;
    }
    if(psState->lIntegrator < psState->lIntegMin)
    {
        psState->lIntegrator = psState->lIntegMin;
    }

    //
    // Compute the new control value.
    //
    llOutput = (((long long)psState->lPGain * (long long)lError) +
                ((long long)psState->lIGain *
                (long long)psState->lIntegrator) +
                ((long long)psState->lDGain *
                (long long)(lError - psState->lPrevError)));

    //
    // Clip the new control value as appropriate.
    //
    if(llOutput > (long long)0x7fffffffffff)
    {
        lOutput = 0x7fffffff;
    }
    else if(llOutput < (long long)0xffff800000000000)
    {
        lOutput = 0x80000000;
    }
    else
    {
        lOutput = (llOutput >> 16) & 0xffffffff;
    }

    //
    // Save the current error for computing the derivitive on the next
    // iteration.
    //
    psState->lPrevError = lError;

    //
    // Return the control value.
    //
    return(lOutput);
}


jhersh 17-01-2012 19:10

Re: New to 2CAN and Jaguar
 
Quote:

Originally Posted by mikets (Post 1107912)
SetPID is a void function. How do I check the "error"? GetFault()? If so, I did print out the value returned by GetFault in the loop. As far as I can tell, it's returning 0.

No... it's not GetFaults() that you want... it's GetError(). You can call StatusIsFatal() to get a boolean for if there is an error or not. GetError() returns an "Error" object (Error.h) that you can call a number of methods on if it is an error. It is generally good practice to always check for an error after every call to a CANJaguar object so you know if you can trust the data that is returned or if the command you sent was acknowledged by the Jaguar. If you get an error that is not "Time-out", the CANJaguar object will stop trying to talk to the device, since the calling code is clearly broken. This is likely what is happening in your case. If you get an error and you want to continue talking to the device, you can call ClearError() to try again. You should also call ClearError() if you get a time-out so that you can tell if there is a timeout from a future call.

I clearly need to write some examples for using CANJaguar in C++. Feel free to contribute some if you like.

-Joe

mikets 17-01-2012 19:11

Re: New to 2CAN and Jaguar
 
Quote:

Originally Posted by jhersh (Post 1107873)
Can you confirm that you are not getting any errors from the set pid call?

Ah, I see what you meant. You meant the error in the console. Yes, it indeed complained that I can't call SetPID while the Jag was in PercentVbus mode. But why the limitation?
Quote:

ERROR: The object is in an incompatible mode: PID constants only apply in Speed, Position, and Current mode ...in SetPID() in C:/WindRiver/workspace/WPILib/CANJaguar.cpp at line 539

jhersh 17-01-2012 19:13

Re: New to 2CAN and Jaguar
 
Quote:

Originally Posted by mikets (Post 1107935)
Ah, I see what you meant. You meant the error in the console. Yes, it indeed complained that I can't call SetPID while the Jag was in PercentVbus mode. But why the limitation?

The limitation is because if your code thinks it's a good idea to call SetPID when not in a closed-loop control mode, you probably need to be made aware of that and fix your code before expecting it to function properly.

mikets 17-01-2012 19:17

Re: New to 2CAN and Jaguar
 
So does it mean I can only call SetPID after I call ChangeControlMode to a close-loop mode? And I assume I have to call SetPID every time after I change to a close-loop mode. In other words, the PID constants will be cleared on every mode change?
Hmm, thinking about it some more, it makes sense. Since the PID constants are different for different close-loop mode, it makes sense to set them after a close-loop mode is set.
Thanks for the info. Learn something today :-)

jhersh 17-01-2012 19:20

Re: New to 2CAN and Jaguar
 
Quote:

Originally Posted by mikets (Post 1107940)
So does it mean I can only call SetPID after I call ChangeControlMode to a close-loop mode? And I assume I have to call SetPID every time after I change to a close-loop mode. In other words, the PID constants will be cleared on every mode change?

The Jaguar has separate messages for setting each control mode's PID constants, so the CANJaguar class has no message ID that it can use to send those PID constants if you are not in a closed-loop mode.

I don't believe they are cleared... they are stored as separate variables in the Jaguar. That could be easily tested by setting one mode, calling SetPID, changing modes, calling SetPID again, then switching modes back and calling GetPID.

mikets 17-01-2012 19:23

Re: New to 2CAN and Jaguar
 
Yes, I remember now. I saw that behavior in bdc-comm tool.

mikets 17-01-2012 20:02

Re: New to 2CAN and Jaguar
 
I have another issue. I am also experimenting with kSpeed mode. No code this time. I am playing with the bdc-comm tool.
- I set one of the Jags to kSpeed mode
- Set the speed to 30 rpm.
- I kept Ki and Kd zero and was playing with Kp only.
- The wheel moved very jerkily (i.e. jerk forward, stop, jerk forward stop, ...) so it is making a loud clunging noise.
- I tried Kp = 1.0 and up. The larger Kp, the louder is the clunging noise.
My theory was that the Kp was too strong. It started too strong and because of the "brake" mode, it also stopped too suddenly. Basically, the "speed" was oscillating. So I cranked down Kp. Eventually, when Kp is 0.35, the wheel seems to turn smoothly. But when looking at the speed, it was very far from the target. For example if I set target to 70 rpm, it comes back with 30. When I set it to 60 rpm, it came back at 25. Am I interpreting this correctly? I am not sure about the units because the bdc-comm tool does not show me the units in Speed mode. It looks like the target value box can only accept a maximum value of 100 (may be it's a percentage? But percentage of what?).

jwakeman 17-01-2012 20:10

Re: New to 2CAN and Jaguar
 
Quote:

Originally Posted by jhersh (Post 1107933)
If you get an error that is not "Time-out", the CANJaguar object will stop trying to talk to the device, since the calling code is clearly broken.


Is this still true with v101 of the firmware? I think this version of the firmware will bring the Jaguar back online after such a fault? Or is this a different set of circumstances?


Quote:

Originally Posted by jhersh (Post 1107933)
I clearly need to write some examples for using CANJaguar in C++. Feel free to contribute some if you like.

I did spend an hour last night figuring out that I needed to call EnableControl() before it would respond to my Set() commands.

This is the code I was playing with last night to get familiar with the Jaguar closed loop current control. Basically a tank drive that commands current:

Code:

#include "testBot.h"
#include "CANJaguar.h"
#include "Joystick.h"


testBot::testBot()
{
}

testBot::~testBot()
{
}       

void testBot::OperatorControl()
{
        printf("Entering Operator Control\n");

        GetWatchdog().SetEnabled(true);       

        CANJaguar* pJag2 = new CANJaguar(2,CANJaguar::kCurrent);
        CANJaguar* pJag3 = new CANJaguar(3,CANJaguar::kCurrent);
        CANJaguar* pJag4 = new CANJaguar(4,CANJaguar::kCurrent);
        CANJaguar* pJag5 = new CANJaguar(5,CANJaguar::kCurrent);
       
        Joystick* pDriveStick1 = new Joystick(1);
        Joystick* pDriveStick2 = new Joystick(2);

        pJag2->SetPID(0.01,0.05,0);
        pJag3->SetPID(0.01,0.05,0);
        pJag4->SetPID(0.01,0.05,0);
        pJag5->SetPID(0.01,0.05,0);
       
        pJag2->ConfigNeutralMode(CANJaguar::kNeutralMode_Coast);
        pJag3->ConfigNeutralMode(CANJaguar::kNeutralMode_Coast);
        pJag4->ConfigNeutralMode(CANJaguar::kNeutralMode_Coast);
        pJag5->ConfigNeutralMode(CANJaguar::kNeutralMode_Coast);

        pJag2->EnableControl();
        pJag3->EnableControl();
        pJag4->EnableControl();
        pJag5->EnableControl();
               
        pJag2->Set(0, 0);
        pJag3->Set(0, 0);
        pJag4->Set(0, 0);
        pJag5->Set(0, 0);
       
        while(IsOperatorControl() && IsEnabled())
        {
                GetWatchdog().Feed();
                pJag2->Set(pDriveStick1->GetY() * 50);
                pJag4->Set(pDriveStick1->GetY() * 50);
                pJag5->Set(pDriveStick2->GetY() * -1 * 50);
                pJag3->Set(pDriveStick2->GetY() * -1 * 50);
        }
       

        printf("Leaving Operator Control\n");
}

void testBot::Autonomous()
{
        GetWatchdog().SetEnabled(false);
       
        while(IsAutonomous() && IsEnabled())
        {
        }
}

START_ROBOT_CLASS(testBot);


mikets 17-01-2012 20:45

Re: New to 2CAN and Jaguar
 
Quote:

Originally Posted by mikets (Post 1107982)
For example if I set target to 70 rpm, it comes back with 30. When I set it to 60 rpm, it came back at 25. Am I interpreting this correctly? I am not sure about the units because the bdc-comm tool does not show me the units in Speed mode. It looks like the target value box can only accept a maximum value of 100 (may be it's a percentage? But percentage of what?).

Since I don't know what are the units in the bdc-comm tool, I started to play with code again setting the Jags to Speed mode and calling jag.Set(300.0) for setting 300 rpm (I think... since that's what the documentation said the unit is). But I also call jag.GetSpeed() and it came back about half. So if the set was 300, I got the speed back 150. If I set 120.0, I got back about 60.0. Is this expected?

jhersh 18-01-2012 01:49

Re: New to 2CAN and Jaguar
 
Quote:

Originally Posted by mikets (Post 1107982)
I have another issue. I am also experimenting with kSpeed mode. No code this time. I am playing with the bdc-comm tool.
- I set one of the Jags to kSpeed mode
- Set the speed to 30 rpm.
- I kept Ki and Kd zero and was playing with Kp only.
- The wheel moved very jerkily (i.e. jerk forward, stop, jerk forward stop, ...) so it is making a loud clunging noise.
- I tried Kp = 1.0 and up. The larger Kp, the louder is the clunging noise.
My theory was that the Kp was too strong. It started too strong and because of the "brake" mode, it also stopped too suddenly. Basically, the "speed" was oscillating. So I cranked down Kp. Eventually, when Kp is 0.35, the wheel seems to turn smoothly. But when looking at the speed, it was very far from the target. For example if I set target to 70 rpm, it comes back with 30. When I set it to 60 rpm, it came back at 25. Am I interpreting this correctly? I am not sure about the units because the bdc-comm tool does not show me the units in Speed mode. It looks like the target value box can only accept a maximum value of 100 (may be it's a percentage? But percentage of what?).

You should probably look at these threads:

http://www.chiefdelphi.com/forums/sh...d.php?t=100135
http://www.chiefdelphi.com/forums/sh...ad.php?t=90508

dsirovica 15-02-2012 17:49

Re: New to 2CAN and Jaguar
 
We have the same issue on jerkyness at low speed. Still trying to figure that one out... see other threads on CANbus Control. We wrote our own PID code, but may move to the Jag intrenal PID to offload cRio.

But on the Kp we had the same result as others. Kp alone will always yields a top speed of approx 1/2 setpoint. Ki however, does a beatiful job at reaching setpoint and (in our configuration) became the dominant control force.

mikets 15-02-2012 19:11

Re: New to 2CAN and Jaguar
 
In order to get a stable speed control using PID, you need to integrate the PID controller. That's why we can't use the Jaguar's built-in PID. There shouldn't be any problem with the cRIO. It would just be an extra PID calculation in the main robot loop.


All times are GMT -5. The time now is 12:17.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi