Thursday, October 11, 2012

Socket Communications (PHP to Python)

The first phase of this project is to get the 'bot working as a rather expensive RC toy with a web application accessed via my iPad being the control panel.


The idea here was one of simple expediency.  One of the other languages that I have decided to learn is PHP.   I have a forms development environment (FB4PHP) that makes it easy to build interactive applications (though it is still a beta product).  The thought was that the robot could periodically reach out via http and grab commands from the server where my little micro app was running.

Unfortunately the world of the internet is a world of latency and occasionally commands were taking way to long to get to the 'bot.   So naturally, this being an educational project, I decided that socket to socket communications would be just the trick!   The server process will run on the RPi on the back of the 'bot and the web application will be the client.  

It did turn out to have much improved latency over the http solution but I still have some tuning to do.   Luckily we have proximity detection for when a stop command just doesn't make it in time!

Here are the code snippets for each side of the conversation (first the server running in Python on the RPi):

    #  Create and open the socket will be listening on
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(("192.168.1.95", 5555))
    server_socket.listen(5)

    # Inside processing loop we wait for a connection
    client_socket, address = server_socket.accept()
    # First get the size of the package we will be getting...
    packageLength = client_socket.recv(1)
    if len(packageLength) == 0:
        break
    packageLength = ord(packageLength)


    # ... then get the package itself
    controlCommand = client_socket.recv(packageLength)
    if controlCommand == "Terminate":
        break


    ... 
    ... DO SOME STUFF 
    ...

    # Respond to the client with current telemetry and status

    client_socket.send(chr(len(sendTelemetry)))
    client_socket.send(sendTelemetry)

    client_socket.close()


Then the client running in PHP on a server in the cloud:

    function CommunicateWithRobot($Commands) {
        // Create a TCP/IP socket.
        $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if ($socket === false) {
            return "Error: socket_create() failed: reason: " .
                socket_strerror(socket_last_error());
        }
        // Connect to the server running on the 'bot
        $result = socket_connect($socket, '99.99.99.99', '5555');
        if ($result === false) {
            return "Error: socket_connect() failed.\nReason: ($result) " .
                socket_strerror(socket_last_error($socket));
        }
        // Write two transmission, one of the size of the package,
        // and the second the package itself
        socket_write($socket, chr(strlen($Commands)), 1);
        socket_write($socket, $Commands, strlen($Commands));

        // Get the response from the server - our current telemetry
        $resultLength = socket_read($socket, 1);
        if (strlen($resultLength) == 0) {
            return "Error: emptyness passed back from server";
        }
        else {
            $Telemetry = socket_read($socket, ord($resultLength));
        }
        socket_close($socket);
        return $Telemetry;
    }

3 comments:

  1. oh great project. can you help do this project? please. my gmail : legend1066@gmail.com

    ReplyDelete
    Replies
    1. It is long time no see, how about your projects

      Delete
  2. This comment has been removed by the author.

    ReplyDelete