|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
| Thread Tools |
Rating:
|
Display Modes |
|
#16
|
|||
|
|||
|
Re: New to 2CAN and Jaguar
Quote:
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. */ 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 |
|
#17
|
||||
|
||||
|
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.
|
|
#18
|
||||
|
||||
|
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. |
|
#19
|
|||
|
|||
|
Re: New to 2CAN and Jaguar
Quote:
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 |
|
#20
|
||||
|
||||
|
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. |
|
#21
|
|||
|
|||
|
Re: New to 2CAN and Jaguar
Quote:
-Joe |
|
#22
|
||||
|
||||
|
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);
}
}
};
|
|
#23
|
|||
|
|||
|
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.
|
|
#24
|
||||
|
||||
|
Re: New to 2CAN and Jaguar
Quote:
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? |
|
#25
|
|||
|
|||
|
Re: New to 2CAN and Jaguar
Can you confirm that you are not getting any errors from the set pid call?
|
|
#26
|
||||
|
||||
|
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.
|
|
#27
|
|||
|
|||
|
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.
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);
}
|
|
#28
|
|||
|
|||
|
Re: New to 2CAN and Jaguar
Quote:
I clearly need to write some examples for using CANJaguar in C++. Feel free to contribute some if you like. -Joe |
|
#29
|
||||
|
||||
|
Re: New to 2CAN and Jaguar
Quote:
Quote:
|
|
#30
|
|||
|
|||
|
Re: New to 2CAN and Jaguar
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.
|
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|