YARP, iCub + Matlab

All hail the mighty Matlab! … when it works

Ok, YARP and iCub-main are up and working, time for the jewel in the crown of every applied math-robotisct… robosicis… robotics mathematician: Matlab

BTW. I had to do this 4 times, thanks to a little bit unclear instructions on YARP website. And do everything except ‘make install’ and operations on /usr/local as a normal user – cmake complained about gcc to me as root

What do I need? Accordingly to the YARP website: SWIG:
http://prdownloads.sourceforge.net/swig/swig-3.0.10.tar.gz
make sure to have jdk installed (on slackware DVD, or sbopkg)
just type javac in the console, you MUST have it

./configure
make && make install

And … I need to recompile YARP. Go figure.

cd yarp
mkdir build4 && cd build4
cmake -DCREATE_GUIS=on -DCREATE_LIB_MATH=on -DCREATE_OPTIONAL_CARRIERS=on -DENABLE_yarpcar_bayer_carrier=on -DYARP_COMPILE_BINDINGS=on -DCREATE_JAVA=on -DCREATE_PYTHON=on ../
make
make install

Now bindings, this will be tricky mainly because you have to do a lot by hand:

cd ..
mkdir build4_bindings
cd build4_bindings
cmake -DCREATE_JAVA=on ../bindings/
make -j4
make install
cp ../bindings/src/LoadYarp.java generated_src/java/
cp ../bindings/src/YarpImageHelper.java generated_src/java/
cd generated_src/java
javac *.java
cd ../..
mkdir package
cd package
mkdir yarp
cp ../generated_src/java/*.class yarp/
mv yarp/LoadYarp.class ./
mv yarp/YarpImageHelper.class ./
jar cvf yarp.jar *
mkdir /usr/local/lib64/jyarp
cp yarp.jar /usr/local/lib64/jyarp/
cp ../libjyarp.so /usr/local/lib64/jyarp/

This makes the .jar file instead of the directory with .class files, but the file to work (well, directory too) must have a very precise structure:

LoadYarp.class
YarpImageHelper.class
yarp/IControlCalibration2Raw.class
yarp/RpcServer.class
yarp/SVector.class
yarp/Matrix.class
...

Those two files in the main, the rest in yarp/ subdirectory, otherwise (if you do it in a flat style) Matlab will not be able to find yarp.Network and you can get an error like this in Matlab:

>> LoadYarp
Java exception occurred:
java.lang.NoClassDefFoundError: yarp/Network
	at LoadYarp.(LoadYarp.java:19)
Caused by: java.lang.ClassNotFoundException: yarp.Network
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 1 more

Now modify your Matlab files, first line will be different based on your system:

cd /usr/local/matlab2012a
echo "/usr/local/lib64/jyarp/yarp.jar" >> toolbox/local/classpath.txt
echo "/usr/local/lib64/jyarp" >> toolbox/local/librarypath.txt

Ok, now the tricky part: we compiled the library using different Java than Matlab normally uses, so we will see an error:

Warning: A Java exception occurred trying to load the LoadYarp class:
Java exception occurred:
java.lang.UnsupportedClassVersionError: LoadYarp : Unsupported major.minor version 52.0
	at java.lang.ClassLoader.defineClass1(Native Method)

we want to start Matlab with a new java:

export MATLAB_JAVA=/usr/lib64/java

but you still will get something like this since the libraries mismatch:

>> LoadYarp
Java exception occurred:
java.lang.UnsatisfiedLinkError: /usr/local/lib64/jyarp/libjyarp.so:
/usr/local/matlab2012a/bin/glnxa64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by
/usr/local/lib64/libYARP_dev.so.1)
	at java.lang.ClassLoader$NativeLibrary.load(Native Method)
	at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1857)
	at java.lang.Runtime.loadLibrary0(Runtime.java:870)
	at java.lang.System.loadLibrary(System.java:1122)
	at LoadYarp.(LoadYarp.java:18)

so we want to use OUR libstdc++ from Slack, start the matlab using:

bash-4.3$ LD_PRELOAD="/usr/lib64/libstdc++.so.6" matlab

and it should work:

>> LoadYarp
Yarp library loaded and initialized
 
ans =
 
LoadYarp@416c58f5

So your command for launching Matlab from a console to work with YARP is:

MATLAB_JAVA=/usr/lib64/java LD_PRELOAD="/usr/lib64/libstdc++.so.6" matlab

Now testing communication, we will need two sessions of Matlab and two consoles. Copy files yarp/examples/matlab/yarp_read.m and yarp_write.m somewhere and modify them:
make sure that both files begin with:

LoadYarp
import yarp.Port
import yarp.Bottle

and in yarp_read modify disp from:

disp(b);

to:

disp(b.toString_c());

Now the tricky part:

Console number 1: yarpserver
Matlab 1: yarp_read
Matlab 2: yarp_write
Console number 2: yarp connect /matlab/write /matlab/read

And the result:

20160930_yarp_matlab

One comment

Leave a Reply