#include #include #include #include #include #include #include #include #include #include #include "engine.hpp" using namespace std; using boost::asio::ip::tcp; using boost::asio::io_service; template class prodcon { private: mutex mut; condition_variable condition; queue q; public: void push(T data) { unique_lock lock(mut); q.push(data); condition.notify_one(); } template bool pop(T &result, const chrono::duration<_Rep, _Period> __rtime) { unique_lock lock(mut); bool success = condition.wait_for(lock, __rtime, [this] {return !this->q.empty();}); if (!success) return false; result = q.front(); q.pop(); return true; } }; class remote_server { private: tcp::acceptor acceptor; io_service &io; thread engine_thread; atomic stop_thread; prodcon> commands; public: remote_server(io_service &io_service); void run(); void engine_loop(); }; int main() { io_service io; remote_server server(io); server.run(); return 0; } remote_server::remote_server(io_service &io_service) : acceptor(io_service), io(io_service), stop_thread(false) { // Nothing to do } void remote_server::run() { tcp::endpoint endpoint(tcp::v4(), 1337); acceptor.open(endpoint.protocol()); acceptor.set_option(tcp::acceptor::reuse_address(true)); acceptor.bind(endpoint); acceptor.listen(1); while (true) { tcp::socket socket(io); acceptor.accept(socket); stop_thread = false; engine_thread = thread(&remote_server::engine_loop, this); while (true) { int8_t speed_left, speed_right; socket.read_some(boost::asio::buffer(&speed_left, 1)); socket.read_some(boost::asio::buffer(&speed_right, 1)); commands.push(pair(speed_left, speed_right)); } } } void remote_server::engine_loop() { engine left( gpio(13, gpio::pin_direction::OUTPUT, gpio::pin_type::LOW_ON), gpio(20, gpio::pin_direction::OUTPUT, gpio::pin_type::LOW_ON) ); engine right( gpio(19, gpio::pin_direction::OUTPUT, gpio::pin_type::LOW_ON), gpio(26, gpio::pin_direction::OUTPUT, gpio::pin_type::LOW_ON) ); while (!stop_thread) { pair command; if (commands.pop(command, 1s)) { left.set_speed(command.first); right.set_speed(command.second); } else { left.set_speed(0); right.set_speed(0); } } }