Saturday, January 24, 2015

My book on using LeJOS with EV3 is now out

A little over a year ago when my wife gave me the Lego Mindstorms EV3 as the most awesome of birthday presents I started tinkering with it in an attempt to use Linux to program it. This led me to discover LeJOS. The subsequent joy of discovery moved me to create this blog and post what I learned about it.

These posts brought me to the attention of Packt publishers who commissioned me to write a book on the subject. That book has now been completed and is available on Amazon (amongst other places): Lego Mindstorms EV3 Essentials

The book is in essence a pedagogically rich instruction manual on how to program the EV3 using both the on-brick visual programming language and using Java by installing LeJOS. The primary focus of the book is using LeJOS while programming on a Linux machine. So if you are a robotics enthusiast who is comfortable with Linux (and really one cannot call themselves an enthusiast of any computer related field if one doesn't learn Linux) then you will love the detailed information this book provides on how to program the EV3 on that great OS. The fact that the EV3 runs Linux itself should be reason enough.

To get an idea of how the book presents its material you need go no further than this blog itself, which is the inception of the book, and the detailed information Packt have provided on their website: Packt Publishers - Lego Mindstorms EV3 Essentials.

Friday, May 23, 2014

SSH in to an EV3 running leJOS using the USB cable

I have underestimated leJOS at every turn, never more so than the issue of connectivity. I got Wifi to work by editing files directly on the SD card. That it worked is a testament both to leJOS and my own stubbornness. It turns out, however, that there is a much easier way of gaining SSH access to an EV3 running leJOS.

Simply use the mini-USB cable that ships with the EV3, connect the EV3 to your Linux machine and wait for the USB Ethernet connection to be established automatically (tested on Ubuntu where a desktop notification appears to indicate this). Run ifconfig to confirm that the usb0 network interface is up and running.

The EV3 displays its IP address on the home screen: 10.0.1.1. Simply SSH in to this address using username root and a blank password. Could it be more painless?

Sunday, April 13, 2014

Connecting to an EV3 running LeJOS using Bluetooth

I had known all along that the EV3 comes equipped with Bluetooth and that LeJOS allowed you to write programs that employed Bluetooth for communication, but the whole truth is way cooler.
I learned only recently that with Bluetooth activated, LeJOS running on the EV3 implements a Bluetooth PAN (Personal Area Network) by becoming a GN (Group ad-hoc Network) Controller.
This means the EV3 is acting as a server on a bluetooth-based network. You can connect your computer to this network using bluetooth. The computer acts as a PANU (a client of the PAN) and is able to ssh in to the EV3 and perform all of the actions we were performing using the WiFi dongle. The immediate advantage is that one does NOT need the WiFi dongle (saves money and you don't have the dongle protruding off of the side of the EV3).
Bluetooth on Linux (my experience is with Ubuntu 12.04 and 13.04) is still buggy but the setup for connecting to the EV3 was surprisingly painless once I figured it out (that part was harder).
The first step is to confirm that bluetooth is running on your computer by running the following command in a terminal:
hciconfig -a
This will spit out a bunch of information:
hci0: Type: BR/EDR  Bus: USB
 BD Address: 00:16:CF:FE:03:A0  ACL MTU: 1017:8  SCO MTU: 64:8
 UP RUNNING PSCAN ISCAN 
 RX bytes:301012 acl:2298 sco:0 events:460 errors:0
 TX bytes:94808 acl:966 sco:0 commands:67 errors:0
 Features: 0xff 0xff 0x8d 0xfe 0x9b 0xfd 0x00 0x80
 Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3 
 Link policy: RSWITCH HOLD SNIFF PARK 
 Link mode: SLAVE ACCEPT 
 Name: 'Abid-Laptop'
 Class: 0x6e010c
 Service Classes: Networking, Rendering, Capturing, Audio, Telephony
 Device Class: Computer, Laptop
 HCI Version: 2.0 (0x3)  Revision: 0x20da
 LMP Version: 2.0 (0x3)  Subversion: 0x4182
 Manufacturer: Broadcom Corporation (15)
Look for "Networking" in 'Service Classes' and "Computer" in 'Device Class'. In addition we need a useful 'Name'. To change it issue:
sudo hciconfig hci0 name '<device name>'
To connect to the EV3 (running LeJOS) turn it on and navigate to the "Bluetooth" menu. Make sure that it says "Visibility on". Now on your computer issue:
hcitool scan
The response should look like:
Scanning ...
 00:16:53:40:E9:7D EV3
We will need the Bluetooth address of the EV3 (the 12 hexadecimal number interspersed with colons) and the IP address of the EV3 on the PAN (displayed on the EV3 screen - 10.0.1.1 in my case). To connect to the EV3 as a PANU client one uses the pand utility (from the bluez-compat package):
sudo pand --connect 00:16:53:40:E9:7D
The PAN has been established but we need to start the bnep0 network interface manually on the computer to allow us to access the EV3 over the bluetooth PAN. Since the EV3 has IP address 10.0.1.1 we choose for our computer 10.0.1.2 (the first three numbers (sub-domain) need to match, the last one can be any number from 2 to 255):
sudo ifconfig bnep0 10.0.1.2
To confirm that the bnep0 network interface is active simply run:
ifconfig
and look for:
bnep0     Link encap:Ethernet  HWaddr 84:a6:c8:9b:ce:58  
          inet addr:10.0.1.2  Bcast:10.255.255.255  Mask:255.0.0.0
          inet6 addr: fe80::86a6:c8ff:fe9b:ce58/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:670 errors:0 dropped:0 overruns:0 frame:0
          TX packets:7 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:30820 (30.8 KB)  TX bytes:428 (428.0 B)

To confirm connectivity with the EV3 we ping it:
ping -c3 10.0.1.1
One can ssh in to the EV3 using IP Address 10.0.1.1, username "root" and blank password:
ssh root@10.0.1.1
It helps with automation if you set up an SSH private/public key-pair and store the public key in /home/root/.ssh/authorized_keys allowing password-less access. Finally to disconnect the computer from the EV3 PAN issue:
sudo pand -K

Monday, January 20, 2014

Hello World C program on the EV3

I have been programming the EV3 using LeJOS (basically Java) for a few weeks now, but the desire to use a truly low-level language such as C to control the robot has not gone away. I took a significant first step in that direction by acquiring a cross-compiler and using it to successfully write and compile a Hello World program that basically prints the infamous string on stdout. Since my computer runs Linux on the x86 architecture while the EV3 runs on an ARM 9 architecture, a cross-compiler is needed on my x86 to take source code (in C) and compile it for the ARM 9 architecture. After compilation the executable can be placed in the EV3 and executed at will. Having a cross-compiler allows me to develop on my PC (a much faster approach) and simply push binaries (executables) to the EV3 for execution. This site/blog explains how to acquire the cross-compiler while this associated section explains how to write and compile the Hello World program. The blog has more complex examples to do with controlling the sensors and motors but that will have to wait for another day.

Saturday, January 11, 2014

Using make to build and deploy LeJOS programs on the EV3

As discussed earlier my aim is to automate the repetitive nature of the edit-build-deploy-run cycle for programming the EV3 using LeJOS. To that end I set up build.gradle to build the project from the command-line as explained here. Furthermore I set up wifi on the EV3 (using a usb dongle). The next step was to edit ~/.ssh/config and add an entry for the EV3:
  Host ev3

      User root
      HostName 192.168.1.16
      IdentityFile ~/.ssh/abid_ev3
Note: Since the wifi setup on the EV3 is DHCP (not static) the IP address is liable to change, in which event one has to modify ~/.ssh/config accordingly.

The next step is to create a Makefile in your project root. Here is a link to the one I'm using for my "Rover" project. Note the extensive use of PHONY and EMPTY targets to ensure that build and scp tasks are only performed when needed. make once correctly set up takes care of the dependencies. I only need to issue make run from the terminal and the source is compiled and the jar file copied to the EV3 only if needed. Sweet and simple, just the way I like it.

You can take a look at the complete Rover source code on github. There you will also find a number of other repos for my various LeJOS EV3 projects.

Building LeJOS programs for EV3 using gradle

With the wifi connection (including ssh) to the EV3 running and IntelliJ set up to write programs, development for the EV3 was coming along nicely. There was still an issue, however, with the time it took to make a change in the code, compile it, copy it to the EV3 (using scp), run it on the EV3 and then repeat. Since repetition is the bane of all programmers I started looking in to ways to automate these tasks. Of course the ubiquitous make tool came instantly to mind. I would just write a make script (Makefile) to automate these tasks. But how to automate the build task that creates the jar file from the source code, and in such a way that make could do it.

The solution is gradle. Gradle is a project automation tool with excellent support for Java (Google now recommends using gradle and Android Studio - a port of IntelliJ - for Android development). Though gradle has somewhat of a learning curve, it is well worth it, since only after using gradle have I finally begun to understand how a java project comes together. Furthermore with gradle one can build projects from the command line by simply issuing the command gradle build.

Gradle installation is straightforward and is explained here. Once installed the next step is to create a build.gradle file in the root folder of your LeJOS project (your source code). The build.gradle for one of my earlier projects looks like this:

apply plugin: 'java'

def main_class = "Rover"          // We define the main class of the project

// We set the Version of the Java SDK to the one on the system: 1.6
sourceCompatibility = 1.6

sourceSets {

    main {

        // We specify the source directories for the project. The first one is created by us while the latter two are part of the LeJOS source and provide
        // essential classes for controlling the EV3.
        java {
            srcDirs = ['src', '/home/abid/applications/lejos/ev3/DBusJava/src', '/home/abid/applications/lejos/ev3/ev3classes/src']
        }

        // We specify the jar library required to compile the project. This provides the com.sun.jna package
        dependencies {
            compile files('/home/abid/applications/lejos/ev3/ev3classes/lib/jna-3.2.7.jar')
        }

        // We specify manifest attributes (key-value pairs that must appear in the META-INF/MANIFEST>MF file inside the output Jar for the EV3 to run it correctly.
        // Additionally we supply the name of the Main-Class which is the starting point of the program execution.
        jar {
            manifest {
                attributes("Main-Class": main_class, "Class-Path": "/home/root/lejos/lib/ev3classes.jar /home/root/lejos/libjna/usr/share/java/jna.jar")
            }
        }
    }
}
This is pretty much a template build.gradle file for any LeJOS EV3 project. The one-time alterations needed are to change the latter two srcDirs to point to the locations in the local LeJOS git repo as well as the jna jar dependency in the same.

The only thing one needs to alter (from project to project) is the name of the main class defined in the variable main_class near the beginning. And you are good to go. Execute gradle build and the project will compile and place the results in the build/ sub-folder.

Next time I will show you how to incorporate all of this in to one epic Makefile complete with dependencies.

Using LeJOS to write write programs for the EV3

Over the years I have thought many times of getting in to Android development; buying books, reading up online tutorials and such. But every time I would be driven away by the sheer ugliness, unusability and slowness of Eclipse. It wasn't until I discovered IntelliJ that I could start making sense of Android and now that is what I do for a living.

What this means is that when I bought the Lego Mindstorms EV3 and installed LeJOS on it the next step was figuring out how to develop programs for it on IntelliJ (and not Eclipse as suggested by the guys at LeJOS, but what do they know). This post explains how to do it on Windows and since IntelliJ is multi-platform the instructions can be ported trivially to Linux.

A few clarifications to the instructions follow:

The LeJOS source code (the classes required for development - think of it as the SDK) can be acquired using:
    git clone git://git.code.sf.net/p/lejos/ev3

Once the repo has been cloned switch to the latest release (0.5.0-alpha):
    git checkout 0.5.0-alpha
This will place you in a HEAD-less state but that is alright.

Your main class doesn't need to be labelled "Main". It just needs to implement the function public static void main(String[] args). This class serves as the entry point in to your application (execution starts in the main function/method. Just remember to use the actual name of the class in the MANIFEST.MD file when specifying the Main-Class value.