|
| 1 | +#!/usr/bin/env python3 |
| 2 | +# |
| 3 | +# Copyright (c) FIRST and other WPILib contributors. |
| 4 | +# Open Source Software; you can modify and/or share it under the terms of |
| 5 | +# the WPILib BSD license file in the root directory of this project. |
| 6 | +# |
| 7 | + |
| 8 | +import wpilib |
| 9 | +import wpilib.drive |
| 10 | +import wpimath.controller |
| 11 | +import wpimath.filter |
| 12 | + |
| 13 | + |
| 14 | +class MyRobot(wpilib.TimedRobot): |
| 15 | + """ |
| 16 | + This is a sample program to demonstrate the use of a PIDController with an ultrasonic sensor to |
| 17 | + reach and maintain a set distance from an object. |
| 18 | + """ |
| 19 | + |
| 20 | + # distance the robot wants to stay from an object |
| 21 | + # (one meter) |
| 22 | + kHoldDistanceMillimeters = 1.0e3 |
| 23 | + |
| 24 | + # proportional speed constant |
| 25 | + # negative because applying positive voltage will bring us closer to the target |
| 26 | + kP = -0.001 |
| 27 | + # integral speed constant |
| 28 | + kI = 0.0 |
| 29 | + # derivative speed constant |
| 30 | + kD = 0.0 |
| 31 | + |
| 32 | + kLeftMotorPort = 0 |
| 33 | + kRightMotorPort = 1 |
| 34 | + |
| 35 | + kUltrasonicPingPort = 0 |
| 36 | + kUltrasonicEchoPort = 1 |
| 37 | + |
| 38 | + def robotInit(self): |
| 39 | + # Ultrasonic sensors tend to be quite noisy and susceptible to sudden outliers, |
| 40 | + # so measurements are filtered with a 5-sample median filter |
| 41 | + self.filter = wpimath.filter.MedianFilter(5) |
| 42 | + |
| 43 | + self.ultrasonic = wpilib.Ultrasonic( |
| 44 | + self.kUltrasonicPingPort, self.kUltrasonicEchoPort |
| 45 | + ) |
| 46 | + self.leftMotor = wpilib.PWMSparkMax(self.kLeftMotorPort) |
| 47 | + self.rightMotor = wpilib.PWMSparkMax(self.kRightMotorPort) |
| 48 | + self.robotDrive = wpilib.drive.DifferentialDrive( |
| 49 | + self.leftMotor, self.rightMotor |
| 50 | + ) |
| 51 | + self.pidController = wpimath.controller.PIDController(self.kP, self.kI, self.kD) |
| 52 | + |
| 53 | + def autonomousInit(self): |
| 54 | + # Set setpoint of the pid controller |
| 55 | + self.pidController.setSetpoint(self.kHoldDistanceMillimeters) |
| 56 | + |
| 57 | + def autonomousPeriodic(self): |
| 58 | + measurement = self.ultrasonic.getRangeMM() |
| 59 | + filteredMeasurement = self.filter.calculate(measurement) |
| 60 | + pidOutput = self.pidController.calculate(filteredMeasurement) |
| 61 | + |
| 62 | + # disable input squaring -- PID output is linear |
| 63 | + self.robotDrive.arcadeDrive(pidOutput, 0, False) |
| 64 | + |
| 65 | + |
| 66 | +if __name__ == "__main__": |
| 67 | + wpilib.run(MyRobot) |
0 commit comments