User:Shatton8111/enes100/my work 3

Helicopter Project, Part 3

Write problem/project Goal
To create an Arduino-based quadcopter that flies itself without a remote control.

My First Task
I'm working on stabilizing the thrusts of the Hacker A10-13L motors on the seesaw apparatus.

Summary of actual work over first weekend
I managed to control the individual thrusts of the motors and show tuned reactions to changes in orientation. This involves the motors receiving control signals from the Thunderbird 9 ESC's, which are sent variable pulse widths from the Arduino Mega 2560. The Arduino runs behavior-controlling code that responds to filtered changes of orientation from the 5DOF SparkFun gyro-accelerometer sensor. The control code in the Arduino calculates response speeds for the individual motors using math based on complementary angles.

Week1 Narrative
In class, I've been focused on editing the behavior-controlling code that is in the Arduino. What is currently working is that one motor attempts to counteract forces on its side until the angle measured (by the Inertial Measurement Unit or 5DOF sensor) is within the definition of a level range. However, once this side's motor is done, the other responds exaggeratedly and doesn't stop until power is removed (in most cases).

I have yet to discover why one motor appears to behave appropriately while its complement is responds aggressively. There are several possibilities for why this is occurring. Problems with the IMU sensor's drift may be changing the definition of what is a stable and level position. After several tests, the calibrated "zenith" appears to shift from ~0.61 to ~0.18. Having a dirty electrical current supplied to the sensor may also induce drift. One motor may be more powerful than the other. They are the same model, but manufacturing methods aren't perfect. Because one motor is occasionally overheating, the "wear and tear" on it might reduce it to being very weak compared to the other motor.

However, despite these problems, it should be possible to account for the differences in thrusts. One possibility I've been told about is using a PID controller. While it would add more complexity and code to the program, if I'm able to understand and implement it successfully, it may resolve thrust balancing issue.

Counteracting the IMU sensor's drift shouldn't be difficult either. However, my attempts haven't worked so far. I've tried recording the initial filtered orientation readings and using them to offset the later readings for calibration. As I tried this, I discovered that such a method is futile since the Kalman filter in use calibrates the readings using multiple readings during the main "run loop" (the "loop" function) of the executing program. As such, it appears that either something else is the problem and the sensor is behaving properly or the calibration would need to watch for the readings to become stable during the run loop's execution (which would be tricky). Hopefully this drift problem is not the case, but I should be able to discover whether or not the problem exists once the PID controller is soundly balancing the seesaw. Erratic behavior across tests would most likely be caused by drift or power supply issues.

My Second Task
Unless I get to it today, I'm going to work on implementing PID controllers in order to control the balancing of the seesaw.

Summary of actual work over second weekend
I'm trying to redesign may "seesaw balancing code" to use PID controllers. The current PID controller implementation I'm using is the third-party PID library for the Arduino.

Week2 Narrative
I've added one PID controller to my code, and now a single side responds to counteract angles measured to be below a certain set point. One problem is that it responds very slowly. It's possible that this delay could be decreased by tuning the P, I, and D parameters to the feedback system. That will most likely be done manually or with an automatic tuning system.

I'm interested in adding the second motor to the system. I also need to redesign the code to clearly show and separate the parts involved in:


 * holding the desired input or control values for speed and angles,
 * ramping up the speeds of the motors gradually from zero to desired values,
 * introducing the corrective actions of the PID controllers,
 * keeping the produced values within safe and usable ranges, and finally...
 * giving the resulting speed values to the ESC's in order to change the motors' speeds.

To do this, I'm trying to design the conceptual outline for how the software would interact with other components. Here's the current idea:

Angle Sensor                                    Desired speed _______                                        (base speed)              Motor |      |                     Desired angle        _______                 (ESC) |      |                            |            |       |                  _  |_______|                            V            |       |                 | | PID Controller     |_______|               __|_|__ |                           ________             |                  |       |      |                           |        |            V                  |       | `> |        | -> + ---> |       |                                  |________|                               |_______|

This is how I'm thinking of redesigning the software to interact with different variables and parts:

Control Inputs Desired angle (X) base speed                                                      | X angle                                                         V  Y angle                                 Angle sensor ---> PID controller |                                                                  V                                 .---> + ---> ESC ---> Motor |                                |                           Desired angle (X) |                                |                                 |                                 V                                 |        Angle sensor ---> PID controller (reversed) |                                |                                 |                                 V                                 |---> + ---> ESC ---> Motor |                                |                           Desired angle (Y) |                                |                                 |                                 V Base speed ---> -|        Angle sensor ---> PID controller |                                |                                 |                                 V                                 |---> + ---> ESC ---> Motor |                                |                           Desired angle (Y) |                                |                                 |                                 V                                 |        Angle sensor ---> PID controller (reversed) |                                |                                 |                                 V                                 `---> + ---> ESC ---> Motor

As I test the code I currently have in simulation, I'm watching a single motor vary its output depending on how far above or below the horizon it is. When it is above the horizon, it slowly decreases its output down to the base speed, where it stays. When it's below the horizon, it gradually increases its speed until it reaches, and stays at, the maximum limit I set.

There are two problems I'm seeing. First, the delay between updates of the PID controller are fairly long. I think it will need to respond quicker for actual use. Second, once the PID controller's internal value is past one of the boundaries, it takes a very long time to reach it again. This is because it doesn't have internal limits (that I know about) and the delay is too long. I'm going to try tuning the values in order to have faster responses.

I tested some adjustments to the P, I, and D parameters. After testing through the Arduino editor's Serial Monitor with the full system (without power for the motors attached), I was able to find some tuning parameters that seemed to respond quickly enough for the seesaw to react quickly: 2, 100, 1; for P, I, and D, respectively.

From testing with the motor (with power), there seems to be a problem: the side that is being controlled is backwards. This leads to slightly confusing behavior. I'm going to try fixing it by setting the PID controller to be "reverse acting." This is done by changing the last initial parameter of the PID function from "DIRECT" to "REVERSE." For testing safely, I'm also going to change the P, I, and D values to 2, 10, and 1, respectively.

The test went relatively well. The motor turned on and spun. It wasn't really easy to tell if it was slowing down or speeding up. I'm going to retry with a servo "speed" of 65 instead of 70.

The test was the same, but the speed seemed slightly lower, based on the pitch of the sound. I'm going to retry with a speed of 60.

It seemed the same. One interesting thing is that when the Arduino starts the motors for the first time after being reprogrammed, it sets the motor to a very high speed. It's very dangerous, and annoying. I'm not sure why it does that. I'm trying again with a speed of 50.

From testing, I found out that the ESC attached to the motor on that side seems to only update its speed when power is first applied to it. That would mean that it becomes inoperable once the Arduino is attempting to update it. The difference between that and the other side is that it is missing the smaller 5 volt and grounding wires to the ESC. I'm going to try giving it those to see if it improves its responsiveness.

That did it. Now it works and is responsive to changes. Now I'm going to add the other side's motor with a "direct acting" (using the "DIRECT" parameter).

I simulated with only the Serial Monitor's output, and it looks good. I'm now trying with power. It works! It doesn't quite balance, but the seesaw is moving back and forth. I'm going to use PID values of 2, 20, & 1 to see if it will respond more quickly. I'm also going to use "somePID.SetSampleTime(15)" to make it update the controllers faster.

It didn't really help that much. I was able to almost balance it in my hands, but not on its own. I'm going to try it without the "safety boundaries" I had set up.

It didn't help much either. But, I did find out that it's basically fine to run the system without the limiters. Although, it might work better to limit within five or ten values of the desired range.

I looked through the ArduPilot Mega code and wiki for ideas. Eventually, I came across the wiki page for PID controller tuning. I found the explanations of PID control in the section "A bit more about PID loops" to be really helpful for understanding tuning. I tested in class today with P, I, and D values of 0.5, 0.5, and 1. The seesaw balances! Now I need to tune it to respond quickly and with little overcompensation, instead of slowly with a little wobbling.

Video: Slowly Balancing Seesaw

My Third task
Record what you are planning on doing for the team during the third weekend.

Summary of actual work over third weekend
How is what you did different than what you planned?

Week3 Narrative
I got the seesaw basically balancing, and then I decided to make the PID controller sample every millisecond instead of ever 15 milliseconds. That completely changed the behavior, making it respond much faster but with stronger motions. This meant that I had to adjust the tuning parameters again.

Here's the code at this point: TiltControl code

My Fourth task
''Record what you are planning on doing for the team during the final weekend of project work. ''

Summary of actual work over fourth weekend
How is what you did different than what you planned?

Week4 Narrative
I've been trying to balance the seesaw by experimenting with the PID parameters. I'm also experimenting with the sampling rates of the two PID controllers and the use of an initial "autotuning" system for finding tunings. Not much progress is being made unfortunately.

From talking to people about the current design, I think it would be good to try using a single PID controller per axis (controlling two motors). I've been worrying that having a single feedback loop for two motors of varying output will lead to instability, due to the different thrusts of the two motors. However, it might make sense, as temperature control systems appear to use a single feedback loop to control both the heating and cooling systems for buildings. I would suspect that each of these parts have varying output, just like the motors I'm using. I haven't researched or verified any of this, but I'll try using a single PID controller.

Complete Team Page
Fill out the Team Form (should have already copied the form, created the team page, linked to it and started filling it out).