Changes between Version 27 and Version 28 of ControlSystems/SoftwareTeam/Training/GettingStarted/IntroRobotJava


Ignore:
Timestamp:
Oct 29, 2019, 1:34:37 AM (6 years ago)
Author:
David Albert
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • ControlSystems/SoftwareTeam/Training/GettingStarted/IntroRobotJava

    v27 v28  
    267267
    268268== Seventh program: Closed Loop Control
    269 In the last example, we saw why robot programming is challenging: robots work in the real world where wheels slip, motors have different powers, wheels aren't inflated equally, and floors aren't perfectly level.  The robot didn't go straight and didn't stop at exactly 36".  What makes robots interesting and powerful is their ability to sense their environment and respond to it.  In the basic Autonomous example, one wheel was turning faster than the other so the robot turned.  Since the encoders were reporting this, we can modify our program to compensate.  The simplest way to do this is to proportionally increase the motor power of the wheel that's going slower.  Add the following to the autonomousPeriodic() method from the previous example:
    270 
    271 {{{
    272 
    273 }}}
     269In the last example, we saw why robot programming is challenging: robots work in the real world where wheels slip, motors have different powers, wheels aren't inflated equally, and floors aren't perfectly level.  The robot didn't go straight and didn't stop at exactly 36".  What makes robots interesting and powerful is their ability to sense their environment and respond to it.  In the basic Autonomous example, one wheel was turning faster than the other so the robot turned.  Since the encoders were reporting this, we can modify our program to compensate.  The simplest way to do this is to proportionally increase the motor power of the wheel that's going slower. 
     270
     271MODIFY the last program as follows:
     272
     273* Add the following imports:
     274{{{
     275  import edu.wpi.first.wpilibj.Timer;
     276}}}
     277
     278*  Add variables for closed loop control in the Robot class
     279  {{{
     280    private double  leftPower, rightPower;
     281    private Timer   autoTimer;
     282    private boolean autoDone;
     283  }}}
     284
     285*  In robotInit() instantiate the new Timer object
     286  {{{
     287    autoTimer = new Timer();
     288  }}}
     289
     290* In robotPeriodic() add the motor power settings to the smart dashboard
     291  {{{
     292    SmartDashboard.putNumber("Left power", leftPower);
     293    SmartDashboard.putNumber("Right power", rightPower);
     294  }}}
     295
     296* In autonomousInit() initialize the motor powers and start the timer we created
     297  so we can periodically adjust the motor power to keep the robot going straight:
     298  {{{
     299    // start motors turning forward at 20% power
     300    leftPower = 0.20;
     301    leftMotor.set(leftPower);
     302    // to go forward, left motor turns clockwise, right motor counter-clockwise
     303    rightPower = -0.20;
     304    rightMotor.set(rightPower);
     305
     306    autoTimer.start();
     307    autoDone = false;
     308  }}}
     309
     310* In the default section of autonomousPeriodic() periodically adjust the motor powers
     311  and stop if we've gone the desired distance.
     312  {{{
     313       if (!autoDone) {
     314          // update motor power every 1/4 second to keep us going straight
     315          if (autoTimer.hasPeriodPassed(0.25)) {
     316            // if we're going straight, leftDistance == rightDistance
     317            // otherwise, compute the error and adjust the motor powers to minimize it
     318            double error = leftEncoder.getDistance() - rightEncoder.getDistance();
     319            double kP = 0.01; // proportion of error used to correct motor power
     320            // adjust motor power to try to keep left/right distances same
     321            leftPower  -= kP*error; // positive error means left is going too fast
     322            rightPower -= kP*error; // right motor spins opposite direction of left
     323            leftMotor.set(leftPower);
     324            rightMotor.set(rightPower);
     325          }
     326          if ((leftEncoder.getDistance() > 36.0) ||
     327              (rightEncoder.getDistance() > 36.0)) {
     328              leftMotor.stopMotor();
     329              rightMotor.stopMotor();
     330              autoDone = true;
     331          }
     332       }
     333   }}}
     334
     335This is the simplest form of closed-loop control: we are sensing position information (left, right distances) and adjusting powers proportionally (kP) to try to minimize the error.  There are more sophisticated ways to do this that consider how quickly the robot is approaching its goal (derivative of error) and how long and how severely it has been off its target (integral of error).  The PID control loop uses all of these for more precise and responsive closed loop control.
    274336
    275337