root/core/gps.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. geodiff
  2. geo2rect
  3. rect2polar
  4. polar2rect
  5. radian2deg
  6. georegInit
  7. georegAdd
  8. georegActual
  9. georegChange
  10. lock
  11. unlock
  12. draw_txt_centered
  13. run_compass_task
  14. test_timezone
  15. load_bitmap
  16. draw_gps_course_info
  17. draw_compass_needle
  18. draw_compass
  19. show_sat_symbol_task
  20. gps_data_task
  21. tracking_icon_task
  22. no_signal_task
  23. gps_logging_task
  24. compass_display_task
  25. gps_waypoint
  26. gps_write_timezone
  27. gps_write_home
  28. init_gps_startup
  29. init_gps_logging_task
  30. init_gps_compass_task
  31. init_gps_navigate_to_home
  32. init_gps_navigate_to_photo

   1 
   2 #include "camera_info.h"
   3 #include "properties.h"
   4 #include "task.h"
   5 #include "modes.h"
   6 #include "debug_led.h"
   7 #include "shutdown.h"
   8 #include "sound.h"
   9 #include "backlight.h"
  10 #include "temperature.h"
  11 #include "file_counter.h"
  12 #include "gps.h"
  13 #include "gps_math.h"
  14 #include "time.h"
  15 
  16 #include "conf.h"
  17 #include "keyboard.h"
  18 #include "lang.h"
  19 #include "levent.h"
  20 #include "math.h"
  21 #include "gui.h"
  22 #include "gui_draw.h"
  23 #include "gui_batt.h"
  24 #include "gui_lang.h"
  25 #include "gui_mbox.h"
  26 
  27 // for testing on cameras without a GPS chip - add #define CAM_HAS_GPS 1 to their platform_camera.h file for the test
  28 //#define SIMULATED_GPS 1    
  29 #undef  SIMULATED_GPS 
  30 
  31 // gps task control
  32 
  33 static int gps_data_lock ;      // task running flags
  34 static int gps_show_lock;
  35 static int gps_record_lock;
  36 static int gps_track_lock;
  37 static int gps_compass_lock ;
  38 static int gps_nosignal_lock;    
  39 
  40 static int exit_data_task =0;  // request task to exit flags
  41 static int exit_show_task=0;
  42 static int exit_record_task=0;
  43 static int exit_track_task=0;
  44 static int exit_compass_task=0;
  45 static int exit_nosignal_task=0;
  46 
  47 //static data for gps task
  48 
  49 static int test_timezone_once=0;
  50 
  51 static char g_d_tim[10];
  52 static char g_d_dat[12];
  53 static char g_d_tim_gps[10];
  54 static char g_d_dat_gps[12];
  55 static int  g_d_stat;
  56 
  57 static double g_d_lat_nav=0.0;
  58 static double g_d_lon_nav=0.0;
  59 static double g_d_lat;
  60 static double g_d_lon;
  61 static double g_d_hei;
  62 
  63 static int time_to_end=0;
  64 
  65 static int navigation_mode=0;       // 0=none, 1=to image,  2=home
  66 
  67 static t_regression_xy buffer1[50];
  68 static t_regression_xy buffer2[50];
  69 static t_regression_xy buffer3[50];
  70 
  71 #define PI      (3.1415926535)
  72 #define RHO     (180.0/3.1415926535)
  73 #define EARTH   (40.e6/360.0)
  74 
  75 typedef struct {
  76     double lat_w;
  77     double lon_w;
  78 } t_geo;
  79 
  80 typedef struct {
  81     double north;
  82     double east;
  83 } t_rectangular;
  84 
  85 typedef struct {
  86     double delta;
  87     double alpha;   // radian
  88 } t_polar;
  89 
  90 static void
  91 geodiff (t_geo * von, t_geo* nach, t_geo* delta) {
  92     delta->lat_w = nach->lat_w - von->lat_w;
  93     delta->lon_w = nach->lon_w - von->lon_w;
  94 }
  95 
  96 static void
  97 geo2rect (t_geo * g, t_rectangular* r, double lat_w) {
  98     r->north= g->lat_w * EARTH;
  99     r->east = g->lon_w * EARTH * cos(lat_w/RHO);
 100 }
 101 
 102 static void
 103 rect2polar (t_rectangular* r, t_polar* p) {
 104     p->delta = sqrt (r->north*r->north + r->east*r->east);
 105     p->alpha = arctan2 (r->east, r->north);
 106 }
 107 
 108 #if 0
 109 static void
 110 polar2rect (t_rectangular* r, t_polar* p) {
 111     r->east = sin(p->alpha) * p->delta;
 112     r->north= cos(p->alpha) * p->delta;
 113 }
 114 #endif
 115 
 116 static int
 117 radian2deg (double alpha) {
 118     return (int) (alpha * RHO + 360.5) % 360;
 119 }
 120 
 121 typedef struct {
 122     t_regression lat_w;
 123     t_regression lon_w;
 124 } t_georeg;
 125 
 126 static void
 127 georegInit (t_georeg* reg, int size, t_regression_xy * buffer1, t_regression_xy * buffer2) {
 128     regressionInit (&reg->lat_w, size, buffer1);
 129     regressionInit (&reg->lon_w, size, buffer2);
 130 }
 131 
 132 static void
 133 georegAdd (t_georeg* reg, double time, t_geo* geo) {
 134     regressionAdd (&reg->lat_w, time, geo->lat_w);
 135     regressionAdd (&reg->lon_w, time, geo->lon_w);
 136 }
 137 
 138 static void
 139 georegActual (t_georeg* reg, t_geo* geo) {
 140     geo->lat_w = regressionActual (&reg->lat_w);
 141     geo->lon_w = regressionActual (&reg->lon_w);
 142 }
 143 
 144 static void
 145 georegChange (t_georeg* reg, t_geo* geo) {
 146     geo->lat_w = regressionChange (&reg->lat_w);
 147     geo->lon_w = regressionChange (&reg->lon_w);
 148 }
 149 
 150 static double now;                                     // seconds of day
 151 static t_geo gps;                                      // measured noisy position
 152 static t_georeg georeg;                                // regression for actual position
 153 static t_geo ist;                                      // actual position of regression
 154 static t_geo speed;                                    // actual position of regression in Grad/s
 155 static t_rectangular mspeed;                           // actual position of regressionin m/s (N/E)
 156 static t_polar pspeed;                                 // actual position of regression in m/s + angle
 157 static int direction;                                  // direction
 158 static t_geo soll;                                     // nominal position
 159 static t_geo delta;                                    // distance to destination(in Grad)
 160 static t_rectangular rdelta;                           // distance to destination (metric N/E)
 161 static t_polar pdelta;                                 // distance to destination (metric+english)
 162 static int peil;                                       // bearing to destination
 163 static int angle;                                      // angle on display from march to the target
 164 static t_regression deltareg;                          // heading and speed
 165 
 166 #ifdef SIMULATED_GPS
 167     #include "gps_simulate.c"  
 168 #endif
 169 
 170 //=======================================================================
 171 //
 172 //  Bakery algoritmn mutex lock / unlock
 173 //
 174 #define NUM_TASKS 6
 175 static volatile unsigned entering[NUM_TASKS] = { 0 };
 176 static volatile unsigned number[NUM_TASKS] = { 0 };
 177 
 178 void lock(int n_task) {
 179   int i ;
 180   unsigned max = 0;    
 181   entering[n_task] = 1;
 182   for (i = 0; i < NUM_TASKS; i++) {
 183     if (number[i] > max) max = number[i];
 184   }
 185   number[n_task] = max + 1 ;
 186   entering[n_task] = 0;
 187   for (i = 0; i < NUM_TASKS; i++) {
 188     if( i != n_task) {
 189         while ( entering[i] !=0 ) { msleep(50) ; }
 190         while ((number[i] != 0) && ( number[i] < number[n_task] || (number[i] == number[n_task] && i < n_task) )) { msleep(50);}
 191     }
 192   }
 193 }
 194  
 195 void unlock(int n_task)
 196 {
 197   number[n_task] = 0;
 198 }
 199  
 200 //=======================================================================
 201 //
 202 //  Helper functions - called from within running tasks
 203 //
 204 
 205 void draw_txt_centered(int line, char *buf, int color)
 206 {
 207     draw_txt_string( (camera_screen.width/FONT_WIDTH-strlen(buf))>>1 , line, buf, color) ;
 208 }
 209 
 210 static void compass_display_task();
 211 static void run_compass_task(int mode){  
 212     
 213     navigation_mode = mode ;
 214     
 215     if (gps_compass_lock == 0 )
 216     {
 217         gps_compass_lock = 1 ;   
 218         CreateTask("GPS_COMPASS", 0x19, 0x1000, compass_display_task);   
 219     }
 220 }
 221 
 222 static void test_timezone(){                           // creates timezone.txt file with current timezone info
 223   
 224     char text[2][30];
 225     char home_name[30];
 226     int timezone_1, timezone_2;
 227     char * endptr;
 228 
 229     sprintf(home_name, "A/GPS/Timezone/Timezone.txt");
 230 
 231     FILE* fp = fopen(home_name, "r");
 232     if( fp )
 233     {
 234         fgets(text[1], 15, fp);
 235         fgets(text[2], 15, fp);
 236         fclose(fp);
 237 
 238         g_d_lat_nav = (strtol (text[1], &endptr, 10 )) / 10000000.0;
 239         g_d_lon_nav = (strtol (text[2], &endptr, 10 )) / 10000000.0;
 240 
 241         timezone_1 = (int)((g_d_lon_nav+7.5)/15);
 242         timezone_2 = (int)((g_d_lon+7.5)/15);
 243 
 244         if (timezone_1 != timezone_2)
 245         {
 246             gui_mbox_init(LANG_INFORMATION, LANG_MENU_GPS_t_2, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL); //Timezone has changed!
 247         }
 248     }
 249 }
 250 
 251 static char *load_bitmap(char *datei){
 252     
 253     FILE *fd;
 254     char *bitmap;
 255     int bitmap_size;
 256 
 257     fd = fopen ( datei, "r" );
 258 
 259     fseek (fd, 0, SEEK_END);
 260     bitmap_size = ftell (fd);
 261     fseek (fd, 0, SEEK_SET);
 262 
 263     bitmap = (char*) malloc (sizeof(char)*bitmap_size);
 264     fread (bitmap,1,bitmap_size,fd);
 265     fclose (fd);
 266 
 267     return bitmap;
 268 }
 269 
 270 static double draw_gps_course_info(int count){             // calculate & display course information
 271 
 272     char vBuf[512];
 273     int angle1=0;
 274 
 275     soll.lat_w = g_d_lat_nav;
 276     soll.lon_w = g_d_lon_nav;
 277 
 278     now = (double) (count);
 279     gps.lat_w = g_d_lat;                                                    // read GPS (with noise)
 280     gps.lon_w = g_d_lon;
 281     georegAdd               (&georeg, now, &gps);                           // feed the regression
 282     georegActual            (&georeg, &ist);                                // read averaged position
 283     georegChange            (&georeg, &speed);                              // read averaged velocity
 284     geo2rect                (&speed, &mspeed, ist.lat_w);                   // Convert to m/s
 285     rect2polar              (&mspeed, &pspeed);                             // convert to direction and speed.
 286     direction = radian2deg  (pspeed.alpha);                                 // get direction
 287     geodiff                 (&ist, &soll, &delta);                          // Distance in degrees (N/E)
 288     geo2rect                (&delta, &rdelta, ist.lat_w);                   // Distance in m (je N/E)
 289     rect2polar              (&rdelta, &pdelta);                             // Distance in degrees m and grad
 290     peil    = radian2deg    (pdelta.alpha);                                 // Bearing to destination
 291     angle  = radian2deg     (pdelta.alpha-pspeed.alpha);                    // Angle relative to the direction of march
 292     regressionAdd           (&deltareg, now, pdelta.delta);                 // do the regression
 293     double eta = regressionReverse (&deltareg, 0);                          // estimated time of arrival
 294     double rest= eta - now;                                                 // Time = arrival time - now
 295 
 296     if (abs(regressionChange (&deltareg))<0.5 || rest < 5.0) rest = 0.0;
 297 
 298     if (camera_info.state.gui_mode_none)
 299     {
 300         angle1=(int)angle;
 301         char anz1[40];
 302         char anz2[40];
 303         char image[9];        
 304 
 305         if (navigation_mode > 0)
 306         {
 307             sprintf(vBuf, lang_str(LANG_MENU_GPS_t_9), (int)pdelta.delta);
 308             draw_txt_string(16, 9, vBuf, MAKE_COLOR(COLOR_GREY_DK_TRANS, COLOR_WHITE));
 309 
 310             int s = (int)rest;
 311             int hour = s / 3600;
 312             s = s % 3600;
 313             int minute =  s / 60;
 314             s = s % 60;
 315             int second = s;
 316 
 317             sprintf(vBuf, lang_str(LANG_MENU_GPS_t_10), hour, minute, second);
 318             draw_txt_string(16, 10, vBuf, MAKE_COLOR(COLOR_GREY_DK_TRANS, COLOR_WHITE));
 319 
 320             sprintf(vBuf, lang_str(LANG_MENU_GPS_t_11), formatDouble (anz1, (pspeed.delta * 3.6), 0, 1));
 321             draw_txt_string(16, 11, vBuf, MAKE_COLOR(COLOR_GREY_DK_TRANS, COLOR_WHITE));
 322             sprintf(vBuf, lang_str(LANG_MENU_GPS_t_12), direction);
 323             draw_txt_string(16, 12, vBuf, MAKE_COLOR(COLOR_GREY_DK_TRANS, COLOR_WHITE));
 324             sprintf(vBuf, lang_str(LANG_MENU_GPS_t_13), (int)angle);
 325             draw_txt_string(16, 13, vBuf, MAKE_COLOR(COLOR_GREY_DK_TRANS, COLOR_WHITE));
 326 
 327             if (navigation_mode==1)
 328             {
 329                 sprintf(image, "%s", camera_jpeg_current_filename());
 330                 image[8] = '\0';
 331                 sprintf(vBuf, lang_str(LANG_MENU_GPS_t_14), image);  // "Navigation to photo: %s started"
 332                 draw_txt_centered(1, vBuf, MAKE_COLOR(COLOR_GREY_DK_TRANS, COLOR_RED));
 333             }
 334             
 335             if (navigation_mode==2)
 336             {
 337                 sprintf(vBuf, lang_str(LANG_MENU_GPS_t_17));         // "Navigation to Home started"
 338                 draw_txt_centered(1, vBuf, MAKE_COLOR(COLOR_GREY_DK_TRANS, COLOR_RED));
 339             }
 340 
 341             sprintf(vBuf, lang_str(LANG_MENU_GPS_t_15), formatDouble (anz1, g_d_lat_nav, 0, 7), formatDouble (anz2, g_d_lon_nav, 0, 7)); //"latitude=%s  -  longitude=%s "
 342             draw_txt_centered(2, vBuf, MAKE_COLOR(COLOR_GREY_DK_TRANS, COLOR_RED));
 343         }
 344         else
 345         {
 346             angle1= direction;
 347             sprintf(vBuf, lang_str(LANG_MENU_GPS_t_16), (int)angle1);   // "heading = %i°"
 348             draw_txt_string(16, 10, vBuf, MAKE_COLOR(COLOR_GREY_DK_TRANS, COLOR_WHITE));            
 349             sprintf(vBuf, lang_str(LANG_MENU_GPS_t_15), formatDouble (anz1, g_d_lat_nav, 0, 7), formatDouble (anz2, g_d_lon_nav, 0, 7)); //"latitude=%s  -  longitude=%s "
 350             draw_txt_string(16, 11, vBuf, MAKE_COLOR(COLOR_GREY_DK_TRANS, COLOR_WHITE));  
 351         }
 352     }
 353 
 354     return angle1;
 355 }
 356 
 357 // draw animated compass needle on GUI
 358 static void draw_compass_needle (int angle, double s_w, double c_w, char *bitmap, int extent, int m_x, int m_y, int offset_x, int offset_y, int f_v_1, int f_v_2){
 359  
 360 /*
 361     char vBuf[32];
 362     sprintf(vBuf, "%d", angle );      
 363     draw_txt_string(30, 0, vBuf, MAKE_COLOR(COLOR_GREY_DK_TRANS, COLOR_RED));   
 364 */
 365     if(bitmap)
 366     {
 367         int mx=0;
 368         int my=0;
 369         int px=0;
 370         int py=0;
 371 
 372         int pos=0;
 373         int x_n;
 374         int y_n;
 375 
 376         if (angle==0 || angle==360)
 377         {
 378             s_w = 0;
 379             c_w = -1;
 380         }
 381 
 382         if (angle==270)
 383         {
 384             s_w = -1;
 385             c_w = 0;
 386         }
 387 
 388         for(pos=0; pos<extent; pos++)
 389         {
 390             int data = bitmap[pos];
 391             if (data >= 49)
 392             {
 393                 px=offset_x+mx;
 394                 py=offset_y+my;
 395 
 396                 x_n = m_x + Round(((c_w * (m_x - px)) + (s_w * (m_y - py))),2);
 397                 y_n = m_y + Round(((c_w * (m_y - py)) - (s_w * (m_x - px))),2);
 398 
 399                 if (data == 49)
 400                 {
 401                     draw_pixel(x_n, y_n, f_v_1);
 402                 }
 403                 if (data == 50)
 404                 {
 405                     draw_pixel(x_n, y_n, f_v_2);
 406                 }
 407             }
 408             if (data == 10 || data == 13)
 409             {
 410                 mx=0;
 411                 my++;
 412                 pos++;
 413             }
 414             else
 415             {
 416                 mx++;
 417             }
 418         }
 419 
 420     }
 421 }
 422 
 423 // draw animated compass on GUI
 424 static void draw_compass (char *bitmap, int o_x, int o_y, int f_v_0, int f_v_1, int f_v_2, int f_v_4){
 425 
 426     if(bitmap)
 427     {
 428         int extent = strlen(bitmap);
 429         int pos=0;
 430         int mx=0;
 431         int my=0;
 432 
 433         for(pos=0; pos<extent; pos++)
 434         {
 435             int data = bitmap[pos];
 436             if (data == 48)
 437             {
 438                 draw_pixel(o_x+mx, o_y+my, f_v_0);
 439             }
 440             if (data == 49)
 441             {
 442                 draw_pixel(o_x+mx, o_y+my, f_v_1);
 443             }
 444             if (data == 50)
 445             {
 446                 draw_pixel(o_x+mx, o_y+my, f_v_2);
 447             }
 448             if (data == 51)
 449             {
 450                 draw_pixel(o_x+mx, o_y+my, f_v_4);
 451             }
 452             if (data == 10 || data == 13)
 453             {
 454                 mx=0;
 455                 my++;
 456                 pos++;
 457             }
 458             else
 459             {
 460                 mx++;
 461             }
 462         }
 463 
 464     }
 465 }
 466 
 467 //=======================================================================
 468 //
 469 // TASK : displays satellite dish image when CHDK GPS functionality enabled
 470 //
 471 static void show_sat_symbol_task(){
 472     
 473     char *bitmap = load_bitmap("A/CHDK/DATA/GPS_Sat.txt");
 474 
 475     if(bitmap)
 476     {
 477         int extent1 = strlen(bitmap);
 478         int pos1=0;
 479         int mx1=0;
 480         int my1=0;
 481         int o_x1=270;
 482         int o_y1=0;
 483         int f_v_0;
 484 //         int f_h_0;
 485         int f_v_1;
 486 //         int f_h_1;
 487         int f_v_2;
 488 //         int f_h_2;
 489         int f_v_3;
 490 //         int f_h_3;
 491         int f_v_4;
 492 //         int f_h_4;
 493 
 494         while (exit_show_task==0) 
 495         {           
 496             int stat = g_d_stat;
 497             
 498             mx1=0;
 499             my1=0;
 500 
 501             f_v_0=COLOR_TRANSPARENT;
 502 //             f_h_0=COLOR_TRANSPARENT;
 503 
 504             f_v_1=COLOR_GREEN;
 505 //             f_h_1=COLOR_GREEN;
 506 
 507             switch (stat)
 508             {
 509                 case 0 :
 510                     f_v_1= COLOR_RED ;
 511 //                     f_h_1= COLOR_RED ;
 512                     break ;
 513                 case 1 :
 514                     f_v_1= COLOR_YELLOW ;
 515 //                     f_h_1= COLOR_YELLOW ;
 516                     break ;
 517                 case 2 :
 518                     f_v_1= COLOR_GREEN ;
 519 //                     f_h_1= COLOR_GREEN ;
 520                     break ;
 521             }
 522             
 523             if (camera_info.state.mode_play)
 524             {
 525                 gps_img_data *igps = ( gps_img_data *) camera_jpeg_current_gps();
 526 
 527                 f_v_1= COLOR_RED ;
 528 //                 f_h_1= COLOR_RED ;
 529                 if (igps->latitudeRef[0] && igps->longitudeRef[0])
 530                 {
 531                     f_v_1= COLOR_YELLOW ;
 532 //                     f_h_1= COLOR_YELLOW ;
 533                     if (igps->height[1])
 534                     {
 535                         f_v_1= COLOR_GREEN ;
 536 //                         f_h_1= COLOR_GREEN ;
 537                     }
 538                 }
 539             }
 540 
 541             f_v_2= COLOR_BLACK ;
 542 //             f_h_2= COLOR_BLACK ;
 543 
 544             f_v_3= COLOR_YELLOW ;
 545 //             f_h_3= COLOR_YELLOW ;
 546 
 547             f_v_4= COLOR_BLUE ;
 548 //             f_h_4= COLOR_BLUE ;
 549 
 550             for(pos1=0; pos1<extent1; pos1++)
 551             {
 552                 int data = bitmap[pos1];
 553                 if (data == 48)
 554                 {
 555                     draw_pixel(o_x1+mx1, o_y1+my1, f_v_0);
 556                 }
 557                 if (data == 49)
 558                 {
 559                     draw_pixel(o_x1+mx1, o_y1+my1, f_v_1);
 560                 }
 561                 if (data == 50)
 562                 {
 563                     draw_pixel(o_x1+mx1, o_y1+my1, f_v_2);
 564                 }
 565                 if (data == 51)
 566                 {
 567                     draw_pixel(o_x1+mx1, o_y1+my1, f_v_3);
 568                 }
 569                 if (data == 52)
 570                 {
 571                     draw_pixel(o_x1+mx1, o_y1+my1, f_v_4);
 572                 }
 573                 if (data == 10 || data == 13)
 574                 {
 575                     mx1=0;
 576                     my1++;
 577                     pos1++;
 578                 }
 579                 else
 580                 {
 581                     mx1++;
 582                 }
 583             }
 584             msleep(1000);           
 585         }
 586         free(bitmap);
 587     }
 588     gps_show_lock = 0 ;     
 589     ExitTask();
 590 }
 591 
 592 //=======================================================================
 593 //
 594 // TASK : updates GPS data structures continuously if CHDK GPS functionality is enabled
 595 //
 596 static void gps_data_task(){
 597     
 598     test_timezone_once=0;
 599     
 600     while (exit_data_task==0)
 601     {
 602         tGPS gps;
 603         int tim00=0;
 604         int tim01=0;
 605         int tim02=0;
 606         unsigned long t;
 607         static struct tm *ttm;        
 608                           
 609   #ifndef SIMULATED_GPS
 610         GPS_UpdateData();  
 611         get_property_case(camera_info.props.gps, &gps, sizeof(gps));
 612   #else     
 613         GPS_FakeData() ;
 614         memcpy( &gps , &gps_dummy_data, sizeof(gps) );
 615   #endif
 616   
 617         t=time(NULL);
 618         ttm = localtime(&t);
 619         
 620         lock(0);
 621         
 622             g_d_lat=0.0;
 623             g_d_lat=(gps.latitude[0]/(gps.latitude[1]*1.0)) + (gps.latitude[2]/(gps.latitude[3]*60.0)) + (gps.latitude[4]/(gps.latitude[5]*3600.0));
 624             if (gps.latitudeRef[0]=='S') g_d_lat=-g_d_lat;
 625 
 626             g_d_lon=0.0;
 627             g_d_lon=(gps.longitude[0]/(gps.longitude[1]*1.0)) + (gps.longitude[2]/(gps.longitude[3]*60.0)) + (gps.longitude[4]/(gps.longitude[5]*3600.0));
 628             if (gps.longitudeRef[0]=='W') g_d_lon=-g_d_lon;
 629 
 630             g_d_hei=0.0;
 631             g_d_hei=gps.height[0]/(gps.height[1]*1.0);
 632 
 633     /**************
 634     char vBuf[256], lat[40],lon[40] ;
 635     sprintf(vBuf, "%d.%d.%d  %d.%d.%d",
 636         gps.latitude[0] / gps.latitude[1] , 
 637         gps.latitude[2] / gps.latitude[3] ,
 638         gps.latitude[4] / gps.latitude[5] ,   
 639         gps.longitude[0] / gps.longitude[1] , 
 640         gps.longitude[2] / gps.longitude[3] ,
 641         gps.longitude[4] / gps.longitude[5] );      
 642     draw_txt_string(1, 0, vBuf, MAKE_COLOR(COLOR_GREY_DK_TRANS, COLOR_RED));    
 643     formatDouble (lat, g_d_lat, 0, 7),
 644     formatDouble (lon, g_d_lon, 0, 7),    
 645     sprintf(vBuf,"lat=%s lon=%s",lat,lon );
 646     draw_txt_string(1, 1, vBuf, MAKE_COLOR(COLOR_GREY_DK_TRANS, COLOR_RED));              
 647     ************/
 648     
 649             sprintf(g_d_tim, "%02d:%02d:%02d", ttm->tm_hour, ttm->tm_min, ttm->tm_sec);
 650             sprintf(g_d_dat, "%04d-%02d-%02d", ttm->tm_year+1900, ttm->tm_mon+1, ttm->tm_mday);
 651 
 652             g_d_stat=0;
 653             if ((int)g_d_lat == 0) {g_d_stat = 0; }
 654             if ((int)g_d_lat != 0 && (int)g_d_hei == 0) {g_d_stat=1; }
 655             if ((int)g_d_lat != 0 && (int)g_d_hei != 0) {g_d_stat=2; }
 656 
 657             if (g_d_stat > 0)
 658             {
 659                 tim00=(int)(gps.timeStamp[0]/gps.timeStamp[1]);
 660                 tim01=(int)(gps.timeStamp[2]/gps.timeStamp[3]);
 661                 tim02=(int)(gps.timeStamp[4]/gps.timeStamp[5]);
 662                 sprintf(g_d_tim_gps, "%02d:%02d:%02d", tim00, tim01, tim02);
 663 
 664                 sprintf(g_d_dat_gps, "%c%c%c%c-%c%c-%c%c",
 665                         gps.dateStamp[0],
 666                         gps.dateStamp[1],
 667                         gps.dateStamp[2],
 668                         gps.dateStamp[3],
 669                         gps.dateStamp[5],
 670                         gps.dateStamp[6],
 671                         gps.dateStamp[8],
 672                         gps.dateStamp[9]);
 673 
 674                 if (((int)conf.gps_test_timezone == 1) && (test_timezone_once==0))
 675                 {
 676                     test_timezone();
 677                     test_timezone_once=1;
 678                 }
 679             }
 680 
 681         unlock(0);
 682 
 683         if ((int)conf.gps_show_symbol == 1)
 684         {
 685             if ( gps_show_lock == 0 )
 686             {                
 687                 exit_show_task= 0 ;      
 688                 gps_show_lock = 1 ;
 689                 CreateTask("GPS_SHOW", 0x19, 0x800, show_sat_symbol_task);
 690             }
 691         } 
 692         else exit_show_task=1; 
 693         
 694         msleep(900);
 695     } 
 696     exit_show_task=1; 
 697     gps_data_lock = 0 ;    
 698     ExitTask();
 699 }
 700 
 701 //=======================================================================
 702 //
 703 // TASK : updates onsceen tracking icon (globe)
 704 //
 705 static void tracking_icon_task(){
 706     
 707     char * bitmap1 = load_bitmap("A/CHDK/DATA/GPS_Track_1.txt");
 708     char * bitmap2 = load_bitmap("A/CHDK/DATA/GPS_Track_2.txt");
 709     char * bitmap3 = load_bitmap("A/CHDK/DATA/GPS_Track_3.txt");
 710 
 711     if(bitmap1 && bitmap2 && bitmap2 )
 712     {
 713         int extent1 = strlen(bitmap1);
 714         int pos1=0;
 715         int mx1=0;
 716         int my1=0;
 717         int o_x1=315;
 718         int o_y1=0;
 719         int f_v_0;
 720 //         int f_h_0;
 721         int f_v_1;
 722 //         int f_h_1;
 723         int f_v_2;
 724 //         int f_h_2;
 725         int f_v_3;
 726 //         int f_h_3;
 727         int f_v_4;
 728 //         int f_h_4;
 729         int f_v_5;
 730 //         int f_h_5;
 731         int blink=0;
 732         int data;
 733 
 734         while (exit_track_task == 0)
 735         {
 736             mx1=0;
 737             my1=0;
 738 
 739             f_v_0=COLOR_TRANSPARENT;
 740 //             f_h_0=COLOR_TRANSPARENT;
 741 
 742             f_v_1= COLOR_BLACK ;
 743 //             f_h_1= COLOR_BLACK ;
 744 
 745             f_v_2= COLOR_BLUE ;
 746 //             f_h_2= COLOR_BLUE ;
 747 
 748             f_v_3= COLOR_YELLOW ;
 749 //             f_h_3= COLOR_YELLOW ;
 750 
 751             f_v_4= COLOR_RED ;
 752 //             f_h_4= COLOR_RED ;
 753 
 754             f_v_5= COLOR_GREEN ;
 755 //             f_h_5= COLOR_GREEN ;
 756 
 757             int stat = g_d_stat ;
 758             
 759             for(pos1=0; pos1<extent1; pos1++)
 760             {
 761                 if ((blink==1) && (stat > 0))
 762                 {
 763                     data = bitmap2[pos1];
 764                 }
 765                 else
 766                 {
 767                     data = bitmap1[pos1];
 768                 }
 769                 if ((blink==1) && (navigation_mode > 0) && (stat > 0))
 770                 {
 771                     data = bitmap3[pos1];
 772                 }
 773                 if (data == 48)
 774                 {
 775                     draw_pixel(o_x1+mx1, o_y1+my1, f_v_0);
 776                 }
 777                 if (data == 49)
 778                 {
 779                     draw_pixel(o_x1+mx1, o_y1+my1, f_v_1);
 780                 }
 781                 if (data == 50)
 782                 {
 783                     draw_pixel(o_x1+mx1, o_y1+my1, f_v_2);
 784                 }
 785                 if (data == 51)
 786                 {
 787                     draw_pixel(o_x1+mx1, o_y1+my1, f_v_3);
 788                 }
 789                 if (data == 52)
 790                 {
 791                     draw_pixel(o_x1+mx1, o_y1+my1, f_v_4);
 792                 }
 793                 if (data == 53)
 794                 {
 795                     draw_pixel(o_x1+mx1, o_y1+my1, f_v_5);
 796                 }
 797                 if (data == 10 || data == 13)
 798                 {
 799                     mx1=0;
 800                     my1++;
 801                     pos1++;
 802                 }
 803                 else
 804                 {
 805                     mx1++;
 806                 }
 807             }
 808 
 809             msleep(1000);
 810             
 811             if (blink==0)
 812             {
 813                 blink=1;
 814             }
 815             else
 816             {
 817                 blink=0;
 818             }
 819         }        
 820     }
 821     if (bitmap1) free(bitmap1) ;
 822     if (bitmap2) free(bitmap2) ;
 823     if (bitmap3) free(bitmap3) ;
 824     gps_track_lock = 0 ; 
 825     ExitTask();
 826 }
 827 
 828 //=======================================================================
 829 //
 830 // TASK : started by waypoint recording code when no GPS signal and picture was taken
 831 //
 832 static void no_signal_task(){
 833    
 834     char vBuf[100];
 835     FILE *fd0;
 836     char w1[20];
 837     char w2[30];
 838     char w3[10];
 839     int o=1, p=1, q=0;
 840     int blite_off=0;
 841     unsigned long bat;
 842     int abort=0;
 843     
 844     gps_key_trap = KEY_DISPLAY ;
 845     
 846     while ( time_to_end !=0 )
 847     {
 848 
 849         // Test battery
 850         if ( (((time_to_end) % 60)) == 0 )
 851         {
 852             bat=get_batt_perc();
 853             if (bat <= (unsigned)conf.gps_batt)
 854             {
 855                 int zba;
 856                 for(zba=30; zba>0; zba--)
 857                 {
 858                     sprintf(vBuf, lang_str(LANG_MENU_GPS_t_3));      // "Battery below setting!"
 859                     draw_txt_centered(8, vBuf, MAKE_COLOR(COLOR_YELLOW, COLOR_RED));
 860                     sprintf(vBuf, lang_str(LANG_MENU_GPS_t_4),zba); // "Camera will shutdown in %02d seconds!"
 861                     draw_txt_centered(9, vBuf, MAKE_COLOR(COLOR_RED, COLOR_BLUE));
 862                     if ( (((zba) % 2)) == 0 )
 863                     {
 864                         debug_led(0);
 865                         if ((int)conf.gps_batt_warn == 1)
 866                         {
 867                             play_sound(6);
 868                         }
 869                     }
 870                     else
 871                     {
 872                         debug_led(1);
 873                     }
 874                     msleep(1000);
 875                 }
 876                 camera_shutdown_in_a_second();
 877                 gps_nosignal_lock = 0 ;                 
 878                 ExitTask();
 879             }
 880         }
 881 
 882         // cancel automatic shut-off if DISP key pressed
 883         if (gps_key_trap == -1 )
 884         {
 885             gps_key_trap = 0;             
 886             abort = 1;
 887             time_to_end = 3600;
 888             TurnOnBackLight();
 889             gui_mbox_init(LANG_INFORMATION, LANG_MENU_GPS_t_5, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL); //Automatic shutdown cancelled!
 890         }
 891 
 892         // manage backlight and display
 893         if ( abort == 0)
 894         {
 895             // update LED blink
 896             if (q==0)
 897             {
 898                 debug_led(0);
 899                 q=1;
 900             }
 901             else
 902             {
 903                 debug_led(1);
 904                 q=0;
 905             }
 906 
 907             // Display countdown of time to finish in mm: ss
 908             int s = (int)time_to_end;
 909             int minute =  s / 60;
 910             s = s % 60;
 911             int second = s;
 912 
 913             if ( (int)conf.gps_countdown==0 )
 914             {
 915                 sprintf(vBuf, lang_str(LANG_MENU_GPS_t_6),minute, second);  // "Camera will wait for GPS for %01d:%02d"
 916             }
 917             else
 918             {
 919                 sprintf(vBuf, " %01d:%02d",minute, second);
 920             }
 921             draw_txt_centered(0, vBuf, MAKE_COLOR(COLOR_GREY_DK_TRANS, COLOR_RED));
 922 
 923             // Switch on the display when countdown <30 seconds
 924             if ((blite_off==1) && (time_to_end <=30))
 925             {
 926                 TurnOnBackLight();
 927             }
 928 
 929             // start countdown if key pressed and backlight is off
 930             if ((blite_off==0) && (kbd_get_pressed_key() !=0))     // any key pressed ?
 931             {
 932                 time_to_end=(int)conf.gps_wait_for_signal;
 933                 o=1;
 934                 p=1;
 935             }
 936 
 937             // start countdown and turn on backlight if key pressed and backlight is off
 938             if ((blite_off==1) && (kbd_get_pressed_key() !=0))     // any key pressed ?
 939             {
 940                 TurnOnBackLight();
 941                 blite_off=0;
 942                 time_to_end=(int)conf.gps_wait_for_signal; 
 943                 o=1;
 944                 p=1;
 945             }
 946 
 947             // switch to play mode
 948             if ((o == (int)conf.gps_rec_play_time) && ((int)conf.gps_rec_play_set == 1))
 949             {
 950                 if (camera_info.state.mode_rec)
 951                 {
 952                     levent_set_play();
 953                 }
 954             }
 955 
 956             // turn off backlight if timed out
 957             if ((p == (int)conf.gps_play_dark_time) && ((int)conf.gps_play_dark_set == 1))
 958             {
 959                 if (camera_info.state.mode_play)
 960                 {
 961                     TurnOffBackLight();
 962                     blite_off=1;
 963                 }
 964             }
 965         }
 966 
 967         // tag waypoint reached
 968 
 969         lock(1) ;
 970             int l_stat      = g_d_stat ;
 971             double l_lat       = g_d_lat ;
 972             double l_lon       = g_d_lon ;
 973             double l_hei       = g_d_hei ;
 974             char l_tim[10];
 975             char l_dat[12];
 976             char l_tim_gps[10];
 977             char l_dat_gps[12];   
 978             strncpy( l_tim ,      g_d_tim,    10 );         
 979             strncpy( l_dat ,      g_d_dat,    12 );
 980             strncpy( l_tim_gps ,  g_d_tim_gps,10 );
 981             strncpy( l_dat_gps ,  g_d_dat_gps,12 );
 982         unlock(1);       
 983     
 984         if ( ((((int)conf.gps_2D_3D_fix) == 1) && (l_stat == 1)) || \
 985              ((((int)conf.gps_2D_3D_fix) == 1) && (l_stat == 2)) || \
 986              ((((int)conf.gps_2D_3D_fix) == 2) && (l_stat == 2)) || \
 987              ((((int)conf.gps_2D_3D_fix) == 3) && (l_stat == 2)) || \
 988              ((((int)conf.gps_2D_3D_fix) == 3) && (l_stat == 1) && (time_to_end < 3)) || \
 989              ((((int)conf.gps_2D_3D_fix) == 0) && (time_to_end < 3)) )
 990         {
 991             TurnOnBackLight();
 992             msleep (1000);
 993 
 994             fd0 = fopen ( "A/GPS/Tagging/wp.tmp", "r" );
 995 
 996             do
 997             {
 998                 fgets (w1, 15, fd0);
 999                 fseek (fd0, 1, SEEK_CUR);
1000                 fgets (w2, 23, fd0);
1001                 fseek (fd0, 1, SEEK_CUR);
1002                 fgets (w3, 1, fd0);
1003 
1004                 char lat[40];
1005                 char lon[40];
1006                 char hei[40];
1007 
1008                 char vBuf1[512];
1009                 char image_name[20];
1010                 char wp_name[30];
1011                 char gpx_name[30];
1012                 char gpx_image_name[20];
1013                 unsigned long t;
1014                 static struct tm *ttm;
1015                 t=time(NULL);
1016                 ttm = localtime(&t);
1017 
1018                 sprintf(wp_name, "A/GPS/Tagging/%04d_%02d_%02d.wp", ttm->tm_year+1900, ttm->tm_mon+1, ttm->tm_mday);
1019                 sprintf(gpx_name, "A/GPS/Tagging/%04d_%02d_%02d.gpx", ttm->tm_year+1900, ttm->tm_mon+1, ttm->tm_mday);
1020 
1021                 sprintf(image_name, "%s", w1);
1022                 sprintf(gpx_image_name, "%s", w1);
1023 
1024                 sprintf(vBuf1, "%s;%s;%s;%s;%s;%s",
1025                         image_name,
1026                         formatDouble (lat, l_lat, 0, 7),
1027                         formatDouble (lon, l_lon, 0, 7),
1028                         formatDouble (hei, l_hei, 0, 2),
1029                         w2,
1030                         w3);
1031 
1032                 FILE* fp = fopen(wp_name, "a");
1033 
1034                 if( fp )
1035                 {
1036                     fwrite(vBuf1, strlen(vBuf1), 1, fp);
1037                 }
1038 
1039                 fclose(fp);
1040 
1041                 fp = fopen(gpx_name, "r");
1042                 if( fp == NULL)
1043                 {
1044                     fp = fopen(gpx_name, "a");
1045                     if( fp )
1046                     {
1047                         sprintf(vBuf1, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
1048                         fwrite(vBuf1, strlen(vBuf1), 1, fp);
1049                         sprintf(vBuf1, "<gpx xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" version=\"1.1\" creator=\"CHDK\" xmlns=\"http://www.topografix.com/GPX/1/1\">\n");
1050                         fwrite(vBuf1, strlen(vBuf1), 1, fp);
1051                         sprintf(vBuf1, "</gpx>");
1052                         fwrite(vBuf1, strlen(vBuf1), 1, fp);
1053                         fclose(fp);
1054                     }
1055                 }
1056 
1057 
1058                 fp = fopen(gpx_name, "a");
1059                 if( fp )
1060                 {
1061                     fseek (fp, -6, SEEK_END);
1062 
1063                     sprintf(vBuf1, "   <wpt lat=\"%s\" lon=\"%s\">\n",formatDouble (lat, l_lat, 0, 7), formatDouble (lon, l_lon, 0, 7));
1064                     fwrite(vBuf1, strlen(vBuf1), 1, fp);
1065                     sprintf(vBuf1, "    <ele>%s</ele>\n",formatDouble (hei, l_hei, 0, 2));
1066                     fwrite(vBuf1, strlen(vBuf1), 1, fp);
1067                     sprintf(vBuf1, "    <time>%s</time>\n", w2);
1068                     fwrite(vBuf1, strlen(vBuf1), 1, fp);
1069                     sprintf(vBuf1, "    <gpst>%sT%sZ</gpst>\n", l_dat_gps, l_tim_gps);
1070                     fwrite(vBuf1, strlen(vBuf1), 1, fp);
1071                     sprintf(vBuf1, "    <temp>%i</temp>\n", (int)get_optical_temp());
1072                     fwrite(vBuf1, strlen(vBuf1), 1, fp);
1073                     sprintf(vBuf1, "    <name>%s</name>\n", gpx_image_name);
1074                     fwrite(vBuf1, strlen(vBuf1), 1, fp);
1075                     sprintf(vBuf1, "   </wpt>\n");
1076                     fwrite(vBuf1, strlen(vBuf1), 1, fp);
1077                     sprintf(vBuf1, "</gpx>");
1078                     fwrite(vBuf1, strlen(vBuf1), 1, fp);
1079                 }
1080                 fclose(fp);
1081             }
1082             while (!feof(fd0));
1083 
1084             fclose (fd0);
1085             if ( abort == 0)
1086             {
1087                 time_to_end=1;
1088             }
1089 
1090         }
1091 
1092         msleep(1000);
1093         o++;
1094         p++;
1095 
1096 
1097         // gps functionality disabled ?
1098         if ((int)conf.gps_on_off ==0)
1099         {
1100             debug_led(0);
1101             gps_nosignal_lock = 0;             
1102             ExitTask();
1103         }
1104 
1105         time_to_end--;
1106     }
1107 
1108     int zba, zba1;
1109 
1110     if (abort == 0)
1111     {
1112         for(zba=15; zba>0; zba--)           // outer loop = 30 seconds
1113         {
1114             sprintf(vBuf, lang_str(LANG_MENU_GPS_t_4), zba);     // "Camera will shutdown in %02d seconds!"
1115             draw_txt_centered(2, vBuf, MAKE_COLOR(COLOR_WHITE, COLOR_BLUE));
1116             sprintf(vBuf, lang_str(LANG_MENU_GPS_t_18));         //"To cancel [Press half]"
1117             draw_txt_centered(3, vBuf, MAKE_COLOR(COLOR_WHITE, COLOR_RED));
1118             play_sound(6);
1119 
1120             for(zba1=100; zba1>0; zba1--)   // inner loop = 2 seconds
1121             {
1122                 if (kbd_get_pressed_key() == KEY_SHOOT_HALF)
1123                     {
1124                         TurnOnBackLight();
1125                         debug_led(0);
1126                         gps_nosignal_lock = 0 ; 
1127                         ExitTask();
1128                     }
1129                 msleep(2);
1130             }
1131         }        
1132         camera_shutdown_in_a_second();
1133     }
1134 
1135     TurnOnBackLight();
1136 
1137     // beep 5 seconds
1138     if ((int)conf.gps_beep_warn == 1)
1139     {
1140         for(zba=5; zba>0; zba--) play_sound(6);
1141     }
1142     
1143     debug_led(0);
1144     gps_nosignal_lock = 0 ; 
1145     ExitTask();
1146 
1147 }
1148 
1149 
1150 //=======================================================================
1151 //
1152 // TASK : started by init_gps_logging_task() to record logging data
1153 //
1154 static void gps_logging_task(){
1155       
1156     char lat[40];
1157     char lon[40];
1158     char hei[40];
1159     char vBuf[512];
1160     unsigned long t;
1161     char gpx_name[30];
1162     static struct tm *ttm;
1163     t=time(NULL);
1164     ttm = localtime(&t);
1165 
1166     mkdir_if_not_exist("A/GPS");
1167     mkdir_if_not_exist("A/GPS/Logging");
1168     sprintf(gpx_name, "A/GPS/Logging/%02d_%02d-%02d_%02d.gpx", ttm->tm_mon+1, ttm->tm_mday, ttm->tm_hour, ttm->tm_min);
1169 
1170     FILE* fp = fopen(gpx_name, "w");
1171     if( fp )
1172     {
1173         sprintf(vBuf, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
1174         fwrite(vBuf, strlen(vBuf), 1, fp);
1175         sprintf(vBuf, "<gpx xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" version=\"1.1\" creator=\"CHDK\" xmlns=\"http://www.topografix.com/GPX/1/1\">\n");
1176         fwrite(vBuf, strlen(vBuf), 1, fp);
1177         sprintf(vBuf, " <metadata />\n");
1178         fwrite(vBuf, strlen(vBuf), 1, fp);
1179         sprintf(vBuf, " <trk>\n");
1180         fwrite(vBuf, strlen(vBuf), 1, fp);
1181         sprintf(vBuf, "  <name />\n");
1182         fwrite(vBuf, strlen(vBuf), 1, fp);
1183         sprintf(vBuf, "  <cmt />\n");
1184         fwrite(vBuf, strlen(vBuf), 1, fp);
1185         sprintf(vBuf, "  <trkseg>\n");
1186         fwrite(vBuf, strlen(vBuf), 1, fp);
1187         sprintf(vBuf, "  </trkseg>\n");
1188         fwrite(vBuf, strlen(vBuf), 1, fp);
1189         sprintf(vBuf, " </trk>\n");
1190         fwrite(vBuf, strlen(vBuf), 1, fp);
1191         sprintf(vBuf, "</gpx>\n");
1192         fwrite(vBuf, strlen(vBuf), 1, fp);
1193     }
1194     fclose(fp);
1195     int zae=1, zae_1=0, bat;
1196     
1197     while ( exit_record_task==0 )
1198     {
1199         if (kbd_get_pressed_key() !=0)   // any key pressed ?
1200         {
1201             TurnOnBackLight();
1202             zae_1=0;
1203         }
1204 
1205         zae_1++;
1206         if ((zae_1 == (int)conf.gps_rec_play_time_1) && ((int)conf.gps_rec_play_set_1 == 1))
1207         {
1208             if (camera_info.state.mode_rec)
1209             {
1210                 levent_set_play();
1211             }
1212         }
1213         if ((zae_1 == (int)conf.gps_play_dark_time_1) && ((int)conf.gps_play_dark_set_1 == 1))
1214         {
1215             if (camera_info.state.mode_play)
1216             {
1217                 TurnOffBackLight();
1218             }
1219         }
1220         if ( (((zae_1) % 2)) == 0 )
1221         {
1222             debug_led(0);
1223         }
1224         else
1225         {
1226             debug_led(1);
1227         }
1228         if ( (((zae * (int)conf.gps_track_time) % 60)) == 0 )
1229         {
1230             bat=get_batt_perc();
1231             if (bat <= (int)conf.gps_batt)
1232             {
1233                 int zba;
1234                 for(zba=30; zba>0; zba--)
1235                 {
1236                     sprintf(vBuf, lang_str(LANG_MENU_GPS_t_3));  // "Battery below setting!"
1237                     draw_txt_centered(8, vBuf, MAKE_COLOR(COLOR_GREY_DK_TRANS, COLOR_RED));
1238                     sprintf(vBuf, lang_str(LANG_MENU_GPS_t_4),zba);
1239                     draw_txt_centered(9, vBuf, MAKE_COLOR(COLOR_GREY_DK_TRANS, COLOR_RED));
1240                     if ( (((zba) % 2)) == 0 )
1241                     {
1242                         debug_led(0);
1243                         play_sound(6);
1244                     }
1245                     else
1246                     {
1247                         debug_led(1);
1248                     }
1249                     msleep(1000);
1250                 }
1251                 camera_shutdown_in_a_second();
1252                 gps_record_lock = 0 ; 
1253                 ExitTask();
1254             }
1255         }
1256         
1257         lock(2) ;
1258             int l_stat   = g_d_stat ;
1259             double l_lat = g_d_lat ;
1260             double l_lon = g_d_lon ;
1261             double l_hei = g_d_hei ;
1262             char l_tim[10];
1263             char l_dat[12];  
1264             strncpy( l_tim, g_d_tim, 10 );         
1265             strncpy( l_dat, g_d_dat, 12 );          
1266         unlock(2) ;
1267         
1268         if (l_stat == 1 || l_stat == 2)
1269         {
1270             fp = fopen(gpx_name, "a");
1271             if( fp )
1272             {
1273                 fseek (fp, -27, SEEK_END);
1274                 sprintf(vBuf, "   <trkpt lat=\"%s\" lon=\"%s\">\n",formatDouble (lat, l_lat, 0, 7), formatDouble (lon, l_lon, 0, 7));
1275                 fwrite(vBuf, strlen(vBuf), 1, fp);
1276                 sprintf(vBuf, "    <ele>%s</ele>\n",formatDouble (hei, l_hei, 0, 2));
1277                 fwrite(vBuf, strlen(vBuf), 1, fp);
1278                 sprintf(vBuf, "    <time>%sT%sZ</time>\n", l_dat, l_tim);
1279                 fwrite(vBuf, strlen(vBuf), 1, fp);
1280                 sprintf(vBuf, "   </trkpt>\n");
1281                 fwrite(vBuf, strlen(vBuf), 1, fp);
1282                 sprintf(vBuf, "  </trkseg>\n");
1283                 fwrite(vBuf, strlen(vBuf), 1, fp);
1284                 sprintf(vBuf, " </trk>\n");
1285                 fwrite(vBuf, strlen(vBuf), 1, fp);
1286                 sprintf(vBuf, "</gpx>\n");
1287                 fwrite(vBuf, strlen(vBuf), 1, fp);
1288             }
1289             fclose(fp);
1290         }
1291         msleep((int)conf.gps_track_time*1000);
1292         zae++;
1293     }
1294     debug_led(0);
1295     gps_record_lock = 0 ; 
1296     ExitTask();
1297 
1298 }
1299 
1300 //=======================================================================
1301 //
1302 // TASK : compass GUI display
1303 //
1304 static void compass_display_task(){
1305 
1306     #define BITMAP_WIDTH  61
1307     #define BITMAP_HEIGHT 61
1308 
1309     georegInit (&georeg, (int)conf.gps_compass_smooth, buffer1, buffer2);
1310     regressionInit (&deltareg, 20, buffer3);
1311 
1312     int stat ;
1313     double angle=0;
1314     double w=0.0;
1315     double c_w;
1316     double s_w;
1317     int n=0;
1318     int count=0;
1319     int m=0;
1320     int old_angle=0;
1321 
1322     int offset_x = 32;
1323     int m_x = offset_x + 31;
1324     int offset_y = 150;     //128
1325     int m_y = offset_y + 31;
1326 
1327     int f_v_0=COLOR_TRANSPARENT;
1328 //     int f_h_0=COLOR_TRANSPARENT;
1329 
1330     int f_v_1=COLOR_BLUE;
1331 //     int f_h_1=COLOR_BLUE;
1332 
1333     int f_v_2= COLOR_WHITE ;
1334 //     int f_h_2= COLOR_WHITE ;
1335 
1336     int f_v_3= COLOR_BLACK ;
1337 //     int f_h_3= COLOR_BLACK ;
1338 
1339     int f_v_4= COLOR_BLACK ;
1340 //     int f_h_4= COLOR_BLACK ;
1341 
1342     double old_c_w=cos(0);
1343     double old_s_w=sin(0);
1344 
1345     char *bitmap1 = load_bitmap("A/CHDK/DATA/GPS_needle.txt");
1346     char *bitmap2 = load_bitmap("A/CHDK/DATA/GPS_compass.txt");
1347     int extent = strlen(bitmap1);
1348 
1349     while (exit_compass_task == 0) 
1350     {
1351         lock(3);
1352             angle= draw_gps_course_info(count);
1353             stat = g_d_stat ;
1354         unlock(3);
1355         
1356         count++;
1357         m=n;
1358         
1359         if ((int)angle != 0) { m=angle; }
1360 
1361         switch ( stat )
1362         {
1363             case 0 : 
1364                 f_v_1= COLOR_RED ;
1365 //                 f_h_1= COLOR_RED ;
1366                 break ;
1367             case 1 :
1368                 f_v_1= COLOR_YELLOW ;
1369 //                 f_h_1= COLOR_YELLOW ;
1370                 break ;
1371             case 2 :
1372                 f_v_1= COLOR_GREEN ;
1373 //                 f_h_1= COLOR_GREEN ;
1374                 break ;
1375         }
1376         
1377         if (camera_info.state.gui_mode_none)
1378         {
1379             draw_compass (bitmap2, offset_x - 27, offset_y -14, f_v_0, f_v_1, f_v_2, f_v_4);
1380         }
1381         if (stat == 2 )
1382         {
1383             f_v_1= COLOR_BLUE ;
1384 //             f_h_1= COLOR_BLUE ;
1385         }
1386         if (m>=0 && m<180)
1387         {
1388             w=(180-m)*3.141592653589793/180;
1389         }
1390         if (m >=180 && m<=360)
1391         {
1392             w=(540-m)*3.141592653589793/180;
1393         }
1394 
1395         c_w=cos(w);
1396         s_w=sin(w);
1397 
1398         if (camera_info.state.gui_mode_none)
1399         {
1400             draw_compass_needle (old_angle, old_s_w, old_c_w, bitmap1, extent, m_x, m_y, offset_x, offset_y, f_v_0, f_v_0);
1401             draw_compass_needle (m, s_w, c_w, bitmap1, extent, m_x, m_y, offset_x, offset_y, f_v_1, f_v_3);
1402         }
1403         old_angle=m;
1404         old_c_w=cos(w);
1405         old_s_w=sin(w);
1406         msleep((int)conf.gps_compass_time*1000);
1407     }
1408     if (bitmap1) free(bitmap1) ;
1409     if (bitmap2) free(bitmap2) ;
1410     gps_compass_lock = 0 ;     
1411     ExitTask();
1412 }
1413 
1414 
1415 //=======================================================================
1416 //
1417 //  Functions called from outside this module :
1418 //      - GUI menu support functions
1419 //      - background tasks
1420 //
1421 
1422 // gps_waypoint()
1423 //  - called from spytask after each shot (if gps_waypoint_save is set)
1424 //  - logs current gpx data if available, otherwise starts gpx_no_signal task to wait for data
1425 void gps_waypoint(){     
1426     
1427     char lat[40];
1428     char lon[40];
1429     char hei[40];
1430 
1431     char vBuf[512];
1432     char image_name[20];
1433     char wp_name[30];
1434     char gpx_name[30];
1435     char gpx_image_name[20];
1436 
1437     unsigned long t;
1438     static struct tm *ttm;
1439     t=time(NULL);
1440     ttm = localtime(&t);
1441 
1442     mkdir_if_not_exist("A/GPS");
1443     mkdir_if_not_exist("A/GPS/Tagging");
1444     sprintf(wp_name, "A/GPS/Tagging/%04d_%02d_%02d.wp", ttm->tm_year+1900, ttm->tm_mon+1, ttm->tm_mday);
1445     sprintf(gpx_name, "A/GPS/Tagging/%04d_%02d_%02d.gpx", ttm->tm_year+1900, ttm->tm_mon+1, ttm->tm_mday);
1446     sprintf(image_name, "IMG_%04d.JPG", get_target_file_num());
1447 
1448     lock(4);
1449         int l_stat         = g_d_stat ;
1450         double l_lat       = g_d_lat ;
1451         double l_lon       = g_d_lon ;
1452         double l_hei       = g_d_hei ;
1453         char l_tim[10];
1454         char l_dat[12];
1455         char l_tim_gps[10];
1456         char l_dat_gps[12];   
1457         strncpy( l_tim ,      g_d_tim,     10 );
1458         strncpy( l_dat ,      g_d_dat,     12 );
1459         strncpy( l_tim_gps ,  g_d_tim_gps, 10 );
1460         strncpy( l_dat_gps ,  g_d_dat_gps, 12 );
1461     unlock(4);
1462         
1463     if ((l_stat >= ((int)conf.gps_2D_3D_fix)) || ((((int)conf.gps_2D_3D_fix) == 3) && (l_stat == 2)))
1464     {
1465         sprintf(vBuf, "%s;%s;%s;%s;%sT%sZ;%i\n",
1466                 image_name,
1467                 formatDouble (lat, l_lat, 0, 7),
1468                 formatDouble (lon, l_lon, 0, 7),
1469                 formatDouble (hei, l_hei, 0, 2),
1470                 l_dat, l_tim,
1471                 get_optical_temp());
1472 
1473         FILE* fp = fopen(wp_name, "a");
1474 
1475         if( fp )
1476         {
1477             fwrite(vBuf, strlen(vBuf), 1, fp);
1478         }
1479         fclose(fp);
1480 
1481         fp = fopen(gpx_name, "r");
1482         if( fp == NULL)
1483         {
1484             fp = fopen(gpx_name, "a");
1485             if( fp )
1486             {
1487                 sprintf(vBuf, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
1488                 fwrite(vBuf, strlen(vBuf), 1, fp);
1489                 sprintf(vBuf, "<gpx xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" version=\"1.1\" creator=\"CHDK\" xmlns=\"http://www.topografix.com/GPX/1/1\">\n");
1490                 fwrite(vBuf, strlen(vBuf), 1, fp);
1491                 sprintf(vBuf, "</gpx>");
1492                 fwrite(vBuf, strlen(vBuf), 1, fp);
1493                 fclose(fp);
1494             }
1495         }
1496 
1497 
1498         sprintf(gpx_image_name, "IMG_%04d.JPG", get_target_file_num());
1499 
1500         fp = fopen(gpx_name, "a");
1501         if( fp )
1502         {
1503             fseek (fp, -6, SEEK_END);
1504 
1505             sprintf(vBuf, "   <wpt lat=\"%s\" lon=\"%s\">\n",formatDouble (lat, l_lat, 0, 7), formatDouble (lon, l_lon, 0, 7));
1506             fwrite(vBuf, strlen(vBuf), 1, fp);
1507             sprintf(vBuf, "    <ele>%s</ele>\n",formatDouble (hei, l_hei, 0, 2));
1508             fwrite(vBuf, strlen(vBuf), 1, fp);
1509             sprintf(vBuf, "    <time>%sT%sZ</time>\n", l_dat, l_tim);
1510             fwrite(vBuf, strlen(vBuf), 1, fp);
1511             sprintf(vBuf, "    <gpst>%sT%sZ</gpst>\n", l_dat_gps, l_tim_gps);
1512             fwrite(vBuf, strlen(vBuf), 1, fp);
1513             sprintf(vBuf, "    <temp>%i</temp>\n", (int)get_optical_temp());
1514             fwrite(vBuf, strlen(vBuf), 1, fp);
1515             sprintf(vBuf, "    <name>%s</name>\n", gpx_image_name);
1516             fwrite(vBuf, strlen(vBuf), 1, fp);
1517             sprintf(vBuf, "   </wpt>\n");
1518             fwrite(vBuf, strlen(vBuf), 1, fp);
1519             sprintf(vBuf, "</gpx>");
1520             fwrite(vBuf, strlen(vBuf), 1, fp);
1521         }
1522         fclose(fp);
1523     }
1524     else
1525     {
1526          FILE* fp ;
1527          
1528         sprintf(vBuf, "%s %sT%sZ %i\n",
1529                 image_name,
1530                 l_dat, l_tim,
1531                 get_optical_temp());
1532           
1533         if ( gps_nosignal_lock == 0 )
1534         {              
1535             gps_nosignal_lock = 1 ;            
1536             CreateTask("GPS_NOSIGNAL", 0x19, 0x1200, no_signal_task);
1537             fp = fopen("A/GPS/Tagging/wp.tmp", "w");
1538         }
1539         else
1540         {
1541             fp = fopen("A/GPS/Tagging/wp.tmp", "a");
1542         }
1543         
1544 
1545 
1546         if( fp )
1547         {
1548             fwrite(vBuf, strlen(vBuf), 1, fp);
1549             fclose(fp);
1550         }
1551         
1552         time_to_end=(int)conf.gps_wait_for_signal;
1553     }
1554         
1555 }
1556 
1557 
1558 
1559 void gps_write_timezone(){          // called from gui.c when "Set position as current timezone" is selected in the UI
1560      
1561     char vBuf[30];
1562     char timezone_name[30];
1563 
1564     lock(5);                      // note : kbd task lock = 5
1565         int l_stat   = g_d_stat ;
1566         double l_lat = g_d_lat ;
1567         double l_lon = g_d_lon ;
1568     unlock(5);
1569     
1570     if (l_stat !=0)
1571     {
1572         mkdir_if_not_exist("A/GPS");
1573         mkdir_if_not_exist("A/GPS/Timezone");
1574         sprintf(timezone_name, "A/GPS/Timezone/Timezone.txt");
1575         
1576         FILE* fp = fopen(timezone_name, "w");
1577         if( fp )
1578         {
1579             sprintf(vBuf, "%i\n", (long)(l_lat*10000000));
1580             fwrite(vBuf, strlen(vBuf), 1, fp);
1581             sprintf(vBuf, "%i\n", (long)(l_lon*10000000));
1582             fwrite(vBuf, strlen(vBuf), 1, fp);
1583         }
1584         fclose(fp);
1585     }
1586     else
1587     {
1588         gui_mbox_init(LANG_ERROR, LANG_MENU_GPS_t_1, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL); //No GPS!
1589     }
1590 }
1591 
1592 void gps_write_home(){             // called from gui.c when "Set position as home location" is selected in the UI
1593     
1594     char vBuf[30];
1595     char home_name[30];
1596 
1597     lock(5);                       // note : kbd task lock = 5
1598         int l_stat = g_d_stat ;
1599         double l_lat = g_d_lat ;
1600         double l_lon = g_d_lon ;
1601     unlock(5);
1602         
1603 
1604     if (l_stat !=0)
1605     {
1606         mkdir_if_not_exist("A/GPS");
1607         mkdir_if_not_exist("A/GPS/Navigation");
1608         sprintf(home_name, "A/GPS/Navigation/Home.txt");
1609 
1610         FILE* fp = fopen(home_name, "w");
1611         if( fp )
1612         {
1613             sprintf(vBuf, "%i\n", (long)(l_lat*10000000));
1614             fwrite(vBuf, strlen(vBuf), 1, fp);
1615             sprintf(vBuf, "%i\n", (long)(l_lon*10000000));
1616             fwrite(vBuf, strlen(vBuf), 1, fp);
1617         }
1618         fclose(fp);
1619     }
1620     else
1621     {
1622         gui_mbox_init(LANG_ERROR, LANG_MENU_GPS_t_1, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL); //No GPS!
1623     }
1624 }
1625 
1626 void init_gps_startup(int stop_request)                       // called from spytask
1627 {
1628     if ( stop_request == 0 )
1629     {
1630          if ( gps_data_lock == 0) 
1631         {
1632             exit_data_task = 0;             
1633             gps_data_lock = 1 ;            
1634             CreateTask("GPS_DATA", 0x19, 0x800, gps_data_task);
1635         }
1636     }
1637     else 
1638     {
1639         if ( exit_data_task != 1)
1640         {
1641             exit_data_task =1;        
1642             exit_show_task=1;
1643             exit_record_task=1;
1644             exit_track_task=1;
1645             exit_compass_task=1;
1646             exit_nosignal_task=1;        
1647         }
1648     }
1649 }
1650 
1651 void init_gps_logging_task(int stop_request){               // called from gui.c to start the gpx logging
1652     exit_track_task = exit_record_task = stop_request ;
1653     
1654     if ( stop_request == 0 ) 
1655     {
1656         if (gps_record_lock == 0)
1657         {
1658             gps_record_lock  = 1 ;                
1659             CreateTask("GPS_RECORD", 0x19, 0x800, gps_logging_task);
1660         }
1661 
1662         if (((int)conf.gps_track_symbol==1) && (gps_track_lock == 0))
1663         {
1664             gps_track_lock = 1 ;                
1665             CreateTask("GPS_TRACK", 0x19, 0x800, tracking_icon_task);
1666 
1667         }
1668     } ; 
1669 }
1670 
1671 void init_gps_compass_task(int stop_request){               // called from gui.c to start the GUI compass display
1672         
1673     exit_compass_task = stop_request ; 
1674     if ( stop_request == 0 )
1675     {     
1676         run_compass_task(0);
1677     }   
1678 }
1679 
1680 
1681 int init_gps_navigate_to_home(int stop_request){            // called from gui.c when navigate home selected from GUI
1682 
1683     exit_compass_task = stop_request ;
1684     if ( stop_request == 0 )
1685     {      
1686         char text[2][30];
1687         char home_name[30];
1688         char * endptr;
1689 
1690         sprintf(home_name, "A/GPS/Navigation/Home.txt");
1691 
1692         FILE* fp = fopen(home_name, "r");
1693         if( fp )
1694         {
1695             fgets(text[1], 15, fp);
1696             fgets(text[2], 15, fp);
1697         }
1698         fclose(fp);
1699 
1700         g_d_lat_nav = (strtol (text[1], &endptr, 10 )) / 10000000.0;
1701         g_d_lon_nav = (strtol (text[2], &endptr, 10 )) / 10000000.0;
1702 
1703         if ((int)g_d_lat_nav != 0)
1704         {        
1705             run_compass_task(2);          
1706             return(1);
1707         }
1708         else
1709         {
1710             gui_mbox_init(LANG_ERROR, LANG_MENU_GPS_t_7, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL); //Navigation to Home Loc is not possible!
1711             navigation_mode=0;
1712         }
1713     }
1714     return(0);
1715 }
1716 
1717 int init_gps_navigate_to_photo(int stop_request){                  // called from gui.c when show navi selected by GUI
1718 
1719     exit_compass_task = stop_request ; 
1720 
1721     if (stop_request == 0)
1722     {      
1723         gps_img_data *igps = ( gps_img_data *) camera_jpeg_current_gps();
1724 
1725         g_d_lat_nav=0.0;
1726         g_d_lon_nav=0.0;
1727 
1728         char image[9];
1729         strncpy(image, camera_jpeg_current_filename(),8) ;
1730         image[8] = '\0';
1731 
1732         if (igps->latitudeRef[0] && igps->longitudeRef[0])
1733         {
1734             g_d_lat_nav=(double)igps->latitude[0]/(double)igps->latitude[1]*1.0 +
1735                                  igps->latitude[2]/(igps->latitude[3]*60.0) +
1736                                  igps->latitude[4]/(igps->latitude[5]*3600.0);
1737             if (igps->latitudeRef[0] == 'S') g_d_lat_nav = -g_d_lat_nav;
1738             g_d_lon_nav=(double)igps->longitude[0]/(double)igps->longitude[1]*1.0 +
1739                                  igps->longitude[2]/(igps->longitude[3]*60.0) +
1740                                  igps->longitude[4]/(igps->longitude[5]*3600.0);
1741             if (igps->longitudeRef[0] == 'W') g_d_lon_nav = -g_d_lon_nav;
1742              
1743             run_compass_task(1);
1744             return(1);
1745         }
1746         else
1747         {
1748             char vBuf[256];
1749             sprintf(vBuf, lang_str(LANG_MENU_GPS_t_8), image);  //"Cant navigate to photo: %s!"
1750             gui_mbox_init(LANG_ERROR, (int)vBuf, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL); //Cant navigate to photo: %s!
1751             navigation_mode=0;
1752         }
1753     }   
1754     return(0) ;
1755 }
1756 
1757 
1758 /****  eof  ****/

/* [<][>][^][v][top][bottom][index][help] */