Interpreting keypresses sent to raspberry-pi through uv4l-webrtc datachannel -


i apologize if doesn't make sense since i'm still newbie using raspberry pi , first time posting on stackoverflow.

i making web app lets me stream video , raspberry pi while letting me send keycodes. sent keycodes let me control servos on drone. after scouring internet, figured simplest way stream 2-way video using uv4l have installed along uv4l-webrtc on raspberry pi. hooked gpio pins flight controller , using pigpio send pwm signals it, monitor using cleanflight.

right now, can manipulate keypresses roll, pitch, etc. of flight controller using python script if access pi remotely using vnc, able through custom web page being served uv4l-server. trying use webrtc data channels, i'm having trouble understanding need recognize messages sent through data channels. know data channels opened when video call initiated , i've tried test in link see if can indeed send keycodes pi (and can).

my problem right have no idea sent messages go or how can them can incorporate them python script. need make server listen keycodes being sent pi?

tl;dr have python script on raspberry pi control servos on flight controller using keypresses , separate webpage streams video using webrtc, have no idea how combine them using webrtc data channels.

thanks @adminkiam solution. here's version of python script listens socket. it's variation of this code person made pigpio:

import socket import time import pigpio  socket_path = '/tmp/uv4l.socket'  try:     os.unlink(socket_path) except oserror:     if os.path.exists(socket_path):         raise  s = socket.socket(socket.af_unix, socket.sock_seqpacket)  roll_pin     = 13 pitch_pin    = 14 yaw_pin      = 15  min_pw = 1000 mid_pw = 1500 max_pw = 2000  none        = 0 left_arrow  = 1 right_arrow = 2 up_arrow    = 3 down_arrow  = 4 less_btn    = 5 greater_btn = 6  print 'socket_path: %s' % socket_path s.bind(socket_path) s.listen(1)  def getch(keycode):     key = none     if keycode == 188:         key = less_btn     elif keycode == 190:         key = greater_btn     elif keycode == 37:         key = left_arrow     elif keycode == 39:         key = right_arrow     elif keycode == 38:         key = up_arrow     elif keycode == 40:         key = down_arrow     return key  def cleanup():     pi.set_servo_pulsewidth(roll_pin, 0)     pi.set_servo_pulsewidth(pitch_pin, 0)     pi.set_servo_pulsewidth(yaw_pin, 0)     pi.stop()  while true:     print 'awaiting connection...'     connection, client_address = s.accept()     print 'client_address %s' % client_address     try:         print 'established connection with', client_address          pi = pigpio.pi()          rollpulsewidth     = mid_pw         pitchpulsewidth    = mid_pw         yawpulsewidth      = mid_pw          pi.set_servo_pulsewidth(roll_pin, rollpulsewidth)         pi.set_servo_pulsewidth(pitch_pin, pitchpulsewidth)         pi.set_servo_pulsewidth(yaw_pin, yawpulsewidth)          while true:             data = connection.recv(16)             print 'received message"%s"' % data              time.sleep(0.01)             key = getch(int(data))              rollpw     = rollpulsewidth             pitchpw    = pitchpulsewidth             yawpw      = yawpulsewidth              if key == up_arrow:                 pitchpw = pitchpw + 10                 if pitchpw > max_pw:                     pitchpw = max_pw             elif key == down_arrow:                 pitchpw = pitchpw - 10                 if pitchpw < min_pw:                     pitchpw = min_pw             elif key == left_arrow:                 rollpw = rollpw - 10                 if rollpw < min_pw:                     rollpw = min_pw             elif key == right_arrow:                 rollpw = rollpw + 10                 if rollpw > max_pw:                     rollpw = max_pw             elif key == greater_btn:                 yawpw = yawpw + 10                 if yawpw > max_pw:                     yawpw = max_pw             elif key == less_btn:                 yawpw = yawpw - 10                 if yawpw < min_pw:                     yawpw = min_pw              if rollpw != rollpulsewidth:                 rollpulsewidth = rollpw                 pi.set_servo_pulsewidth(roll_pin, rollpulsewidth)             if pitchpw != pitchpulsewidth:                 pitchpulsewidth = pitchpw                 pi.set_servo_pulsewidth(pitch_pin, pitchpulsewidth)             if yawpw != yawpulsewidth:                 yawpulsewidth = yawpw                 pi.set_servo_pulsewidth(yaw_pin, yawpulsewidth)              if data:                 print 'echo data client'                 connection.sendall(data)             else:                 print 'no more data from', client_address                 break      finally:         # clean connection         cleanup()         connection.close() 

when webrtc data channel created between uv4l , other webrtc peer (i.e. browser, janus gateway, etc...), uv4l creates full-duplex unix domain socket (/tmp/uv4l.socket default) from/to can receive/send messages on raspberry pi. python script should open, listen , read socket incoming messages e.g. web application and/or write messages same socket web app receive them. example doing in c++ under link tutorial pointed out in question:

/*     copyright (c) 2016 info@linux-projects.org     rights reserved.      redistribution , use in source , binary forms permitted     provided above copyright notice , paragraph     duplicated in such forms , documentation,     advertising materials, , other materials related such     distribution , use acknowledge software developed     linux-projects.org. name of     linux-projects.org may not used endorse or promote products derived     software without specific prior written permission.     software provided ``as is'' , without express or     implied warranties, including, without limitation, implied     warranties of merchantability , fitness particular purpose. */  /*  * simple echo server.  * creates unix domain socket of type sock_seqpacket specified  * command line, listens waiting incoming messages clients  * (e.g. uv4l) , replies received messages senders.  *  * example:  *     $ ./datachannel_server /tmp/uv4l.socket  *  * compile program need boost v1.60 or greater, example:  * g++ -wall -i/path/to/boost/include/ -std=c++11 datachannel_server.cpp -l/path/to/boost/lib -l:libboost_coroutine.a -l:libboost_context.a -l:libboost_system.a -l:libboost_thread.a -pthread -o datachannel_server  */  #include <boost/asio/io_service.hpp> #include <boost/asio/spawn.hpp> #include <boost/asio/write.hpp> #include <boost/asio/buffer.hpp> #include <boost/asio.hpp> #include <memory> #include <cstdio> #include <array> #include <functional> #include <iostream>  #if !defined(boost_asio_has_local_sockets) #error local sockets not available on platform. #endif  constexpr std::size_t max_packet_size = 1024 * 16;  namespace seqpacket {      struct seqpacket_protocol {          int type() const {             return sock_seqpacket;         }          int protocol() const {             return 0;         }          int family() const {             return af_unix;         }          using endpoint = boost::asio::local::basic_endpoint<seqpacket_protocol>;         using socket = boost::asio::generic::seq_packet_protocol::socket;         using acceptor = boost::asio::basic_socket_acceptor<seqpacket_protocol>;  #if !defined(boost_asio_no_iostream)         /// unix domain iostream type.         using iostream = boost::asio::basic_socket_iostream<seqpacket_protocol>; #endif     }; }  using seqpacket::seqpacket_protocol;  struct session : public std::enable_shared_from_this<session> {     explicit session(seqpacket_protocol::socket socket) : socket_(std::move(socket)) {}      ~session() {         //std::cerr << "session closed\n";     }      void echo(boost::asio::yield_context yield) {         auto self = shared_from_this();         try {             (;;) {                 seqpacket_protocol::socket::message_flags in_flags = msg_waitall, out_flags = msg_waitall;                  // wait message client                 auto bytes_transferred = socket_.async_receive(boost::asio::buffer(data_), in_flags, yield);                  // write same message client                 socket_.async_send(boost::asio::buffer(data_, bytes_transferred), out_flags, yield);             }         } catch (const std::exception& e) {             std::cerr << e.what() << '\n';             socket_.close();         }     }      void go() {         boost::asio::spawn(socket_.get_io_service(), std::bind(&session::echo, this, std::placeholders::_1));     }  private:     seqpacket_protocol::socket socket_;     std::array<char, max_packet_size> data_; };  int main(int argc, char* argv[]) {     try {         if (argc != 2) {             std::cerr << "usage: datachannel_server <file> (e.g. /tmp/uv4l.socket)\n";             std::cerr << "*** warning: existing file removed ***\n";             return exit_failure;         }          boost::asio::io_service io_service;          std::remove(argv[1]);          boost::asio::spawn(io_service, [&](boost::asio::yield_context yield) {                     seqpacket_protocol::acceptor acceptor_(io_service, seqpacket_protocol::endpoint(argv[1]));                     (;;) {                         boost::system::error_code ec;                         seqpacket_protocol::socket socket_(io_service);                         acceptor_.async_accept(socket_, yield[ec]);                         if (!ec)                             std::make_shared<session>(std::move(socket_))->go();                     }                 });          io_service.run();      } catch (std::exception& e) {         std::cerr << "exception: " << e.what() << "\n";         return exit_failure;     } } 

Comments

Popular posts from this blog

php - Vagrant up error - Uncaught Reflection Exception: Class DOMDocument does not exist -

vue.js - Create hooks for automated testing -

Add new key value to json node in java -