Log in

View Full Version : PIDController not manipulating jaguars


vigneshv
25-01-2014, 15:02
Hi,
I have a PIDController with the PIDSource as an encoder and the PIDOutput as a Jaguar. Even though the PIDController->GetError() returns a value of 100 (the encoder distance value - setpoint (this is correct)), the Jaguars do not run automatically to minimize the error. Why is this happening?

Joe Ross
25-01-2014, 16:30
What values did you use for P, I, and D? Did you enable the PID Controller?

vigneshv
25-01-2014, 17:41
P = 13, I = 13, D = 13, PID was enabled.

NotInControl
25-01-2014, 17:59
Are there any flashing or solid lights on the Jaguar? is it a black jag or a grey one? Do you notice the same behavior using BDC-COM?

vigneshv
25-01-2014, 18:52
The Jaguar is a grey Jaguar, and the Jaguar just has a solid orange light. I cannot use Set() to manipulate it either.

gpetilli
25-01-2014, 19:12
The Jaguar is a grey Jaguar, and the Jaguar just has a solid orange light. I cannot use Set() to manipulate it either.

Are you using CAN or PWM for the Jaguar. If CAN, the gray Jaguars do not have an RS232 to CAN interface and can not be the first Jaguar in a chain. You should check it by using PC with BDC-COM and a serial cable to a black Jaguar and daisy chain CAN to the gray one. You might as well flash the firmware while you have it hooked up.

NotInControl
25-01-2014, 19:40
The Jaguar is a grey Jaguar, and the Jaguar just has a solid orange light. I cannot use Set() to manipulate it either.

Can you paste your code? Because the light is solid that means that the jaguar is correctly gettting power and receiving comms. It may be a programming problem, maybe the wrong motor controller is referenced.

Posting your code will help us better help you.

vigneshv
25-01-2014, 19:59
We also get a PID output with a value between 1 and -1, but the Jaguar does not move. The Jaguar is connected to the PWM output port 1.

#include "WPILib.h"

class RobotDemo : public SimpleRobot
{
RobotDrive myRobot; // robot drive system

Joystick *stick; // only joystick
DriverStationLCD *screen;
Encoder *encoder1;

Jaguar *motor1;

PIDController *PIDmotor1;


public:
RobotDemo():
myRobot(1, 2)//, // these must be initialized in the same order

{
stick = new Joystick(1);
screen = DriverStationLCD::GetInstance();
encoder1 = new Encoder(13,14);
motor1 = new Jaguar(1);
PIDmotor1 = new PIDController(0.5,0,0,encoder1,motor1);

PIDmotor1->SetContinuous(true);
PIDmotor1->SetOutputRange(-1,1);
PIDmotor1->SetTolerance(3);

myRobot.SetExpiration(0.1);
}

/**
* Drive left & right motors for 2 seconds then stop
*/
void Autonomous()
{
myRobot.SetSafetyEnabled(false);
myRobot.Drive(-0.5, 0.0); // drive forwards half speed
Wait(2.0); // for 2 seconds
myRobot.Drive(0.0, 0.0); // stop robot
}


void OperatorControl()
{
myRobot.SetSafetyEnabled(true);

encoder1->Start();

PIDmotor1->SetSetpoint(0);

while (IsOperatorControl())
{
if(stick->GetRawButton(3))
{
PIDmotor1->SetSetpoint(100);
}
if(stick->GetRawButton(2))
{
PIDmotor1->SetSetpoint(-100);
}
if(stick->GetRawButton(4))
{
PIDmotor1->Enable();
}





screen->PrintfLine(DriverStationLCD::kUser_Line1, "Count = %d", encoder1->GetRaw());
screen->PrintfLine(DriverStationLCD::kUser_Line2, "Error = %f", PIDmotor1->GetError());
screen->PrintfLine(DriverStationLCD::kUser_Line3, "Setpoint = %f", PIDmotor1->GetSetpoint());
screen->PrintfLine(DriverStationLCD::kUser_Line4, "Output = %f", PIDmotor1->Get());
//myRobot.ArcadeDrive(stick); // drive with arcade style (use right stick)
screen->UpdateLCD();
Wait(0.005); // wait for a motor update time
}
}

/**
* Runs during test mode
*/
void Test() {

}
};

START_ROBOT_CLASS(RobotDemo);

Joe Ross
25-01-2014, 20:09
Both the Jaguar and the RobotDrive are using PWM 1.

vigneshv
25-01-2014, 20:35
So if we remove the RobotDrive, it will work?

vigneshv
25-01-2014, 20:36
So if we remove the RobotDrive, it will work, because as I understand RobotDrive uses the Jag ports as well?

Alan Anderson
26-01-2014, 13:08
Put your PID-controlled Jaguar on a PWM port that isn't already being used by other code. It's a one-character change to your code, and a single connector to move from one set of pins to another.
motor1 = new Jaguar(3);

vigneshv
26-01-2014, 15:32
Isn't the RobotDrive supposed to use the jaguar ports, or should I remove that entirely and control the robot with motor1->Set()?

Alan Anderson
26-01-2014, 21:38
The questions you're asking seem to be assuming something that you haven't told us. Can you explain exactly what you're trying to get the robot to do? What sort of mechanism are you controlling, and where do you have the encoder mouted? I get the feeling that what you want is something you haven't quite made clear to us.

vigneshv
27-01-2014, 09:14
Hi,
I am trying to use the PID controller to keep the robot stationary while shooting.

Alan Anderson
27-01-2014, 10:52
That's most of an answer to my first question. If I understand you correctly, you want to control the drivebase motors in order to maintain a fixed position on the field, right?

Let's try for an answer to my other two questions now. What kind of drivebase do you have? Describe the number, type, and placement of wheels, number and type of motors, kind of gearbox, chain vs. belt, etc. Where do you have the encoders mounted? I'd rather give advice based on what you really need rather than assume things about what your robot is like.

Here's another question, now that I think you're talking about the drive motors: Does it matter whether or not the robot gets turned in place?

vigneshv
27-01-2014, 11:55
It is a 6 wheel tank drive with the encoders on the gearbox. It just matters if the gears on either the left or right gearbox turn. Thanks!

Alan Anderson
27-01-2014, 12:59
I am reluctant to offer suggestions when I can't get a straight answer to yes-or-no questions. I'll ask them again:

1) You want to control the drivebase motors in order to maintain a fixed position on the field, right?

2) Does it matter whether or not the robot gets turned in place?

I'm trying to find out if you care about the orientation of the robot (the direction it's facing) or if you just want to stay over the same patch of field carpet. There are several different ways to do it, and the most appropriate one depends on the details of your requirements.

vigneshv
27-01-2014, 14:18
1) Yes
2) Yes, whether the robot is turned in place matters.

gpetilli
27-01-2014, 15:31
It is a 6 wheel tank drive with the encoders on the gearbox. It just matters if the gears on either the left or right gearbox turn. Thanks!

Keep in mind that with tank drive, there is no way to protect against what I will call T-Bone. Your encoders wont move, and you have no torque in the X-direction anyway.

Are you using center drop wheel or are you using Omniwheels? If you are not using drop center wheels, I strongly recommend exactly two omnis (front or back) as a good compromise between turning ability and traction.

If you have left and right velocity PID loops to your gearbox encoders, it should allow the robot to old it's ground since any movement will be an error verses the commanded zero velocity. If the two loops act independently, they should also hold orientation. Any slop in your drive chain will limit your ability to sense movement and cause sensor delays (phase errors) which make the PID much harder to stabilize.

That said, we are finding that for external forces, the accelerometer works well for X and Y. For rotation, we are looking at the gyro.

Ether
27-01-2014, 15:40
If you have left and right velocity PID loops to your gearbox encoders, it should allow the robot to old it's ground since any movement will be an error verses the commanded zero velocity. If the two loops act independently, they should also hold orientation.

I question whether velocity PID based on rate feedback from drivetrain gearbox encoders will allow the bot to re-establish its orientation (or even position) after an impact.

Joe Ross
27-01-2014, 15:47
It can be a little tricky to get PID control and manual control of the same motors with the WPILib PID Controller class. I posted a short description of the method we used here: http://www.chiefdelphi.com/forums/showthread.php?t=114061

Alan Anderson
27-01-2014, 15:51
2) Yes, whether the robot is turned in place matters.

Then you probably want to do arcade drive with closed-loop control. The forward/backward "Y" input should be driven based on the average of the two encoder values, and the left/right "Z" input should be driven based on their difference. It *might* work to do tank drive with each side of the robot being controlled independently, but I think it makes sense to think of the position and direction as separate measured values. In that case, you won't be driving the motors directly from the output of the PID computation. You'll be providing simulated joystick input to drive the robot back into place when it gets disturbed.

Will this be happening only while the robot is in autonomous mode, or will there be some way of selecting it to "hold position" during teleoperated mode?

vigneshv
27-01-2014, 16:00
It would be for autonomous and a "hold position" control in teleop

Alan Anderson
27-01-2014, 16:22
Joe Ross posted a link to a previous discussion of the sort of thing you want to do, along with some information about how to make it work for drive motors.

gpetilli
27-01-2014, 16:52
I question whether velocity PID based on rate feedback from drivetrain gearbox encoders will allow the bot to re-establish its orientation (or even position) after an impact.




We got our velocity loops working this past Saturday (after finally solving a problem with I2C comm to different sensors in independent timed threads corrupting data). The robot clearly actively resisted any movement. When forcibly kicked two feet out of place, I was surprised but the robot actively returned to the original position and orientation . I have not had time to investigate, but I think the PID is integrating the velocity error correction (any velocity is error with a zero commanded velocity) and then "de-integrating" the error. It may also be the loop is too slow, and just happened to stop correcting the velocity error such that it landed back at the starting location.
For our application, returning was not desired behavior. We plan on adding more D term on Tuesday to see if we can limit the "integrator windup".

That all said, I agree that for the stated problem a position loop would be adequate, easier to implement and probably preferred.

vigneshv
27-01-2014, 17:03
Thank you everyone

ekapalka
30-01-2014, 19:51
The robot clearly actively resisted any movement. When forcibly kicked two feet out of place, I was surprised but the robot actively returned to the original position and orientation . I have not had time to investigate, but I think the PID is integrating the velocity error correction (any velocity is error with a zero commanded velocity) and then "de-integrating" the error.Wow... that sounds amazing. Was this just using the simple WPILib PID classes or was it something else entirely? We've been looking into using closed loop control on our robot this year (we haven't ever in the past) and were thinking a "stay in place" button would be a cool [possibly unnecessary] thing to do for learning purposes (our robot is relatively simple).

gpetilli
31-01-2014, 13:53
Wow... that sounds amazing. Was this just using the simple WPILib PID classes or was it something else entirely? We've been looking into using closed loop control on our robot this year (we haven't ever in the past) and were thinking a "stay in place" button would be a cool [possibly unnecessary] thing to do for learning purposes (our robot is relatively simple).

Yesterday we increased the D term and the robot resisted movement more vehemently and only returned about 1in when kicked 1 foot - which is closer to our desired behavior.

As a point of clarification, we are not using encoders on the gearboxes - we have small, undriven follower omni-wheels with encoders to feedback velocity to the PID on the cRIO. This means that if the driven wheels lose traction while being pushed (or we spin wheels during hard acceleration) the PID still detects and tries to correct the movement. The closed loop PID "set point" is the driver commanded velocity. We do not have a "stay in place" special case, the PID is trying to drive to commanded zero velocity.

The WPI PID could potentially do this, but we implemented custom PID because we are using a holonomic drive (modified Killough) where the four driven omni-wheels are at a 30deg angle and we want the driver commands to be Cartesian. We measure the three degrees of freedom (X, Y, Rotation) and derive the four motor voltages.

gpetilli
31-01-2014, 13:55
I question whether velocity PID based on rate feedback from drivetrain gearbox encoders will allow the bot to re-establish its orientation (or even position) after an impact.




encoders are on follower omni-wheels so they do detect the translation even if the driven wheels slip.

Ether
31-01-2014, 14:36
It is a 6 wheel tank drive with the encoders on the gearbox. It just matters if the gears on either the left or right gearbox turn. Thanks!

If you have left and right velocity PID loops to your gearbox encoders, it should allow the robot to old it's ground since any movement will be an error verses the commanded zero velocity.

I question whether velocity PID based on rate feedback from drivetrain gearbox encoders will allow the bot to re-establish its orientation (or even position) after an impact.

We got our velocity loops working this past Saturday... The robot clearly actively resisted any movement. When forcibly kicked two feet out of place, I was surprised but the robot actively returned to the original position and orientation

As a point of clarification, we are not using encoders on the gearboxes - we have small, undriven follower omni-wheels with encoders to feedback velocity to the PID on the cRIO. This means that if the driven wheels lose traction while being pushed (or we spin wheels during hard acceleration) the PID still detects and tries to correct the movement... we are using a holonomic drive (modified Killough)

Well that's a horse of a different color.