While Loïc and Bertrand were working on Friday’s presentation slides, Samuel and myself spent the whole day testing our copter’s PID.
We finally found two majors bugs in our code (a motor offset unbalancing the system and a Integral term too often cleared). After that we were able for the first time to get a real flight while only acting on the thrust using remote control. We now have to add yaw PID and altitude PID and we may have something really nice to show on Friday.
Today, we went to the complex, a more spacious room than the one where we used to do our tests. The tests were quite conclusive. We were able to do some « landing » (the copter was caught by Axel near the floor because of turbulences caused by the proximity of this obstacle). With more power to the motors, we made the copter stay longer in the air, about 10/20 seconds (sadly, it wasn’t filmed).
We also used the remote to control the trust and the setpoint of the PID. It will need some software adjustments since it is still to brutal and rather hard to use.
Tomorrow, we’ll restore height control in our PID and see how much the copter drifts. This drift shall be corrected with the remote.
After having spent hours focusing on our PID into the Télécom ParisTech’s dancing room, we joined Télécom Robotic’s room in order to work on our implementation of Lucas and Kanade algorithm, because of a giant chessboard in green and red, perfect for image processing. We fixed Copterix in the air using some strings, and started test, with or without threshold, and it wasn’t really efficient…
We thought a moment about using ‘unfisheye’ opencv’s algorithm (see joined photo to understand why we wanted to use it), but it took 0.6 seconds per frame on our Gumstix…
What our camera actually sees: we can observe a 'fisheye' effect
Then we stopped and decided we should decide exactly how, even if it worked, Lucas and Kanade would help us to correct Copterix’s drift.
As we have 10 frames per second when processing the algorithm, it will be really difficult to determine in real time if we actually corrected the drift whenever we would want to correct it, and that is why we imagined the following algorithm:
wait for Copterix to be horizontal (pitch and yaw < epsilon)
take a reference picture and search the good features to track on it (quite heavy operation)
while Copterix is horizontal (pitch and yaw < epsilon)
____take a picture, compare it with reference
____if not horizontal (pitch and yaw >= epsilon)
______wait for Copterix to be horizontal (pitch and yaw < epsilon)
______go to 3.
____if drift is big enough (move size > threshold)
______go to 12.
____if we don’t find enough features to track
______go to 1.
ask PID to incline Copterix toward the good direction (we have to decide an angle)
wait a chosen time (we have to be over-precise on this data)
ask PID to set Copterix horizontal
go to 1.
The real difficulty of this algorithm is that it infers we do own a powerful and precise PID, able to remain horizontal most of the time, and to follow an order in the better and faster possible way, which is of course not true.
That is why we are now considering the fact that we may not have time to have a excellent PID AND implement such a precise algorithm; we will talk about it tomorrow with our teachers.
These last two days we mainly worked on tuning the PID coefficients to improve the stability. In this way, we tried to find the best set of PID coefficients so that RoseWheel could raise from an almost horizontal position and recover stability as soon as possible and then maintain this stability over time, even under hard external perturbation. We also worked on improving the coefficients we found for the human driving mode to make the right compromise between smooth-driving and responsiveness.
During this test and improve phase, Alexis advised us to plot the curve of the different values critical for our system. Thus, we plotted over time the value of the angle and the angle rate before and after the kalman filtering and also the command sent to the motor calculated by our PID algorithm.
It made us find 2 problems in our software that explains why at the beginning RoseWheel was so unstable:
The Kalman filter wasn’t configured correctly. We first configured it for the testbench but we forgot to change the time step that was indeed ten times smaller than the correct value. That led to latency and incorrectness in the output of the Kalman filtering. Changing this parameter to its correct value made the system become really more stable.
Even after the Kalman filtering, we noticed that the angular rate was still a lot noisy. This noise caused our gyropod to vibrate a lot when increasing the derivative coefficient Kd in the PID. That is a problem because increasing the derivative coefficient is the only way we have to lower the amplitudes of the oscillations induced by a big proportionnal term Kp in the PID. Thus, we decided to smooth the angular rate value by using a low-pass filter after the Kalman filtering. It’s really a simple filter as it’s only made of 2 coefficients, but according to the plots, it made its work correctly and the angular rate seems to be really smoother than before. But while testing, increasing the derivative coefficient still leads to oscillations and vibrations, so we still have to work on it.
As we obtained satisfying results at making RoseWheel maintain its equilibrium, we started working on other features :
We implemented the safety switch and elaborated a protocol to avoid as much dangerous situations as possible :
At the very beginning, when one presses the power on button, RoseWheel is in self-driving-mode by default. That means it will try to reach its equilibrium position as soon as possible and then remain in this position. We assume that the user isn’t too silly and, for instance, will not try to power on RoseWheel in an almost horizontal position whereas he is facing it. Then, as soon as the safety switch that is located on the base is pressed, that means that someone has its foot on RoseWheel and wants to ride it : RoseWheel switches to its human-drive mode. If suddenly the safety switch is released, RoseWheel checks the angle. If it’s almost 0°, that means that RoseWheel’s speed is almost 0 and the person maybe wants to get out, then calmly RoseWheel switches to its self-driven mode (we still need to implement it). If the angle is under 75°, that could means two things: the person has felt down or the person has temporarily raised its foot. Thus, if the safety switch isn’t pressed within 1 second, RoseWheel makes a special noise, then, if it’s still not switched on within another second, RoseWheel switch to its self-driven mode. Finally, if the angle is greater than 75°, that means that the person has felt down and RoseWheel could represent a menace for people around, motors are disabled.
2) Concerning the obstacle detection, we almost finished to implement the sharps and sonar drivers. As these detectors are really sensitive to the external conditions, we still have to test them and see how they react in the different environnements RoseWheel will evolve in.
3) Concerning the remote control, we almost finished to implement the drivers for the Bluetooth, we made some tests yesderday, but we still need to continue them today and we will talk more about it in the next article.
We can now control the attitude of our copter with the RF remote control. We have also implemented the possibility of turning on/off the motors directly with the RF remote control. Bertrand has made a script for running all the control tasks at boot. We can thus take control of our Copter as soon as the gumstix has started and is running Linux, without using any SSH connexion.
Then, we took the Copter outside for a first flight in real conditions. We succeed in taking off, but I wasn’t very comfortable with it. Then, we had a big crash: Bertrand accidentally put the thrust too high at the takeoff. The Copter overturned and damaged/broke some propellers. Fortunately, we put a protection onto the motors’ boards yesterday. They thus don’t seem to have suffered damages. Here are some photos after the crash. (Photos are from Samuel Tardieu)
the broken propeller... what a shame.
Crash of the 22th April, 2011
Tomorrow, we’ll try to improve our PID algorithm for pitch, yaw and roll, and then we’ll probably work on the Kanade algorithm, for X and Y control loop.
Tuesday evening, after nearly two days of fine-tuning our testing procedures and security measures, we finally did the first tests on our own vehicle. In order to make sure we didn’t damage the equipment (nor hurt somebody), we followed a simple and strict protocol:
1. First of all, we checked that we could control manually the motors via our interpreter;
2. Then, we verified that the limitations we applied to the variation of the voltage of each motor were adequate (as mentioned in a previous post, an abrupt increase or decrease on the voltage could severely damage the motors);
3. Finally, we determined a maximum speed that seemed reasonable, so that we could stop the vehicle manually should the worst happen.
After this initial procedure, we could start the actual tests of our system. After some iterations of tuning the coefficients of our controller, we realized that it was actually much easier to equilibrate the vehicle with a human being on top of it than without any load, since:
(i) the person enhances the performance of the control system by balancing his/her weight in a way that maximizes stability;
(ii) the presence of the human being makes the test conditions closer to the physical model we used to compute and simulate the parameters.
After several adjustments, we were able to take our first ride on the RoseWheel -- with basic steering capabilities via the integrated potentiometer implemented as a plus.
Nevertheless, by wednesday morning we had not yet found a way of balancing the RoseWheel alone -- a must for our next major goal, remote control. Then, we realized that the chassis we used had a very interesting property: by tilting it to a specific angle, we could align the center of gravity of the steering bar with the axis of the wheels, reaching a metastable equilibrium. We used this fact to offset the error variable of our PID controller, and that proved to be very effective, since we obtained as a result a pretty good stability. But all this comes at a price: since we now have two different equilibrium positions, we must use the safety button located on the chassis to determine if we are carrying a person or not; nothing too difficult to implement, though.
On the other hand, the PID coefficients may be trickier to master. We are still working on them to solve the issues we are having, notably oscillations and vibrations that sometimes occur. To help us with the debugging, we set up a solution to plot angle, angular velocity, and output voltage command for each one of the motors. Our next actions on this front will be to use all these data to better tune Kp, Ki and Kd, so as to have a more responsive and stable control algorithm.
Meanwhile, we started to move on to our next goals: we began to study the Bluetooth controller, and are already able to compile and run a « hello world » Android application. Next steps include implementing drivers for our distance sensors to implement obstacle detection.
To summarize all our work, we prepared a special video showing some of the most interesting (and/or funny) demos we made so far. Enjoy!
Today, our purpose was also to find the good values for the PID. At the beginning, the copter was very instable and oscillating. But after having changed the structure of the PID (before we had 6 values to configure, now we have only 3 coefficients), the impact of each coefficients was more easily to understand. The result seems good, but it will be better when we will have the camera and the Sharp (distance sensor). Here is a little video illustrating our breakthrough:
Today, we tried to set the coefficients of our PID algorithm. In order to do this, we used the Ziegler-Nichols method. The first step is to set the integral and the derivative gains to zero. Then, we increase the value of the proportional gain, to obtain the control loop oscillating constantly. Unfortunatly, we didn’t succeed in obtaining the special value of P (proportional gain). It seemed we had still some bugs on the Kalman filter. Samuel and Axel tested again the good working of the Kalman filter (we had to change some coefficients of the Kalman since we put the card on the Copter), and fixed it.
Samuel made a basic program, in order to change easily the PID coefficients, while the Copter is running : we can now observe the effects of the changes in live.
We worked also on some improvements of the code: for the STM32 and for the Kanade algorithm, to prepare the future work & debug. For example, the UART was configured at 1 000 000 bps, so the STM32 had only 72 instructions to perform between each UART interrupt. Since we only send 150 packets/s (~20 bytes), 57600 bps speed would be fine, and more convenient.
This week we tried to put together our developments and make them interact with each other. It includes sensors communication, kalman filter, control feedback, motors control, CAN communication protocol. We were dogged by bad luck as we realized the heatsink of our mainboard was too big to fit in the Zzaag… A few millimeters required us to order for a new one with a more suitable shape. Fortunately Alexis and Samuel helped us to find a new one. Because of that we were not able to validate the following « feedback control tuning » PSSC for Saturday as planned. Adviced by Samuel we also decided to postpone the « encoders drivers » PSSC as it wasn’t really in our first order priorities.
We tried to make profit of this situation and decided to prepare everything for the first tests. Alexis helped us defining our tests procedure to be as safe as possible for both hardware and people. Motors need special attention as they can be broken with unsuitable commands. Because of the wheels and the weight of the chassis they have a really high inertia. Asking them sharply to reverse their direction of rotation when they are rotating fast can seriously damage them and the H-bridges. If we damage them we wouldn’t be able to order new ones before the end of the course, it would be fatal for our project. Therefore we need at first to make some testing at low speed so as to define the maximum acceptable speed at which we can run the motors before they get damaged. To this extent we need an interpreter running on the mainboard and communicating using RS232 to be able to give motors various commands and define this maximum speed. Then we need to limit our commands to this maximum speed using software limitations. Finally the interpreter should be able to change the feedback control values for our testing to be more flexible. We implemented such an interpreter and made a video. The motors commands in the video are given between 0 and 1000 such as:
ml0 = 0%: max negative speed
ml500 = 50%: stop
ml1000 = 100%: max positive speed
Before trying the Zzaag motors we do some testings on other DC motors with less inertia that we cannot damage as easily as the Zzaag’s ones. Putting all the pieces together we were able to shoot a video which shows the motors reacting appropriately to the inclination of the sensorboard. As for the Kalman filter, we implemented a lighter version than the one of RoseWheel as it works best when tested on the real system. This version was only able to track the gyroscope drift and correct it. As far as we could see during the testing, it did it well. Concerning the PID, we tried to test the version that we are going to use in the RoseWheel but it still needs to be improved during the next tests.
Tomorrow we will be able to work on the Zzaag motors using our safe procedure and the tools developped. We look forward to it as it is a major step further for our project…
Today, I finalized the emission of the commands for the motors, from the Gumstix to the STM32 and their reception (check the validity of the packet and if it’s valid, update the commands sent to the motors).
Then, with Samuel, we added 0MQ exchanges on the Gumstix between Kalman and the PID and between the PID and the UART.
On the Gumstix, the program that handles the UART has two threads. One receives data from the sensors from the STM32 and sends it -thanks to 0MQ- to the program computing Kalman. The other one, receives the commands of the motors from the PID and sends them to the STM32.
We also attached the PCBs on the copter:
We configured Kalman with the new axes and the offset of roll and pitch angles.
Finally, we all tested the PID. The algorithm seems okay, however, we’ll have to set each coefficient properly.
We’re trying to control roll and pitch angles with a low thrust (in order to prevent any accident). Then, we’ll add a control on Z thanks to the Sharp sensor.