Changes between Version 39 and Version 40 of ControlSystems/SoftwareTeam/Training/GettingStarted/IntroRobotJava


Ignore:
Timestamp:
Oct 30, 2019, 10:39:19 PM (6 years ago)
Author:
David Albert
Comment:

--

Legend:

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

    v39 v40  
    1212* [wiki://ControlSystems/SoftwareTeam/Training/GettingStarted/Autonomous Autonomous]
    1313* [wiki://ControlSystems/SoftwareTeam/Training/GettingStarted/ClosedLoopControl Closed Loop Control]
    14 
    15 
    16 
    17 
    18 == Seventh program: Closed Loop Control
    19 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. 
    20 
    21 MODIFY the last program as follows:
    22 
    23 * Add the following imports:
    24 {{{
    25   import edu.wpi.first.wpilibj.Timer;
    26 }}}
    27 
    28 *  Add variables for closed loop control in the Robot class
    29   {{{
    30     private double  leftPower, rightPower;
    31     private Timer   autoTimer;
    32     private boolean autoDone;
    33   }}}
    34 
    35 *  In robotInit() instantiate the new Timer object
    36   {{{
    37     autoTimer = new Timer();
    38   }}}
    39 
    40 * In robotPeriodic() add the motor power settings to the smart dashboard
    41   {{{
    42     SmartDashboard.putNumber("Left power", leftPower);
    43     SmartDashboard.putNumber("Right power", rightPower);
    44   }}}
    45 
    46 * In autonomousInit() initialize the motor powers and start the timer we created
    47   so we can periodically adjust the motor power to keep the robot going straight:
    48   {{{
    49     // start motors turning forward at 20% power
    50     leftPower = 0.20;
    51     leftMotor.set(leftPower);
    52     // to go forward, left motor turns clockwise, right motor counter-clockwise
    53     rightPower = -0.20;
    54     rightMotor.set(rightPower);
    55 
    56     autoTimer.start();
    57     autoDone = false;
    58   }}}
    59 
    60 * In the default section of autonomousPeriodic() periodically adjust the motor powers
    61   and stop if we've gone the desired distance.
    62   {{{
    63        if (!autoDone) {
    64           // adjust motor power every 1/4 second to keep us going straight
    65           if (autoTimer.hasPeriodPassed(0.25)) {
    66             // if we're going straight, leftDistance == rightDistance
    67             // otherwise, compute the error and adjust the motor powers to minimize it
    68             double error = leftEncoder.getDistance() - rightEncoder.getDistance();
    69             double kP = 0.01; // proportion of error used to correct motor power
    70             // adjust motor power to try to keep left/right distances same
    71             leftPower  -= kP*error; // positive error means left is going too fast
    72             rightPower -= kP*error; // right motor spins opposite direction of left
    73             leftMotor.set(leftPower);
    74             rightMotor.set(rightPower);
    75           }
    76           if ((leftEncoder.getDistance() > 36.0) ||
    77               (rightEncoder.getDistance() > 36.0)) {
    78               leftMotor.stopMotor();
    79               rightMotor.stopMotor();
    80               autoDone = true;
    81           }
    82        }
    83    }}}
    84 
    85 This 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.
    86 
    87 Notice that there are two critical values in this control loop:
    88   * How often the control loop runs (every 0.25 seconds in the above example)
    89   * How much the control loop adjusts the power based on the sensed inputs (kP=0.01 in the above example)
    90   * Try printing the error and adjusted motor powers using System.out.println(...) to see what adjustments are taking place.
    91 Try experimenting with these values (carefully and changing them a little at a time) to see what effect they have.  Be prepared to hit the Disable button or space bar when testing!
    92 
    9314
    9415== Study some examples