Rev 360 | Rev 491 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 360 | Rev 490 | ||
---|---|---|---|
Line 51... | Line 51... | ||
51 | // + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations. |
51 | // + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations. |
52 | // + *) The territory aspect only refers to the place where the Software is used, not its programmed range. |
52 | // + *) The territory aspect only refers to the place where the Software is used, not its programmed range. |
53 | // + #### END OF LICENSING TERMS #### |
53 | // + #### END OF LICENSING TERMS #### |
54 | // + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de. |
54 | // + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de. |
55 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
55 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
56 | - | ||
- | 56 | #include <ctype.h> |
|
- | 57 | #include <stdio.h> |
|
- | 58 | #include <stdlib.h> |
|
57 | #include <string.h> |
59 | #include <string.h> |
58 | #include "91x_lib.h" |
60 | #include "91x_lib.h" |
59 | #include "waypoints.h" |
61 | #include "waypoints.h" |
60 | #include "uart1.h" |
62 | #include "uart1.h" |
- | 63 | #include "fat16.h" |
|
Line 61... | Line 64... | ||
61 | 64 | ||
62 | // the waypoints list |
65 | // the waypoints list |
Line 63... | Line 66... | ||
63 | #define MAX_LIST_LEN 101 |
66 | #define MAX_LIST_LEN 101 |
Line 95... | Line 98... | ||
95 | PointList[i].Position.Longitude = 0; |
98 | PointList[i].Position.Longitude = 0; |
96 | PointList[i].Position.Altitude = 0; |
99 | PointList[i].Position.Altitude = 0; |
97 | PointList[i].Heading = 361; // invalid value |
100 | PointList[i].Heading = 361; // invalid value |
98 | PointList[i].ToleranceRadius = 0; // in meters, if the MK is within that range around the target, then the next target is triggered |
101 | PointList[i].ToleranceRadius = 0; // in meters, if the MK is within that range around the target, then the next target is triggered |
99 | PointList[i].HoldTime = 0; // in seconds, if the was once in the tolerance area around a WP, this time defines the delay before the next WP is triggered |
102 | PointList[i].HoldTime = 0; // in seconds, if the was once in the tolerance area around a WP, this time defines the delay before the next WP is triggered |
100 | PointList[i].Type = POINT_TYPE_INVALID; |
- | |
101 | PointList[i].Event_Flag = 0; // future implementation |
103 | PointList[i].Event_Flag = 0; // future implementation |
- | 104 | PointList[i].Index = 0; |
|
- | 105 | PointList[i].Type = POINT_TYPE_INVALID; |
|
- | 106 | PointList[i].WP_EventChannelValue = 0; |
|
102 | PointList[i].AltitudeRate = 0; // no change of setpoint |
107 | PointList[i].AltitudeRate = 0; // no change of setpoint |
- | 108 | PointList[i].Speed = 0; |
|
- | 109 | PointList[i].CamAngle = 0; |
|
- | 110 | PointList[i].Name[0] = 0; |
|
103 | } |
111 | } |
104 | return TRUE; |
112 | return TRUE; |
105 | } |
113 | } |
Line 106... | Line 114... | ||
106 | 114 | ||
Line 141... | Line 149... | ||
141 | PointCount++; |
149 | PointCount++; |
142 | break; |
150 | break; |
143 | } |
151 | } |
144 | break; |
152 | break; |
Line 145... | Line 153... | ||
145 | 153 | ||
146 | case POINT_TYPE_WP: // was a waypoint |
154 | case POINT_TYPE_WP: // was a waypoint |
147 | switch(pPoint->Type) |
155 | switch(pPoint->Type) |
148 | { |
156 | { |
149 | case POINT_TYPE_INVALID: |
157 | case POINT_TYPE_INVALID: |
150 | WPCount--; |
158 | WPCount--; |
Line 342... | Line 350... | ||
342 | Point_t* PointList_GetPOI(void) |
350 | Point_t* PointList_GetPOI(void) |
343 | { |
351 | { |
344 | return PointList_GetAt(POIIndex); |
352 | return PointList_GetAt(POIIndex); |
345 | } |
353 | } |
Line -... | Line 354... | ||
- | 354 | ||
- | 355 | #define LINE_MAX 70 |
|
- | 356 | #define WP_FILE_VERSION_COMPATIBLE 3 |
|
- | 357 | // save actual point list to SD card |
|
- | 358 | u8 PointList_SaveToFile(u8 place) |
|
- | 359 | { |
|
- | 360 | File_t *fp; |
|
- | 361 | s8 wpline[LINE_MAX], retval = 0; |
|
- | 362 | // user absolute path, i.e. leading / |
|
- | 363 | ||
- | 364 | sprintf(wpline, "/list_%03d.wpl", place); |
|
- | 365 | ||
- | 366 | UART1_PutString("\n\r Write "); |
|
- | 367 | UART1_PutString(wpline); |
|
- | 368 | UART1_PutString("..."); |
|
- | 369 | ||
- | 370 | UART1_PutString("\n\r Save WPL..."); |
|
- | 371 | ||
- | 372 | if(Fat16_IsValid()) |
|
- | 373 | { // check if wpl file is existing |
|
- | 374 | fp = fopen_(wpline, 'w'); // try to open the file |
|
- | 375 | if(fp == NULL) |
|
- | 376 | { |
|
- | 377 | UART1_PutString("ERROR: Creating waypoint file!\r\n"); |
|
- | 378 | return(retval); |
|
- | 379 | } |
|
- | 380 | // Create general section and key entries |
|
- | 381 | fputs_("[General]\r\n", fp); |
|
- | 382 | sprintf(wpline, "FileVersion=%d\r\n", WP_FILE_VERSION_COMPATIBLE); |
|
- | 383 | fputs_(wpline, fp); |
|
- | 384 | sprintf(wpline, "NumberOfWaypoints=%d\r\n", PointCount); |
|
- | 385 | fputs_(wpline, fp); |
|
- | 386 | // dump all points if existent |
|
- | 387 | if(PointCount) |
|
- | 388 | { |
|
- | 389 | u8 i, u8_1; |
|
- | 390 | s32 i32_1, i32_2; |
|
- | 391 | ||
- | 392 | for (i = 0; i < PointCount; i++) |
|
- | 393 | { |
|
- | 394 | sprintf(wpline, "[Point%d]\r\n",PointList[i].Index); |
|
- | 395 | fputs_(wpline, fp); |
|
- | 396 | // write latitude in deg |
|
- | 397 | if(PointList[i].Position.Latitude < 0) u8_1 = '-'; |
|
- | 398 | else u8_1 = '+'; |
|
- | 399 | i32_1 = abs(PointList[i].Position.Latitude)/10000000L; |
|
- | 400 | i32_2 = abs(PointList[i].Position.Latitude)%10000000L; |
|
- | 401 | sprintf(wpline, "Latitude=%c%ld.%07ld\r\n", u8_1, i32_1, i32_2); |
|
- | 402 | fputs_(wpline, fp); |
|
- | 403 | // write longitude in deg |
|
- | 404 | if(PointList[i].Position.Longitude < 0) u8_1 = '-'; |
|
- | 405 | else u8_1 = '+'; |
|
- | 406 | i32_1 = abs(PointList[i].Position.Longitude)/10000000L; |
|
- | 407 | i32_2 = abs(PointList[i].Position.Longitude)%10000000L; |
|
- | 408 | sprintf(wpline, "Longitude=%c%ld.%07ld\r\n", u8_1, i32_1, i32_2); |
|
- | 409 | fputs_(wpline, fp); |
|
- | 410 | // write tolerace radius in m |
|
- | 411 | sprintf(wpline, "Radius=%d\r\n", PointList[i].ToleranceRadius); |
|
- | 412 | fputs_(wpline, fp); |
|
- | 413 | // write altitude in m |
|
- | 414 | if(PointList[i].Position.Altitude < 0) u8_1 = '-'; |
|
- | 415 | else u8_1 = '+'; |
|
- | 416 | if(PointList[i].Type == POINT_TYPE_POI) |
|
- | 417 | { |
|
- | 418 | i32_1 = abs(PointList[i].Position.Altitude)/100L; // cm --> m |
|
- | 419 | i32_2 = abs(PointList[i].Position.Altitude)%100L; |
|
- | 420 | } |
|
- | 421 | else |
|
- | 422 | { |
|
- | 423 | i32_1 = abs(PointList[i].Position.Altitude)/10L; // dm --> m |
|
- | 424 | i32_2 = abs(PointList[i].Position.Altitude)%10L; |
|
- | 425 | } |
|
- | 426 | sprintf(wpline, "Altitude=%c%ld.%01ld\r\n", u8_1, i32_1, i32_2); |
|
- | 427 | fputs_(wpline, fp); |
|
- | 428 | // write climb rate in 0.1 m/s |
|
- | 429 | sprintf(wpline, "ClimbRate=%d\r\n", PointList[i].AltitudeRate); |
|
- | 430 | fputs_(wpline, fp); |
|
- | 431 | // write hold time in s |
|
- | 432 | sprintf(wpline, "DelayTime=%d\r\n", PointList[i].HoldTime); |
|
- | 433 | fputs_(wpline, fp); |
|
- | 434 | // write event channel value |
|
- | 435 | sprintf(wpline, "WP_Event_Channel_Value=%d\r\n", PointList[i].WP_EventChannelValue); |
|
- | 436 | fputs_(wpline, fp); |
|
- | 437 | // write heading in deg (0= nothing, neg. values index to poi) |
|
- | 438 | sprintf(wpline, "Heading=%d\r\n", PointList[i].Heading); |
|
- | 439 | fputs_(wpline, fp); |
|
- | 440 | // write speed in 0.1 m/s |
|
- | 441 | sprintf(wpline, "Speed=%d\r\n", PointList[i].Speed); |
|
- | 442 | fputs_(wpline, fp); |
|
- | 443 | // write cam angle in degree (255 -> POI-Automatic) |
|
- | 444 | sprintf(wpline, "CAM-Nick=%d\r\n", PointList[i].CamAngle); |
|
- | 445 | fputs_(wpline, fp); |
|
- | 446 | // write point type |
|
- | 447 | sprintf(wpline, "Type=%d\r\n", PointList[i].Type + 1); |
|
- | 448 | fputs_(wpline, fp); |
|
- | 449 | // write prefix |
|
- | 450 | //if(PointList[i].Type == POINT_TYPE_WP) u8_1 = 'P'; |
|
- | 451 | //else u8_1 = '0'; |
|
- | 452 | sprintf(wpline, "Prefix=%s\r\n", PointList[i].Name); |
|
- | 453 | fputs_(wpline, fp); |
|
- | 454 | } // EOF loop over all points |
|
- | 455 | } // EOF if(PointCount) |
|
- | 456 | if(EOF == fclose_(fp)) |
|
- | 457 | { |
|
- | 458 | UART1_PutString("failed!\r\n"); |
|
- | 459 | } |
|
- | 460 | else |
|
- | 461 | { |
|
- | 462 | UART1_PutString("ok\r\n"); |
|
- | 463 | retval = 1; |
|
- | 464 | } |
|
- | 465 | } // EOF if(Fat16_IsValid()) |
|
- | 466 | UART1_PutString("no file system found!\r\n"); |
|
- | 467 | return(retval); |
|
- | 468 | } |
|
- | 469 | ||
- | 470 | // load actual point list from SD card |
|
- | 471 | u8 PointList_ReadFromFile(u8 place) |
|
- | 472 | { |
|
- | 473 | File_t *fp; |
|
- | 474 | s8 wpline[LINE_MAX], retval = 0; |
|
- | 475 | ||
- | 476 | s8 *name, *value; |
|
- | 477 | u8 i; |
|
- | 478 | ||
- | 479 | u8 IsGeneralSection = 0; |
|
- | 480 | u8 IsPointSection = 0; |
|
- | 481 | u8 WPNumber = 0; |
|
- | 482 | ||
- | 483 | // user absolute path, i.e. leading / |
|
- | 484 | sprintf(wpline, "/list_%03d.wpl", place); |
|
- | 485 | ||
- | 486 | UART1_PutString("\n\r Read "); |
|
- | 487 | UART1_PutString(wpline); |
|
- | 488 | UART1_PutString("..."); |
|
- | 489 | ||
- | 490 | if(Fat16_IsValid()) |
|
- | 491 | { // check if wpl file is existing |
|
- | 492 | fp = fopen_(wpline, 'r'); // try to open the file |
|
- | 493 | if(fp == NULL) |
|
- | 494 | { |
|
- | 495 | UART1_PutString("ERROR: Reading waypoint file!\r\n"); |
|
- | 496 | return(0); |
|
- | 497 | } |
|
- | 498 | // clear point list first |
|
- | 499 | PointList_Clear(); |
|
- | 500 | // read all lines from file |
|
- | 501 | while(fgets_(wpline, LINE_MAX, fp) != 0) |
|
- | 502 | { |
|
- | 503 | if ( // ignorelines starting with \r,\n,' ',';','#' |
|
- | 504 | (wpline[0] != '\n') && |
|
- | 505 | (wpline[0] != '\r') && |
|
- | 506 | (wpline[0] != ' ' ) && |
|
- | 507 | (wpline[0] != ';' ) && |
|
- | 508 | (wpline[0] != '#' ) |
|
- | 509 | ) |
|
- | 510 | { |
|
- | 511 | // check for section line found |
|
- | 512 | if(wpline[0] == '[') |
|
- | 513 | { |
|
- | 514 | // next section found |
|
- | 515 | IsGeneralSection = 0; |
|
- | 516 | IsPointSection = 0; |
|
- | 517 | ||
- | 518 | name = strtok(&wpline[1], "]"); |
|
- | 519 | if(name != NULL) // if section name |
|
- | 520 | { |
|
- | 521 | // check section type |
|
- | 522 | for(i=0; name[i]; i++) name[i] = toupper(name[i]); // convert to upper case |
|
- | 523 | ||
- | 524 | if(strncmp(name, "POINT", 5) == 0) |
|
- | 525 | { |
|
- | 526 | IsPointSection = (u8)atoi(&name[5]); |
|
- | 527 | PointCount++; |
|
- | 528 | } |
|
- | 529 | else if(strcmp(name, "GENERAL") == 0) |
|
- | 530 | { |
|
- | 531 | IsGeneralSection = 1; |
|
- | 532 | } |
|
- | 533 | else |
|
- | 534 | { |
|
- | 535 | UART1_PutString("Unknown section: "); |
|
- | 536 | UART1_PutString(name); |
|
- | 537 | UART1_PutString("\r\n"); |
|
- | 538 | } |
|
- | 539 | } |
|
- | 540 | } // EOF section line |
|
- | 541 | else |
|
- | 542 | { // look for key entrys of each sections |
|
- | 543 | name = strtok(wpline, "="); // get name |
|
- | 544 | value = strtok(NULL, "="); // get value |
|
- | 545 | if ((name != NULL) && (value != NULL)) |
|
- | 546 | { |
|
- | 547 | for(i=0; name[i]; i++) name[i] = toupper(name[i]); // convert to upper case |
|
- | 548 | if(IsPointSection && (IsPointSection <= WPNumber)) |
|
- | 549 | { |
|
- | 550 | if(strcmp(name, "LATITUDE") == 0) |
|
- | 551 | { |
|
- | 552 | PointList[IsPointSection-1].Position.Latitude = (s32)(atof(value) * 1E7); |
|
- | 553 | } |
|
- | 554 | else if(strcmp(name, "LONGITUDE") == 0) |
|
- | 555 | { |
|
- | 556 | PointList[IsPointSection-1].Position.Longitude = (s32)(atof(value) * 1E7); |
|
- | 557 | } |
|
- | 558 | else if(strcmp(name, "RADIUS") == 0) |
|
- | 559 | { |
|
- | 560 | PointList[IsPointSection-1].ToleranceRadius = (u8)atoi(value); |
|
- | 561 | } |
|
- | 562 | else if(strcmp(name, "ALTITUDE") == 0) |
|
- | 563 | { |
|
- | 564 | PointList[IsPointSection-1].Position.Altitude = (s32)(atof(value) * 100.0); // in cm |
|
- | 565 | PointList[IsPointSection-1].Position.Status = NEWDATA; |
|
- | 566 | } |
|
- | 567 | else if(strcmp(name, "CLIMBRATE") == 0) |
|
- | 568 | { |
|
- | 569 | PointList[IsPointSection-1].AltitudeRate = (u8)atoi(value); |
|
- | 570 | } |
|
- | 571 | else if(strcmp(name, "DELAYTIME") == 0) |
|
- | 572 | { |
|
- | 573 | PointList[IsPointSection-1].HoldTime = (u8)atoi(value); |
|
- | 574 | } |
|
- | 575 | else if(strcmp(name, "WP_EVENT_CHANNEL_VALUE") == 0) |
|
- | 576 | { |
|
- | 577 | PointList[IsPointSection-1].WP_EventChannelValue = (u8)atoi(value); |
|
- | 578 | } |
|
- | 579 | else if(strcmp(name, "HEADING") == 0) |
|
- | 580 | { |
|
- | 581 | PointList[IsPointSection-1].Heading = (s16)atoi(value); |
|
- | 582 | } |
|
- | 583 | else if(strcmp(name, "SPEED") == 0) |
|
- | 584 | { |
|
- | 585 | PointList[IsPointSection-1].Speed = (u8)atoi(value); |
|
- | 586 | } |
|
- | 587 | else if(strcmp(name, "CAM-NICK") == 0) |
|
- | 588 | { |
|
- | 589 | PointList[IsPointSection-1].CamAngle = (u8)atoi(value); |
|
- | 590 | } |
|
- | 591 | else if(strcmp(name, "TYPE") == 0) |
|
- | 592 | { |
|
- | 593 | PointList[IsPointSection-1].Type = (u8)atoi(value); |
|
- | 594 | if(PointList[IsPointSection-1].Type > 0) PointList[IsPointSection-1].Type--; // index shift |
|
- | 595 | else PointList[IsPointSection-1].Type = POINT_TYPE_INVALID; |
|
- | 596 | ||
- | 597 | switch(PointList[IsPointSection-1].Type) |
|
- | 598 | { |
|
- | 599 | case POINT_TYPE_WP: |
|
- | 600 | // this works only if altitude key is set before point type key in WPL file !! |
|
- | 601 | PointList[IsPointSection-1].Position.Altitude /= 10; // dm only for WPs |
|
- | 602 | WPCount++; |
|
- | 603 | break; |
|
- | 604 | ||
- | 605 | case POINT_TYPE_POI: |
|
- | 606 | POICount++; |
|
- | 607 | break; |
|
- | 608 | } |
|
- | 609 | } |
|
- | 610 | else if(strcmp(name, "PREFIX") == 0) |
|
- | 611 | { |
|
- | 612 | strncpy(PointList[IsPointSection-1].Name, value, 4); |
|
- | 613 | PointList[IsPointSection-1].Name[3] = 0; // Terminate string |
|
- | 614 | } |
|
- | 615 | else |
|
- | 616 | { |
|
- | 617 | UART1_PutString("Unknown key: "); |
|
- | 618 | UART1_PutString(name); |
|
- | 619 | UART1_PutString("\r\n"); |
|
- | 620 | } |
|
- | 621 | } // EOF point section |
|
- | 622 | else if(IsGeneralSection) |
|
- | 623 | { |
|
- | 624 | if(strcmp(name, "NUMBEROFWAYPOINTS") == 0) |
|
- | 625 | { |
|
- | 626 | WPNumber = (u8)atoi(value); |
|
- | 627 | if(!WPNumber) // no waypoints in file |
|
- | 628 | { |
|
- | 629 | return(1); // we are done here |
|
- | 630 | } |
|
- | 631 | else if(WPNumber > MAX_LIST_LEN) // number o points larger than ram list |
|
- | 632 | { |
|
- | 633 | UART1_PutString("To much points!"); |
|
- | 634 | return(0); |
|
- | 635 | } |
|
- | 636 | } |
|
- | 637 | else if (strcmp(name, "FILEVERSION") == 0) |
|
- | 638 | { |
|
- | 639 | if((u8)atoi(value) != WP_FILE_VERSION_COMPATIBLE) |
|
- | 640 | { |
|
- | 641 | UART1_PutString("Bad file version!\r\n"); |
|
- | 642 | return(0); |
|
- | 643 | } |
|
- | 644 | } |
|
- | 645 | else |
|
- | 646 | { |
|
- | 647 | UART1_PutString("Unknown key: "); |
|
- | 648 | UART1_PutString(name); |
|
- | 649 | UART1_PutString("\r\n"); |
|
- | 650 | } |
|
- | 651 | } // EOF general section |
|
- | 652 | } // EOF valid key entry |
|
- | 653 | } // EOF key entry line |
|
- | 654 | } // valid line |
|
- | 655 | } // EOF loop over all lines |
|
- | 656 | fclose_(fp); |
|
- | 657 | NaviData.WaypointNumber = WPCount; |
|
- | 658 | UART1_PutString("ok\r\n"); |
|
- | 659 | retval = 1; |
|
- | 660 | } // EOF if(Fat16_IsValid()) |
|
- | 661 | else UART1_PutString("no file system found!\r\n"); |
|
- | 662 | return(retval); |
|
- | 663 | } |