Tuesday, September 15, 2015

Linux Experience

This Year I was very busy with developing Andruav.com an RC related android application. This September  2015 I finish 1 year working on it. It is a sophisticated app to develop, however I hope it is alot easier to be used.

I have been a Windows developer for more than +15 years, a C++ anti-java person. Well I regret that, I do love windows, however Java is a very nice language, especially when it comes to Android. Also Linux is an excellent platform that I was away from. Now my Laptop is Ubuntu :)

Anyway when I was looking for an inexpensive server for Andruav.com I had to go to Linux, at first I thought buying a VPS Ubuntu means a remote desktop with GUI, but I found my self lonely in front of back screen and all I have is ssh to connect :(.  That was horrible at the beginning, but later I was very comfort with it. I had to go through alot of issues that I will summaries here for other people who want to use Linux easily.


The platform I use is Ubuntu 12.04


Steps of installing LAMP on Ubuntu 14.04


1. Install Apache

sudo apt-get install apache2

2. Install MySQL

sudo apt-get install mysql-server
* reconfig
/usr/sbin/dpkg-reconfigure: mysql-server-5.5

3. Install PHP

sudo apt-get install php5 libapache2-mod-php5

4. Restart Server

sudo /etc/init.d/apache2 restart

5. Check Apache

http://localhost/.



7. Installing MySQLAdmin

apt-get install php5-mysql http://www.thetechrepo.com/main-articles/488.html
sudo apt-get install phpmyadmin

*reconfig phpmyadmin database:
sudo dpkg-reconfigure phpmyadmin

Add extension=mysqli.so (near other 'extension=' lines) line to your php.ini


8. Restart Server

sudo /etc/init.d/apache2 restart


If you execute these commands in order you will have LAMP on your Ubuntu


A Python Experiment in Gyro Calibration & Drift Cancelling






This article is to share my findings in gyro calibration. I tried to make a python script that uses data comes from mobile phone [S5 that has 6050 IMU]. It was a good chance to write simple code and visualize results much easier than doing so on Arduino with IMU 6050 attached. But still the concept is the same.
I used this mobile app, this is not the only one, so you can choose other if you want.

I used three approaches for Gyro calibration.
First Approach:
This is the normal approach where you read values from Gyro and then divide total by number of reads. This is the average value. Almost all quadcopter firmwares do this step before arming to make sure that the value that is read from gyro represents zero rad/s i.e. no rotations.
gyro from value will be:
     Gyro = (gyro_raw - gyro_avg ) * timediff
      where gyro_avg is the average measured by reading a sample values and divide over count.
There is nothing wrong in above approach, it is simple, and really can make your quad flies. 
Second Approach:
The second approach was almost the same, but in this trial, I took values from First averaging algorithm as a first guess,  then I ran an inner loop that tries to get error based on the original average, and tries to add correction to it.
gyro of value will be:
      Gyro = (gyro_raw - gyro_avg_dyn) * timediff
      where gyro_avg_dyn: is the best average with least error.
I find this is a equivalent of running the first approach method multiple time and try to get the best average with least error. It could be smarter than blindly get an average after n counts -first method- where you can test some values in between. This also may be more useful when using integers rather than decimal in 8-bit chips.
Third Approach:
This approach was a bit different. It assumes that original average will give zero error for the noise, however drift will still occur, and it is in one direction. So if you integrate values from gyro it will keep either increasing or decreasing in one direction -as an overall behaviour-. 
The idea was to try to read the rate of which drift occurs and store it in a value called Gyro_AvrDriftRate. The unit of this value will be rad/sec^2.
So the Value of Gyro will be:    

      Gyro = (gyro_raw - gyro_avg - (gyro_avgdriftrate * timediff) ) * timediff
     
       where gyro_avg is the average measured by reading a sample values and divide over count.
      and gyro_avgdriftrate is drift rate per second

Drift already affects the original average value, as gyro_raw is not random values with normal distribution around an offset value; as it has drift component inside. and so the original average has a skew from the zero offset. In the third approach the drift will appear clearly in the integration of readings and using time-difference one can estimate a rate for the drift.

Actual Results:

Script Logic:
     1- calculate average and drift using the three methods.

    
 2- while loop:
              a. read gyro_raw
              b. calculate gyro_value_method1,2,3

              c. integrate these values into three different variables gyro_x1_int, gyro_x3_int, gyro_x3_int

              d. print result
The best approach should have the least absolute value i.e. the nearest to zero.

Results:

I ran the code several times, the result is not the same every time. but in general the third method is promising, as in
many cases it gives less drift than the other methods.

the third method is the one has x_rad/s2 label.
Also the second method sometimes get stuck in local minimum, as it reads less values in the inner loop, and sometimes get worst that normal average. 
This is not always the case. Anyway I hope this could be a small start for others to make much more investigation.

Note: sometimes values sent from mobile jumps in crazy way without movements, so I just added a skip statement to skip those values, and I assume you run this script while leaving your mobile with no movement at all.
imu_gyroCalibration.py

Latest Code version is available at this link