Robots! Part 2, the android client

Continuing on from my previous post, I’ve created an android client that I can use to send commands to my python server.

Ultimately I want to be able to control the robot remotely, the best way to do this would be to control the robot from a tablet or a phone which communicates wirelessly with the pi via bluetooth or wifi. In my previous post I described setting up a python application that will run on the raspberry pi and listen for commands. All I needed to do was to create a very basic android interface that can send commands to the raspberry pi.

The robot I intend to build will be based on tracks instead of wheels, there are many benefits to this but the most significant is that from an engineering perspective is that its much easier to build. A car needs forward and backwards drive, but also sideways drive for the front axle. In my opinion, it is far simpler to have a tracked vehicle with a motor controlling each side. When both motors are turned in the same direction the vehicle moves forward or backwards, and when the motors run in opposite directions the vehicle will turn on the spot.

My app interface mimics the layout of the vehicle itself, with an up and down button on the left and right hand side of the screen, as shown below.

Arrow buttons for controlling robots tracks

Arrow buttons for controlling robots tracks

You can see the code for this layout on the github repo here.

I want the user to be able to hold a button and the motor will run until they take their finger off. For this I’ve attached listeners on the buttons that will listen for the key up and key down events. It will send separate events for starting and stopping the motors, like so:

        Button leftForward = (Button) findViewById(R.id.leftForward);

        leftForward.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_DOWN: {
                        sendCommand(leftForwardCommand + "-Start");
                        break;
                    }
                    case MotionEvent.ACTION_UP: {
                        sendCommand(leftForwardCommand + "-Stop");
                        break;
                    }
                }
                return false;
            }
        });

As the sendCommand needs send a message over the network, I need to take this off the main UI thread otherwise I’d get an exception such as:

android.os.NetworkOnMainThreadException

To take this off the UI thread, I simply move the sending of the command into an AsyncTask, like so:

private void sendCommand(String command) {
        new SendCommandTask().execute(command);
    }

    class SendCommandTask extends AsyncTask<String, Void, Void> {

        @Override
        protected Void doInBackground(String... commands) {
            String command = commands[0];
            try {
                //TODO: make this configurable inside the app
                Socket socket = new Socket("192.168.0.6", 3033);
                PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
                out.println(command);

                Log.d(TAG, "Successfully sent " + command);
            } catch (IOException ioe) {
                Log.d(TAG, "Unable to send command", ioe);
            }
            return null;
        }
    }

Now if I run the python server and then send press the buttons in the app, I see this output from the python application.

Server listening on port 3033...
...L-FORWARD-Start…..L-FORWARD-Stop….

Thats all for now, you can access this code on my github repository. Next post will either be in relation to building the robot, or using the BrickPi APIs.

How to keep checking if port is open, by issuing socket connects

I recently need to check if a particular application is online and listening on a particular set of ports. I figured that the best way to do this was to periodically issue some socket connects onto those ports. If I got an exception, then clearly there would be an issue.

This was all running on a CentOS Linux machine, so I opted for a Python script, have a look at my sample below

# Socket Connect Script
# Author : James Elsey
# Date : 27 January 2011

# Imports
import socket
import sys
import time
import datetime

# Configure these as required..
remote_host = "127.0.0.1"

print "About to start running script..."

# run continuously
while True:
        time.sleep(60)
        for remote_port in [80,8080]:
                # Setup socket
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.settimeout(60)
                now = datetime.datetime.now()
                now_text = now.strftime("%Y-%m-%d %H:%M:%S")

                try:
                        # Issue the socket connect on the host:port
                        sock.connect((remote_host, remote_port))
                except Exception,e:
                        print "%s %d closed - Exception thrown when attempting to connect. " % (now_text, remote_port)
                else:
                        print  "%s %d open" % (now_text, remote_port)
                sock.close()

So there you have it, take it and modify as you please! You could remove the while True and setup a for loop to check for a specific number of times, or leave the continual loop in and create another method of breaking out, for me I just wanted to leave it running in a putty window and watch for changes.

Also, to run it, just use save it into a .py file and call “python myFile.py”

Happy coding