Program Listing for File serial.h

Return to documentation for file (/tmp/ws/src/libcreate/include/create/serial.h)

// Based on example from:
//   https://github.com/labust/labust-ros-pkg/wiki/Create-a-Serial-Port-application

#ifndef CREATE_SERIAL_H
#define CREATE_SERIAL_H

#include <condition_variable>
#include <functional>
#include <memory>
#include <mutex>
#include <thread>

#include <boost/asio.hpp>

#include "create/data.h"
#include "create/types.h"
#include "create/util.h"

namespace create {
  class Serial : public std::enable_shared_from_this<Serial> {

    protected:
      boost::asio::io_service io;
      boost::asio::signal_set signals;
      boost::asio::serial_port port;

    private:
      std::thread ioThread;
      std::condition_variable dataReadyCond;
      std::mutex dataReadyMut;
      bool dataReady;
      bool isReading;
      bool firstRead;
      uint8_t byteRead;

      // Callback executed when data arrives from Create
      void onData(const boost::system::error_code& e, const std::size_t& size);
      // Callback to execute once data arrives
      std::function<void()> callback;
      // Start and stop reading data from Create
      bool startReading();
      void stopReading();
      bool openPort(const std::string& portName, const int& baud);
      bool closePort();

    protected:
      std::shared_ptr<Data> data;
      // These are for possible diagnostics
      uint64_t corruptPackets;
      uint64_t totalPackets;

      virtual bool startSensorStream() = 0;
      virtual void processByte(uint8_t byteRead) = 0;

      void signalHandler(const boost::system::error_code& error, int signal_number);
      // Notifies main thread that data is fresh and makes the user callback
      void notifyDataReady();

    public:
      Serial(std::shared_ptr<Data> data, bool install_signal_handler);
      ~Serial();
      bool connect(const std::string& port, const int& baud = 115200, std::function<void()> cb = 0);
      void disconnect();
      inline bool connected() const { return port.is_open(); };
      bool send(const uint8_t* bytes, const uint32_t numBytes);
      bool sendOpcode(const Opcode& code);
      uint64_t getNumCorruptPackets() const;
      uint64_t getTotalPackets() const;
  };
}  // namespace create

#endif // CREATE_SERIAL_H