Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <Math.h>
- #include <Wire.h>
- #include <LSM303.h>
- #include <L3G.h>
- /*
- L3G - gyro
- The sensor outputs provided by the library are the raw 16-bit values
- obtained by concatenating the 8-bit high and low gyro data registers.
- They can be converted to units of dps (degrees per second) using the
- conversion factors specified in the datasheet for your particular
- device and full scale setting (gain).
- Example: An L3GD20H gives a gyro X axis reading of 345 with its
- default full scale setting of +/- 245 dps. The So specification
- in the L3GD20H datasheet (page 10) states a conversion factor of 8.75
- mdps/LSB (least significant bit) at this FS setting, so the raw
- reading of 345 corresponds to 345 * 8.75 = 3020 mdps = 3.02 dps.
- */
- /*
- LSM303D Magnetometer
- The sensor outputs provided by the library are the raw 16-bit values
- obtained by concatenating the 8-bit high and low accelerometer and
- magnetometer data registers. They can be converted to units of g and
- gauss using the conversion factors specified in the datasheet for your
- particular device and full scale setting (gain).
- Example: An LSM303D gives a magnetometer X axis reading of 1982 with
- its default full scale setting of +/- 4 gauss. The M_GN specification
- in the LSM303D datasheet (page 10) states a conversion factor of 0.160
- mgauss/LSB (least significant bit) at this FS setting, so the raw
- reading of -1982 corresponds to 1982 * 0.160 = 317.1 mgauss =
- 0.3171 gauss.
- LSM303DLH - akcelerometer
- In the LSM303DLHC, LSM303DLM, and LSM303DLH, the acceleration data
- registers actually contain a left-aligned 12-bit number, so the lowest
- 4 bits are always 0, and the values should be shifted right by 4 bits
- (divided by 16) to be consistent with the conversion factors specified
- in the datasheets.
- Example: An LSM303DLH gives an accelerometer Z axis reading of -16144
- with its default full scale setting of +/- 2 g. Dropping the lowest 4
- bits gives a 12-bit raw value of -1009. The LA_So specification in the
- LSM303DLH datasheet (page 11) states a conversion factor of 1 mg/digit
- at this FS setting, so the value of -1009 corresponds to -1009 * 1 =
- 1009 mg = 1.009 g.
- */
- L3G gyro;
- LSM303 compass;
- char report[120];
- struct AccelRotation {
- double pitch;
- double roll;
- double yaw;
- };
- struct Rotation{
- float pitch;
- float roll;
- float yaw;
- float hding;
- };
- void setup()
- {
- Serial.begin(9600);
- Wire.begin();
- compass.init();
- compass.enableDefault();
- if (!gyro.init())
- {
- Serial.println("Failed to autodetect gyro type!");
- while (1);
- }
- gyro.enableDefault();
- }
- /*
- * Deklaracie premennych
- */
- int indexPreZrychlenie=0;
- int vzorkovanie=50;
- float g=9.80665;
- float gx=0,gy=0,gz=0;
- float rychlostX=0, rychlostY=0, rychlostZ=0;
- float rychlost;
- float priemerneZrychlenieX=0, priemerneZrychlenieY=0, priemerneZrychlenieZ=0;
- float akceleraciaX, akceleraciaY, akceleraciaZ;
- float heading1, heading2, yaw, yawU;
- float gyroX, gyroY, gyroZ;
- float akceX, akceY, akceZ;
- float magX, magY, magZ;
- float pi= 3.14159;
- float Xh, Yh;
- float clearAccelX=0,clearAccelY=0,clearAccelZ=0;
- //Rotation rotat;
- AccelRotation rot;
- /*int xMagnetMax=0, yMagnetMax=0, zMagnetMax=2;
- int xMagnetMin=10000, yMagnetMin=10000, zMagnetMin=10000;
- float xMagnetMap=0,yMagnetMap=0,zMagnetMap=0;*/
- float heading;
- /*
- * Funkcia sluzi na vypocitanie azimutu - potrebujeme ho na urcenie smeru pohybu
- */
- void readFromSenzors(){
- compass.read();
- gyro.read();
- //Prepocet raw dat z gyro na DBS - degrees by second
- gyroX=(gyro.g.x*8.75/1000); //roll
- gyroY=(gyro.g.y*8.75/1000); //yaw,
- gyroZ=(gyro.g.z*8.75/1000); //pitch, naklananie do stran
- //prepocet raw dat z akcelerometra na G
- akceX=(compass.a.x>>4)*0.001;
- akceY=(compass.a.y>>4)*0.001;
- akceZ=(compass.a.z>>4)*0.001;
- //prepocet raw dat z magnetometra na mgauss
- magX=(compass.m.x*0.160);
- magY=(compass.m.y*0.160);
- magZ=(compass.m.z*0.160);
- }
- /*
- * Funkcia sluzi na vypocitanie Roll, Pitch, Yaw, Heading. Vypocitava azimuth ale treba dorobit tretiu os, respektive naklonenie osi.
- *
- *
- */
- void noGravity(){
- gx=g*sin(rot.pitch);
- gy=g*sin(rot.roll);
- //float az=ax*sin(rot.pitch)+ay*sin(rot.roll);
- //float az2=sqrt((akceleraciaZ*akceleraciaZ)+(akceleraciaX*akceleraciaX)+(akceleraciaY*akceleraciaY));
- //double az=g*(sin(rot.roll)-sin(rot.pitch));
- gz=sqrt((g*g)-(gx*gx)-(gy*gy));
- if (akceleraciaZ<0)
- {
- gz=gz*(-1);
- }
- // float az2=sqrt(10.25*cos(rot.pitch)+10.25*cos(rot.roll));
- clearAccelX=akceleraciaX-gx;
- clearAccelY=akceleraciaY-gy;
- clearAccelZ=akceleraciaZ-gz;
- }
- void nastavPriemZrych(){
- indexPreZrychlenie=0;
- priemerneZrychlenieX=0;
- priemerneZrychlenieY=0;
- priemerneZrychlenieZ=0;
- };
- void priemerneZrychlenie(){
- priemerneZrychlenieX+=clearAccelX; //Pridavame 10x zrychlenie a potom ho delime 10
- priemerneZrychlenieY+=clearAccelY;
- priemerneZrychlenieZ+=clearAccelZ;
- indexPreZrychlenie++;
- if (indexPreZrychlenie==10){
- priemerneZrychlenieX/=10;
- priemerneZrychlenieY/=10;
- priemerneZrychlenieZ/=10;
- pocitajRychlost();
- nastavPriemZrych();
- }
- };
- void pocitajRychlost(){
- rychlostX+=priemerneZrychlenieX*1; //v=a*t , cas mam 1 pretoze pridavam rychlost len kazdu sekundu
- rychlostY+=priemerneZrychlenieY*1;
- rychlostZ+=priemerneZrychlenieZ*1;
- // rychlost=sqrt((rychlostX^2)+(rychlostY^2)+(rychlostZ^2));
- };
- void pocitajZrychlenie(){
- akceleraciaX=akceX*g; //akceleracia v m.s-1 pre kazdu os
- akceleraciaY=akceY*g;
- akceleraciaZ=akceZ*g;
- }
- void vypocitaj(){
- //POCITANIE HEADING
- /* Pocitat Roll, pitch a YAW sa neda s raw datami - hadze blbe udaje
- rotat.pitch = (atan2(compass.a.x,sqrt((compass.a.y)^2+(compass.a.z)^2))*180.0)/pi;
- rotat.roll = (atan2(compass.a.y,sqrt((compass.a.x)^2+(compass.a.z)^2))*180.0)/pi;
- //rotat.yaw= atan2( (-compass.m.y*cos(rotat.roll) + compass.m.z*sin(rotat.roll) ) , compass.m.x*cos(rotat.pitch) + compass.m.z*sin(rotat.pitch)*sin(rotat.roll)+ compass.m.z*sin(rotat.pitch)*cos(rotat.roll)) *180/PI;
- float XXH = (compass.m.x*cos(rotat.pitch))+(compass.m.z*sin(rotat.pitch));
- if (XXH>360){
- XXH=XXH-360;
- }
- float YYH = (compass.m.x*sin(rotat.roll)*sin(rotat.pitch))+((compass.m.y*cos(rotat.roll))-(compass.m.z*sin(rotat.roll)*cos(rotat.pitch)));
- if (YYH>360){
- YYH=YYH-360;
- }
- */
- /*rot.pitch = (atan2(akceX,sqrt(akceY*akceY+akceZ*akceZ))*180.0)/pi;
- rot.roll = (atan2(akceY,sqrt(akceX*akceX+akceZ*akceZ))*180.0)/pi;*/
- rot.pitch = (atan2(akceX,sqrt(akceY*akceY+akceZ*akceZ))); //v radianoch
- rot.roll = (atan2(akceY,sqrt(akceX*akceX+akceZ*akceZ))); //v radianoch
- rot.yaw=atan2( (magZ*sin(rot.roll)-magY*cos(rot.roll) ) , (magX*cos(rot.pitch) + magY*sin(rot.pitch)*sin(rot.roll))+ (magZ*sin(rot.pitch)*cos(rot.roll)));
- Xh = magX*cos(rot.pitch)+magZ*sin(rot.pitch);
- if (Xh>360){
- Xh=Xh-360;
- }
- Yh = magX*sin(rot.roll)*sin(rot.pitch)+magY*cos(rot.roll)-magZ*sin(rot.roll)*cos(rot.pitch);
- if (Yh>360){
- Yh=Yh-360;
- }
- /*
- Heading = vychylenie v stupnoch od magnetickeho severu = nas smmer ktory potrebujeme, pouzivame len osi X a Y kedze nepotrebujeme vidiet zdvih
- if (heading<0) - normalizujeme vystup ak by boli zaporne hodnoty tak ich dame do kladnych
- Heading arctan(Y / X )
- Xh = Xm cos Pitch + Zm sin Pitch
- Yh = Xm sinRoll sinPitch + YmcosRoll - Zm sinRoll cos Pitch
- */
- heading2 = (atan2(Yh,Xh) * 180) / pi; //problem solved - roll a pitch musia byt v radianoch
- if (heading2 < 0){
- heading2 = 360+heading2;
- }
- //heading = compass.heading(); original compass heading, neda sa ale zmenit os X,Y,Z - potrebujeme aby kompas fungoval aj pri zmene osí
- /*heading1 = (atan2(magY,magX) * 180) / pi; //problem s tretou osou resp. naklonenim device
- if (heading1 < 0){
- heading1 = 360+heading1;
- }*/
- }
- void vypis(){
- /*
- * RAW hodnoty
- * snprintf(report, sizeof(report), "A: %6d %6d %6d M: %6d %6d %6d G: %6d %6d %6d",
- compass.a.x, compass.a.y, compass.a.z,
- compass.m.x, compass.m.y, compass.m.z,
- gyro.g.x, gyro.g.y, gyro.g.z);
- Serial.println(report);*/
- //Serial.println(rot.roll);
- //Serial.println(rot.pitch);
- //Gyroskop
- //Serial.print("Gyroskop: "); Serial.print(gyroX); Serial.print(" "); Serial.print(gyroY); Serial.print(" "); Serial.print(gyroZ); Serial.println(" ");
- //Akcelerometer
- //Serial.print("Roll: "); Serial.print(rot.roll); Serial.print("Pitch: "); Serial.print(rot.pitch); Serial.print("Yaw: "); Serial.println(rot.yaw);
- /*Serial.print("Roll2: "); Serial.print(rotat.roll); Serial.print("Pitch2: "); Serial.println(rotat.pitch); */
- //Serial.print("Akcelerometer: "); Serial.print(akceX); Serial.print(" "); Serial.print(akceY); Serial.print(" "); Serial.print(akceZ); Serial.println(" ");
- //Magnetometer
- //Serial.print("Magnetometer: "); Serial.print(magX); Serial.print(" "); Serial.print(magY); Serial.print(" "); Serial.print(magZ); Serial.print(" ");
- //Serial.println(rychlost);
- Serial.print(rot.pitch); Serial.print(";");Serial.print(rot.roll); Serial.print(";");
- Serial.print(clearAccelX); Serial.print(";"); Serial.print(clearAccelY); Serial.print(";"); Serial.println(clearAccelZ);
- /*
- * Vypocitane zlozky gravitacneho zrychlenia
- */
- //Serial.print(gx); Serial.print(" "); Serial.print(gy); Serial.print(" ");Serial.print(gz); Serial.print(" ");// Serial.print(gz2); Serial.print(" ");
- /*
- * Merana akceleracia
- */
- //Serial.print(" Merane "); Serial.print(akceleraciaX); Serial.print(" "); Serial.print(akceleraciaY); Serial.print(" "); Serial.print(akceleraciaZ);
- /*
- * Uhly naklonu - roll + pitch
- */
- //Serial.print(" Uhly "); Serial.print(rot.roll); Serial.print(" "); Serial.println(rot.pitch);
- /*
- * Rozdiely medzi meranou a vypocitanou akceleraciou - pouzivame iba s pokojnom stave na zistenie rozdielov - nepresnosti
- */
- // Serial.print(" Rozdiely "); Serial.print(clearAccelX); Serial.print(" "); Serial.print(clearAccelY); Serial.print(" "); Serial.print(clearAccelZ);
- /*
- * Poloha v zavislosti od severu
- */
- //Serial.print("Heading: "); Serial.print(heading); Serial.print("Heading1: "); Serial.println(heading2);
- /*
- * Rychlost na X,Y,Z osi
- */
- // Serial.print(" Rychlosti "); Serial.print(rychlostX); Serial.print(" "); Serial.print(rychlostY); Serial.print(" "); Serial.println(rychlostZ);
- //Serial.print("Heading: "); Serial.print(heading1); Serial.print(" Roll "); Serial.print(rot.roll); Serial.print(" Pitch "); Serial.print(rot.pitch); Serial.print("\n");
- //Serial.print("Heading1: "); Serial.print(heading1); Serial.print(" Heading2: "); Serial.println(heading2);
- //Serial.print(" magX: "); Serial.print(magX); Serial.print(" magY: "); Serial.print(magY); Serial.print(" Xh: "); Serial.print(Xh); Serial.print(" Yh: "); Serial.println(Yh);
- }
- void loop()
- {
- readFromSenzors();
- vypocitaj();
- pocitajZrychlenie();
- priemerneZrychlenie();
- pocitajRychlost();
- noGravity();
- vypis();
- /*if (indexPreZrychlenie==10){
- nastavPriemZrych();
- }*/
- delay(vzorkovanie);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement