Version 0.6.1
[marnav.git] / examples / read_nmea_boostasio.cpp
blobacef1f406479f87b59c95cc1068e880acb62890d
1 /// This example shows how to use Boost.ASIO in order to read synchronously
2 /// NMEA data from a serial port.
4 #include <iostream>
5 #include <boost/asio.hpp>
6 #include <marnav/io/default_nmea_reader.hpp>
7 #include <marnav/nmea/nmea.hpp>
8 #include <marnav/nmea/rmc.hpp>
9 #include <marnav/nmea/io.hpp>
11 namespace marnav_example
14 /// Synchronous reading of the serial port using Boost.ASIO
15 class boost_asio_serial : public marnav::io::device
17 public:
18 boost_asio_serial(const std::string & port)
19 : io()
20 , serial(io, port)
22 serial.set_option(boost::asio::serial_port_base::baud_rate(4800));
25 virtual void open() override {}
27 virtual void close() override { serial.close(); }
29 virtual int read(char * buffer, uint32_t size) override
31 if ((buffer == nullptr) || (size == 0))
32 throw std::invalid_argument{"invalid buffer or size"};
33 if (!serial.is_open())
34 throw std::runtime_error{"device not open"};
36 return boost::asio::read(serial, boost::asio::buffer(buffer, size));
39 virtual int write(const char *, uint32_t) override
41 throw std::runtime_error{"operation not supported"};
44 private:
45 boost::asio::io_service io;
46 boost::asio::serial_port serial;
49 /// This subclassing is not really necessary, but hides the instantiation
50 /// of boost_asio_serial from normal usage (see function 'main'). This way
51 /// it is completley transparent whether or not Boost.ASIO is in use or not
52 /// from the perspective of just using it.
53 class sentence_reader : public marnav::io::default_nmea_reader
55 public:
56 sentence_reader(const std::string & port)
57 : default_nmea_reader(std::unique_ptr<marnav::io::device>{new boost_asio_serial{port}})
63 int main(int, char **)
65 using namespace marnav;
67 // create and open the device for reading.
68 marnav_example::sentence_reader reader{"/dev/ttyUSB0"};
70 std::string data;
72 // read and process NMEA sentences, bus synchronization is done automatically.
73 while (reader.read_sentence(data)) {
74 // data was successfully read from the NMEA bus, inclusive synchronization
75 // of NMEA sentences. This means it is possible to begin to listen on the
76 // bus at any time.
77 auto sentence = nmea::make_sentence(data);
79 // do something with the sentence, for example dump the position
80 if (sentence->id() == nmea::sentence_id::RMC) {
81 auto rmc = nmea::sentence_cast<nmea::rmc>(sentence);
82 std::cout << "latitude : " << nmea::to_string(rmc->get_latitude()) << "\n";
83 std::cout << "longitude: " << nmea::to_string(rmc->get_longitude()) << "\n";