-
Notifications
You must be signed in to change notification settings - Fork 2
BYOM: software
You are here to build your own mule and you want as much control as possible over the build. Well, it is not a short process, but it is relatively straightforward, in the sense that every challenge is surmountable.
The two steepest cliffs from the software side are the provisioning of the tensorflow and opencv libraries. These are not just simple pip install commands. They must be built for the raspberry pi from source. There are existing tutorials online for the opencv build and we reproduce one here. However, we did not manage to build tensorflow ourselves on the pi and we are using a third-party cross-compilation openly available. More on these matters below.
This tutorial is macOS-centric from those commands that require a PC (but that is not many). On the Pi-side, we are expecting a Raspberry Pi 3 Model B, a Picamera (for the Picamera section), a PWM controller (for the I2C section).
- Download Jessie Lite to you Mac:
wget http://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2017-06-23/2017-06-21-raspbian-jessie-lite.zip
- Unzip:
unzip 2017-06-21-raspbian-jessie-lite.zip
- Insert sdcard into your Mac and find the disk number:
df
The appropriate line of output will be mounted within /Volumes. We are interested in the disk number from the filesystem column, for example, the 2 from:
/dev/disk2s1
- Unmount it and burn the image:
sudo diskutil umount /dev/diskXs1
sudo dd bs=32m if=2017-06-21-raspbian-jessie-lite.img of=/dev/rdiskX
where X should be replaced with the appropriate disk number.
- We wish to conduct a headless setup of the raspberry pi so we need to ensure that ssh is enabled at the outset. With this in mind, remount the card (it should be automatically mounted at /Volumes/boot) and simply create an empty ssh file within this boot folder:
sudo diskutil mount /dev/diskXs1
touch /Volumes/boot/ssh
- Eject the sdcard:
sudo diskutil eject /dev/diskXs1
- Place the sdcard into the raspberry pi, connect the raspberry pi using an ethernet cable to your router and boot up.
- Find the raspberry pi on your local network. So from you Mac:
arp -a
to find "everything" that is on your network. (Not necessarily, routers are pretty mean at times). In general, the output can be pretty cryptic so it might worth typing the command with the raspberry pi disconnected from the router, in order to see what it new.
- Once you have its network address, e.g. 192.168.178.33, you are ready to ssh:
ssh pi@192.168.178.33
It may even resolve the default hostname for you, so you might be able to:
ssh pi@raspberrypi
The default user is pi and the default password is raspberry.
- Perform some initialization and (optional) customization:
sudo raspi-config
Then expand the filesystem (necessary), change hostname (optional), change password (optional but advised obviously). Upon finishing these, you will be directed to perform a reboot (to actually expand the filesystem). Do so, you will be disconnected, so reconnect through ssh once again.
- With the ssid and passphrase of your local network, you can generate an encrypted version:
wpa_passphrase <ssid> <passphrase>
For example, on the network "asdfasdf" with passphrase "qwerqwer", the output of:
wpa_passphrase asdfasdf qwerqwer
is
network={
ssid="asdfasdf"
#psk="qwerqwer"
psk=196706ebd5bde679730d964f0f42439a9e9350719d092ff022f684938275de08
}
- Edit using:
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf
to contain the output of the wpa_passphrase command above. Do not forget to delete the unencrypted password line psk="qwerqwer".
- Reconfigure the wifi:
wpa_cli -i wlan0 reconfigure
- See https://www.raspberrypi.org/documentation/configuration/wireless/wireless-cli.md for more information.
- Update and upgrade the system:
sudo apt-get update && sudo apt-get upgrade
- Load awesomeness (version control, editting, shell):
sudo apt-get install git vim zsh
- Switch to zsh:
chsh -s $(which zsh)
In order for the switch to take effect, logout and back in through ssh.
- Load even more awesomeness:
cd ~
git clone https://github.com/robbyrussell/oh-my-zsh.git
cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc
oh-my-zsh is simply a fantastic set of plugins for zsh that allows for wonderful customizations.
- On Jessie-Lite, no python3 is installed by default, do so:
sudo apt-get install python3
This should install install python 3.4.2. (We want 3.4 for later tensorflow compatibility.)
- Get python package installers for python2 and python3:
sudo apt-get python-pip
sudo apt-get python3-pip
- Python virtual environments are must:
sudo pip install virtualenv virtualenvwrapper
after which, we should append to our .zshrc file:
export WORKON_HOME=$HOME/.virtualenvs
VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
source /usr/local/bin/virtualenvwrapper.sh
- Create a new (empty) virtual environment for the mule:
mkvirtualenv mule
Now append to your .zshrc file:
workon mule
To automatically load this virtualenv every time you log in. We are assuming that you use this raspberry pi for running the muleAI. In general, to leave:
deactivate mule
and to enter:
workon mule
Now for the first of the 3rd-party installs. It would be nice of course to think that we could compile from source the tensorflow code directly on the raspberry pi all on our own, but not only is this an arduous task, it is unlikely to succeed.
- Create a directory for the code:
cd ~
mkdir ThirdParty && cd $_
- Load libraries necessary for the installation of the tensorflow wheel:
sudo apt-get install libblas-dev liblapack-dev libatlas-base-dev gfortran python3-dev python3-setuptools
- Check out the website: http://ci.tensorflow.org/view/Nightly/job/nightly-pi-python3/buildTimeTrend for the version that you want. There are two things to note. First, a lot of builds are red, meaning that they failed. You can neglect these. Second, of the builds that passed, not all will work. For example, build 8 (tensorflow-1.3.0) passed yet after installation, importing tensorflow throws the error: /home/pi/.virtualenvs/mule/lib/python3.4/site-packages/tensorflow/python/_pywrap_tensorflow_internal.so: undefined symbol: _Py_ZeroStruct In general a _Py_ZeroStruct error means that the so was built with some python2 headers. I don't know if that was on our side or in the original wheel.
- Download your chosen wheel:
wget -O tensorflow-1.5.0-cp34-none-any.whl http://ci.tensorflow.org/view/Nightly/job/nightly-pi-python3/122/artifact/output-artifacts/tensorflow-1.5.0-cp34-none-any.whl
- Install the wheel (into the mule virtualenv):
pip install tensorflow-1.5.0-cp34-none-any.whl
There you go.
Computer vision!!! Once again, not a simple pip install, we need to build from source, but we can and it only takes 3hrs. Yeah! (Note: it takes 3hrs). For more information, you should check out: https://www.pyimagesearch.com/2017/09/04/raspbian-stretch-install-opencv-3-python-on-your-raspberry-pi/ Your tensorflow installation should have installed numpy for you as a prerequisite. Importantly, it is the only python prerequisite for opencv. Check that is in the mule virtualenv with:
pip list
It is going to be there, but if for some reason it is not (and that reason is unlikely to be good, e.g. did you ensure that you were in the mule virtualenv when you installed tensorflow????), then:
pip install numpy
Note that you do not just lay down a pip install command for a heavily cythonized library on a raspberry pi. You will be left twiddling your thumbs for a while.
- Get the libraries:
sudo apt-get install build-essential cmake pkg-config
sudo apt-get install libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
sudo apt-get install libxvidcore-dev libx264-dev
sudo apt-get install libgtk2.0-dev libgtk-3-dev
sudo apt-get install libatlas-base-dev gfortran
sudo apt-get install python3-dev
- Get the source code:
cd ~/ThirdParty
wget -O opencv.zip https://github.com/Itseez/opencv/archive/3.4.0.zip
unzip opencv.zip
wget -O opencv_contrib.zip https://github.com/Itseez/opencv_contrib/archive/3.4.0.zip
unzip opencv_contrib.zip
cd ~/opencv-3.4.0/
- Setup the build environment:
mkdir build && cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D INSTALL_PYTHON_EXAMPLES=ON \
-D OPENCV_EXTRA_MODULES_PATH=~/ThirdParty/opencv_contrib-3.4.0/modules \
-D BUILD_EXAMPLES=ON ..
- Setup swap for build:
sudo nano /etc/dphys-swapfile
comment the current CONF_SWAPSIZE line and add:
CONF_SWAPSIZE=1024
Then restart the process:
sudo /etc/init.d/dphys-swapfile stop
sudo /etc/init.d/dphys-swapfile start
- Make:
make -j4
sudo make install
sudo ldconfig
This takes a while.
- Check that the shared object file is installed and rename it to something simpler:
ls -l /usr/local/lib/python3.4/site-packages/
cd $_
mv cv2.cpython-34m.so cv2.so
- Now link the file to mule virtualenv:
cd ~/.virtualenvs/mule/lib/python3.4/site-packages
ln -s /usr/local/lib/python3.4/site-packages/cv2.so cv2.so
- Revert the swapfile to its original state (IMPORTANT: you will degrade your sdcard quickly if not) and restart the process.
At last ready for some intelligence. Let's get the mule going.
mkdir Development && cd $_
git clone https://github.com/MarcusJones/muleAI.git