Modified 2020-09-03 by Rara Ma
Modified 2020-09-16 by Rachel Ma
In this part of the project, you will be implementing a PID controller for a simulated drone that can only move in one dimension, the vertical dimension. You can control the speed the motors spin on the drone, which sets the thrust being generated by the propellers. In this system, the process variable is the drone’s altitude, the setpoint is the desired altitude, and the error is the distance in meters between the setpoint and the drone’s altitude. The output of the control function is a PWM (pulse-width modulation) value between 1100 and 1900, which is sent to the flight controller to set the drone’s throttle.
To run the simulation, you need to use the vnc server. You can find the installation link here.
Run sudo vncserver
.
With bash, navigate to the file named drone_simulator, which is located within the scripts folder of pidrone_pkg-master folder.
You should implement the discretized version of the PID control function in student_pid_class.py:
Notice that there is an extra offset term added to the control function. This is the base PWM value/throttle command before the three control terms are applied to correct the error in the system.
To tune your PID, set the parameters () in z_pid.yaml.
To test your PID, run python sim.py
on your base station or a department computer but not on your drone, since it requires a graphical user interface to visualize the output. The PID class in student_pid_class.py will automatically be used to control the simulated drone. The up and down arrow keys will change the setpoint, and r resets the simulation.
You will need numpy, matplotlib, and yaml to run the simulation. To install these dependencies, run pip install numpy matplotlib pyyaml
.
Modified 2020-09-03 by Rara Ma
Exercises
Modified 2020-09-03 by Rara Ma
Now, we introduce latency! Run the simulation as python sim.py -l 6
to
introduce 24 milliseconds of latency (six steps of latency running at
25 hz).
Exercises
Modified 2020-09-03 by Rara Ma
In the most realistic mode, you will tune a controller with latency,
noise, and a drag coefficient. You can do this with the command line
arguments python sim.py -l 3 -n 0.5 -d 0.02
to be most realistic to
real-world flight.
Exercises
Run python sim.py -h
to see the other simulator parameters. We
encourage you to experiment with those and observe their
effects on your controller.
Modified 2020-09-03 by Rara Ma
In this portion of the project, you will be tuning the low rate integral terms of the PID controllers that we’ve provided.
Modified 2020-09-03 by Rara Ma
Due to differences in the weight distribution and other factors that cause asymmetries, the drone will tend to initially drift in a particular direction. In order to tune your altitude PID, the planar motion of the drone needs to be controlled. This is important so that the drone does not fly uncontrollably across the room while you’re trying to tune its altitude controller. To control the drone’s planar motion while you’re tuning the altitude, we’ve created and tuned PIDs to do this for you, but you will need to tune the initial low-rate integral terms to account for the uneven weight distribution specific to your drone. You will first use the provided altitude PID to tune the planar controllers, and then you will tune your altitude PID with the tuned planar controllers.
Write brief answers to all exercises in answers_pid.md.
Modified 2020-09-03 by Rara Ma
Our controller is a dual I-term (integral term) PID controller. The high-rate I-term changes quickly, allowing fast response to changes. The low-rate I-term changes slowly, allowing the drone to adjust to systemic sources of error. The provided PID gains have been pretuned to this drone hardware, and should not need significant modification for your specific drone. But, the initial low I-terms do need to be adjusted based on the static error of your specific drone.
Exercises
1. Name a source of static error that the low-rate I term can correct for.
2. Name two sources of dynamic error that the high-rate I term can correct for.
Modified 2020-09-03 by Rara Ma
The first step in the tuning process is finding an initial throttle value that allows your drone to have a smooth and controlled takeoff. To do this, you’ll be adjusting the value of throttle_low.init_i
in pid_class.py. This is the initial value of the low-rate (slow changing) integral term for the throttle, which controls altitude. The default value is 100. you will tune this value by having the drone take off, observing its behavior, and modifying the value accordingly. Each time you wish to change the value, you will need to restart pid_controller.py to use the new value.
Setup
1. Prepare your drone to fly over a highly textured planar surface1.
2. Navigate to `4 of the screen.
3. Quit the program by pressing ctrl-c.
Exercises
1. In this screen (`4), use a text editor (such as vim or nano) to modify throttle_low.init_i
in pid_class.py to test out different values for throttle_low.init_i
. Be cautious when modifying this value because the drone could take off abruptly with a value that is too high. The specific throttle_low.init_i
value is drone specific, but typical values range between 50 and 150. Try both of these values and two more values between then. In one sentence, describe the drone’s behavior as a result of changing the value up and down.
2. Now find the value for which your drone is able to have a smooth and controlled takeoff. The goal is to reduce the overshoot and undershoot for the drone to takeoff and fly stable at 0.3m. Try changing this value in increments of 10 and then 5 until you find a value that allows the drone to take off at a reasonable rate. Record this value in your answers.
Modified 2020-09-03 by Rara Ma
Next you will set the trim on roll and pitch. You will do this by tuning the low I-terms to adjust for the static errors that exist on your drone. The default value is 0, and positive values will move the drone to the right or forward, and negative to the left or backward, depending on the axis you’re modifying. Note that you may need to repeat this process periodically, for example after a crash or the like. When performing this process, each time make sure that you:
Setup
Modify pid_controller.py to print out the low rate integral terms of the PIDs by finding the block of code shown below and uncommenting the following print statements
print 'roll_low.init_i', pid_controller.pid.roll_low.init_i
print 'pitch_low.init_i', pid_controller.pid.pitch_low.init_i
You will also need to set the verbose
variable in this file to zero so that these print statements will not be overridden by the other print statements: verbose = 0
While flying, the low-rate I-terms will change to account for the static flight error, and when you disarm the drone, the initial low-rate I terms will be set to these changed values, thus allowing the low-rate I terms to start at this corrected value. Eventually, these values will converge, and your drone will no longer drift. Once converged, you will save the values by modifying the variables self.roll_low.init_i
and self.pitch_low.init_i
in pid_class.py
to the corresponding value printed in `4 of the screen after disarming. This will store the initial low-rate I-terms between flights.
Exercises
1A flat posterboard scribbled or written on with marker will work.
Modified 2020-09-03 by Rara Ma
In this part, you will be transferring the altitude PID you created in part 1 onto your drone. You will then tune the PID gains on your drone as you did in the simulator.
Modified 2020-09-16 by Rachel Ma
Now that the planar PIDs are tuned, and you have found a value for throttle_low.init_i
that allows the drone to take off at a reasonable rate, you will be using your altitude PID to control the height of the drone. To tune your altitude PID, you will first use the Ziegler-Nichols tuning method to generate an initial set of tuning parameters. You will then fine tune these parameters similar to how you tuned the drone in simulation.
To use your PID, you’ll be running student_pid_controller.py instead of pid_controller.py. This will allow your PID to run alongside our planar PIDs, and on top of our throttle low-rate I-term which you found previously. Your PID will be responsible for keeping the drone flying steady vertically.
Setup
Change directories to ~/ws/src
. Run git clone https://github.com/h2r/project-pid-yourGithubName.git
. In your repo, change “~/ws/
and run catkin_make --pkg project-pid-yourGitHubName
.
OR
Use the scp
command to transfer student_pid_class.py, student_pid_controller.py, and z_pid.yaml from the repo on your base station to the scripts folder of your drone (~/ws/src/pidrone_pkg/scripts/
). In the instructions below, instead of using rosrun
, you may use python
to execute your scripts.
Change directories into ~/ws/src/pidrone_pkg
and modify pi.screenrc to start up with your altitude pid by changing python pid_controller.py\n
to rosrun project-pid-yourGitHubName student_pid_controller.py\n
. Prepare your drone to fly and then navigate to `4 of the screen. Press ctrl-c to quit student_pid_controller.
In this screen (`4), modify ~/ws/src/project-pid-yourGitHubName/z_pid.yaml
by setting to 1250 and the rest of the gain constants to 0. Now run rosrun project-pid-yourGitHubName student_pid_controller.py
to fly with your altitude PID.
Exercises
Fly your drone and observe its flight. Tune by slowly increasing its value between flights until you can see the drone moving up and down with uniform oscillations. Each time you will need to quit the controller, edit ~/ws/src/project-pid-yourGitHubName/z_pid.yaml
, and then run rosrun project-pid-yourGitHubName student_pid_controller.py
again to use the new PID gains.
Take a video of your drone flying first using our altitude pid by running pid_controller.py in `4, then take a video of your tuned pid by running student_pid_controller.py in `4. See if you can get yours to track the altitude setpoint better than ours! The drone should get to the setpoint quickly and stay there without bouncing up and down.
2 Use the graph on the web interface to observe the drone’s behavior as it oscillates around the 0.3m setpoint the drone’s ability to hover at the setpoint. When observing the drone itself, try to get eye-level with the drone to just focus on the the altitude and ignore the planar motion; it is easier to focus on one axis at a time when tuning the PIDs. The planar axes can be re-tuned after you tune your altitude pid if need be.
Modified 2020-09-03 by Rara Ma
Thus far, the planar PIDs have been used to control the velocity of the drone; now, you will use cascaded PIDs to control the position of the drone. The cascaded PIDs are set up so that the position controller forms the outer loop which uses the position error to provide setpoint velocities for the inner loop velocity controller.
Modified 2020-09-03 by Rara Ma
Engaging position control involves two steps. First you have to tell the drone to “remember” a frame. You can do this using the r key. This will save the frame which the drone will attempt to fly directly above. Next you have to engage position control. You can engage this mode with the p key, and disengage with v for velocity control. So the procedure is to first save a frame (target location for position hold) using r and then shortly after (before drifting too much) type p.
Note: Position hold works best over a textured surface with lots of visual contrast. Even when doing position hold, always be ready to kill in case of a mishap. Especially be careful when looking at other windows.
Modified 2020-09-03 by Rara Ma
This video demonstrates the drone doing a zero velocity hover and drifting in the scene. Then we turn on position hold (you can tell when it is engaged when the drone’s throttle drops) and it holds its position for several minutes.
Then we turn off the position hold so you can see it drift again, and then turn it on again at the end and land. You can tell when it is turned on because we move the drone back to the center of the flight area before each hold.
Modified 2020-09-03 by Rara Ma
First, you are going to experiment with flying your drone in velocity control and controlling its motion with the keyboard keys. Based on observations and knowledge of the controllers, you will then explain the inner workings of the velocity PIDs in your own words.
Setup
Prepare your drone to fly over a highly textured planar surface. Make sure there is space for the drone to fly around.
Exercise
Fly your drone in velocity control (the default control) and make sure there is room to fly to the right. Press and hold ‘L’ and observe the drone’s motion, and release ‘L’ to stop the drone from moving.
Modified 2020-09-16 by Rachel Ma
Now you are going to fly your drone in position control and experiment with controlling its motion with the keyboard keys. Based on observations and knowledge of the controllers, you will then explain the inner workings of the position PIDs in your own words.
Setup
Prepare your drone to fly over a highly textured planar surface. Make sure there is space for the drone to fly around.
Exercises
1. Engage position hold using the procedure described above. Observe the drone’s behavior. How is it different from just velocity control?
2. How long are you able to hold position? Ideally you should be able to do this in one spot for an entire battery. If not, try re-tuning your I-term preloads above. If you’re flying on the power supply instead of a battery, the drone should stay in place indefinitely, but you can stop it after 5 minutes.
3. While flying in position control, make sure there is room for the drone to fly to the right and then take note of the desired position in `4 of the screen. Now press the ‘L’ key in the user interface and note the new desired x-position of the drone; it should be 0.1m to the right of the drone’s last position. Explain what the following key terms are in the outer loop position controller, and how they change to cause the drone to move and stop 0.1m to the right after you press ‘L’ in position control: setpoint, error, control variable, process variable, proportional term, integral term, derivative term. We are looking only for a higher level description to demonstrate understanding of cascaded PID controllers.
4. Try flying in position control over a uniform surface such as the floor in 121, or un-patterned carpet. Echo the state of the drone by typing rostopic echo /pidrone/state
into an empty window in the screen. Note the position data, and explain your observations of how well the drone is able to estimate its position. How long is it able to hold position? Does the drone move correctly when you use the arrow keys?
Take a one minute video of your drone flying in velocity control, and then engage position control.