At the Singapore Hour of Code event I got a great tip from Melvin on how to set up a web control page for the BeerBot. In this post I’ll describe the first working version, which you can see in the video below (apologies for the robotic monotone on the voiceover).
The BeerBot is a Raspberry Pi/Mindstorms powered robot that can be steered from a control computer. It streams video to the control computer using MJPG Streamer. Before now I have used an SSH interface to control the BeerBot, and then I’ve used a separate browser window to show the video stream from MJPG Streamer. This means that you have two windows open at once – one for control and one for video. I’ve thought before about how to integrate both functions into a webpage, but I didn’t know where to start. Melvin’s suggestion was to use the CherryPy python web framework to implement some APIs that can control the robot. Since the current control software is written in Python using the nxt-python library this seemed like a great choice.
I started by going through the tutorials on the CherryPy site. As usual I was almost instantly distracted by a side project, in this case working out what text editor I was going to use. I read somewhere that Vim is extremely powerful, so I decided to give that a go. It is indeed very powerful, but it is not instantly intuitive (e.g. to move the cursor down you use the “j” key). Fortunately it comes with a very good tutorial in the form of a text file that includes both instructions and exercises for the tutorial. Once I’d done the tutorial and had set up syntax highlighting and sensible options for autotab I started to see why it is a great tool. I will keep practicing with it.
After that detour was complete I went through the CherryPy tutorials. I did the tutorials on the BeerBot using an SSH connection from my desktop computer and tested the results using a web browser on my desktop computer pointing at the BeerBot. By default CherryPy only allows access from the same computer so I had to change that setting first. I also had to change the port that CherryPy uses since MJPG Streamer is already using the default port of 8080. I set it to 8099.
The early tutorials show you how to set up CherryPy to send out a webpage when it gets a particular request from a client. I needed to put the video streaming code in that webpage. MJPG Streamer comes with a few demo pages including one for javascript. I copied the code from that page and included it in an index.html file for CherryPy to deliver.
The later CherryPy tutorials go through setting up APIs and also show a demonstration of ajax. As I understand it, ajax allows you to send signals in the background without having to load a new webpage. This technique is what I needed to be able to control the robot. I made some APIs for robot movements etc. in the python script running on the BeerBot and in the javascript portion of the index.html file I created some buttons that linked to jquery functions. This is the first time I’ve done anything with javascript. Before this project I didn’t fully understand that when you are interacting with a website there are usually two programs running – the one on the server (my CherryPy web framework) and one on the client’s computer (the javascript that sends calls to the APIs when buttons are pressed).
To get everything to appear properly on the webpage I had to use css to put a wrapper around the video stream. Without this wrapper all the buttons were hidden behind the video.
I am learning how to use Github to keep track of edits to the code. You can see the latest version here.
Learning points from this project
This was a great project for learning about a few hitherto mysterious bits of tech and how they link together:
- CherryPy is a very quick, easy and powerful way to do cool web stuff using Python. It can deliver pages that include html and javascript
- html is what you need to add elements to a webpage
- Javascript and jquery can make elements in a webpage do smart things (like call APIs)
- CSS makes everything pretty and readable by human beings