diff options
| -rw-r--r-- | .clang-format | 45 | ||||
| -rw-r--r-- | .clang-tidy | 19 | ||||
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | compile_flags.txt | 10 | ||||
| -rw-r--r-- | config.mk | 2 | ||||
| -rw-r--r-- | makefile | 15 | ||||
| -rw-r--r-- | src/main.cpp | 86 |
7 files changed, 179 insertions, 0 deletions
diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..ff96bb5 --- /dev/null +++ b/.clang-format | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | --- | ||
| 2 | AccessModifierOffset: -4 | ||
| 3 | AlignConsecutiveAssignments: 'true' | ||
| 4 | AlignConsecutiveDeclarations: 'true' | ||
| 5 | AlignEscapedNewlines: Left | ||
| 6 | AlignTrailingComments: 'true' | ||
| 7 | AlwaysBreakAfterReturnType: TopLevelDefinitions | ||
| 8 | BreakBeforeBraces: Stroustrup | ||
| 9 | BreakConstructorInitializers: BeforeComma | ||
| 10 | BreakInheritanceList: BeforeComma | ||
| 11 | ColumnLimit: '0' | ||
| 12 | CompactNamespaces: 'false' | ||
| 13 | Cpp11BracedListStyle: 'false' | ||
| 14 | FixNamespaceComments: 'true' | ||
| 15 | IncludeBlocks: Regroup | ||
| 16 | IncludeCategories: | ||
| 17 | - Regex: '^.*(precomp|pch|stdafx)' | ||
| 18 | Priority: -1 | ||
| 19 | - Regex: '^<.*>' | ||
| 20 | Priority: 1 | ||
| 21 | - Regex: '^".*"' | ||
| 22 | Priority: 2 | ||
| 23 | - Regex: '.*' | ||
| 24 | Priority: 3 | ||
| 25 | IndentCaseLabels: 'false' | ||
| 26 | IndentPPDirectives: AfterHash | ||
| 27 | IndentWidth: '4' | ||
| 28 | IndentWrappedFunctionNames: 'false' | ||
| 29 | KeepEmptyLinesAtTheStartOfBlocks: 'false' | ||
| 30 | PointerAlignment: Left | ||
| 31 | SortIncludes: 'true' | ||
| 32 | SpaceAfterCStyleCast: 'true' | ||
| 33 | SpaceAfterTemplateKeyword: 'false' | ||
| 34 | SpaceBeforeAssignmentOperators: 'true' | ||
| 35 | SpaceBeforeParens: ControlStatements | ||
| 36 | SpaceBeforeRangeBasedForLoopColon: 'false' | ||
| 37 | SpaceInEmptyParentheses: 'false' | ||
| 38 | SpacesInAngles: 'false' | ||
| 39 | SpacesInCStyleCastParentheses: 'false' | ||
| 40 | SpacesInConditionalStatement: 'true' | ||
| 41 | SpacesInParentheses: 'false' | ||
| 42 | Standard: Auto | ||
| 43 | TabWidth: '4' | ||
| 44 | UseTab: ForIndentation | ||
| 45 | ... | ||
diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..0bceb5b --- /dev/null +++ b/.clang-tidy | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | --- | ||
| 2 | Checks: "*, | ||
| 3 | -abseil-*, | ||
| 4 | -altera-*, | ||
| 5 | -android-*, | ||
| 6 | -fuchsia-*, | ||
| 7 | -google-*, | ||
| 8 | -llvm*, | ||
| 9 | -modernize-use-trailing-return-type, | ||
| 10 | -zircon-*, | ||
| 11 | -readability-else-after-return, | ||
| 12 | -readability-static-accessed-through-instance, | ||
| 13 | -readability-avoid-const-params-in-decls, | ||
| 14 | -cppcoreguidelines-non-private-member-variables-in-classes, | ||
| 15 | -misc-non-private-member-variables-in-classes, | ||
| 16 | " | ||
| 17 | WarningsAsErrors: '' | ||
| 18 | HeaderFilterRegex: '' | ||
| 19 | FormatStyle: none | ||
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cd42ee3 --- /dev/null +++ b/.gitignore | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | bin/ | ||
| 2 | obj/ | ||
diff --git a/compile_flags.txt b/compile_flags.txt new file mode 100644 index 0000000..3ea2c1a --- /dev/null +++ b/compile_flags.txt | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | -Wall | ||
| 2 | -Werror | ||
| 3 | -Wextra | ||
| 4 | -Wconversion | ||
| 5 | -Wdouble-promotion | ||
| 6 | -pedantic | ||
| 7 | -std=c++17 | ||
| 8 | -Iinclude | ||
| 9 | -I../minmea/include | ||
| 10 | -I/usr/local/include | ||
diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..29f8ca1 --- /dev/null +++ b/config.mk | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | CPPFLAGS=-Wall -Werror -pedantic -std=c++17 -O2 -Iinclude -I../minmea/include -I/usr/local/include -DNDEBUG | ||
| 2 | LDFLAGS=-L../minmea/lib -lminmea -L/usr/local/lib -lpthread | ||
diff --git a/makefile b/makefile new file mode 100644 index 0000000..3f481bc --- /dev/null +++ b/makefile | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | include config.mk | ||
| 2 | |||
| 3 | bin/app: obj/main.o | bin | ||
| 4 | c++ $(LDFLAGS) $^ -o $@ | ||
| 5 | |||
| 6 | obj/%.o: src/%.cpp | obj | ||
| 7 | c++ $(CPPFLAGS) -c $< -o $@ | ||
| 8 | |||
| 9 | clean: | ||
| 10 | rm -rf bin obj | ||
| 11 | |||
| 12 | bin obj: | ||
| 13 | mkdir $@ | ||
| 14 | |||
| 15 | .PHONY: all clean | ||
diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..e699c6a --- /dev/null +++ b/src/main.cpp | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | #include <asio.hpp> | ||
| 2 | #include <ctime> | ||
| 3 | #include <iostream> | ||
| 4 | #include <string> | ||
| 5 | |||
| 6 | #include "minmea.h" | ||
| 7 | |||
| 8 | using namespace std; | ||
| 9 | |||
| 10 | // constexpr auto PORT = "/dev/cuaU0"; | ||
| 11 | constexpr auto PORT = "/dev/ugen0.14"; | ||
| 12 | constexpr auto BAUDRATE = 9600; | ||
| 13 | |||
| 14 | namespace { | ||
| 15 | |||
| 16 | auto | ||
| 17 | read_line(asio::serial_port& com) | ||
| 18 | { | ||
| 19 | for ( string result;; ) { | ||
| 20 | char chr = 0; | ||
| 21 | |||
| 22 | asio::read(com, asio::buffer(&chr, 1)); | ||
| 23 | switch ( chr ) { | ||
| 24 | case '\r': | ||
| 25 | break; | ||
| 26 | case '\n': | ||
| 27 | return result; | ||
| 28 | default: | ||
| 29 | result += chr; | ||
| 30 | } | ||
| 31 | } | ||
| 32 | } | ||
| 33 | |||
| 34 | string | ||
| 35 | get_gps_timestamp(const minmea_time& time, const minmea_date& date) | ||
| 36 | { | ||
| 37 | tm tm_utc{}; | ||
| 38 | ::minmea_getdatetime(&tm_utc, &date, &time); | ||
| 39 | |||
| 40 | auto timestamp = ::timegm(&tm_utc); | ||
| 41 | |||
| 42 | tm tm_local{}; | ||
| 43 | (void) ::localtime_r(×tamp, &tm_local); | ||
| 44 | |||
| 45 | static const auto buffer_size = 100; | ||
| 46 | array<char, buffer_size> buffer{}; | ||
| 47 | |||
| 48 | (void) ::strftime(buffer.data(), buffer.size(), "%Y-%m-%d %H:%M:%S", &tm_local); | ||
| 49 | |||
| 50 | return buffer.data(); | ||
| 51 | } | ||
| 52 | |||
| 53 | } // namespace | ||
| 54 | |||
| 55 | int | ||
| 56 | main() | ||
| 57 | { | ||
| 58 | try { | ||
| 59 | asio::io_context io_context{}; | ||
| 60 | asio::serial_port com(io_context, PORT); | ||
| 61 | com.set_option(asio::serial_port::baud_rate(BAUDRATE)); | ||
| 62 | |||
| 63 | for ( ;; ) { | ||
| 64 | const auto line = read_line(com); | ||
| 65 | const auto nmea_id = ::minmea_sentence_id(line.c_str(), true); | ||
| 66 | |||
| 67 | if ( nmea_id != MINMEA_SENTENCE_RMC ) { | ||
| 68 | continue; | ||
| 69 | } | ||
| 70 | |||
| 71 | minmea_sentence_rmc frame{}; | ||
| 72 | if ( !::minmea_parse_rmc(&frame, line.c_str()) || !frame.valid ) { | ||
| 73 | continue; | ||
| 74 | } | ||
| 75 | |||
| 76 | auto timestamp = get_gps_timestamp(frame.time, frame.date); | ||
| 77 | |||
| 78 | cout << timestamp << ": $RMC floating point degree coordinates and speed: (" | ||
| 79 | << ::minmea_tocoord(&frame.latitude) << "," << ::minmea_tocoord(&frame.longitude) << ") " | ||
| 80 | << ::minmea_tofloat(&frame.speed) << '\n'; | ||
| 81 | } | ||
| 82 | } | ||
| 83 | catch ( exception& e ) { | ||
| 84 | cerr << "io-error: " << e.what() << '\n'; | ||
| 85 | } | ||
| 86 | } | ||
