Thursday, September 26, 2024

Assembling a Robotic arm

Research

Now that we have a robotic car, I'm considering attaching more devices to it. What about attaching a robotic arm? The tutorial for the car has a section about controlling the robotic arm but unfortunately, my car didn't have one.
I started researching about robotic arms and learning what kind of servos they need. I found that any arm needs at least 4 servos to operate, I looked through dozens of arm models to find the best price/quality model. There are tons of cheap plastic arms but I wanted something more durable and also not expensive. I found one model named 6DOF Robot Mechanical Arm Clamp Claw Kit DOF Manipulator Industrial Robot Parts. It looks a little bit big for my car but I was willing to buy and assemble it. The learning experience is worth 37 bucks spent on the robotic arm :). Oh...the product description didn't say anything about instructions so I probably won't expect any assembling instructions. I found 6DOF Robotic Arm Assembly Tutorial which explains how to assemble the arm. Now I'm confident that my 37$ will not be wasted :)

Assembling

I started assembling the arm following the video tutorial and it went smoothly. The video tutorial is clear and simple to follow. Just until the first servo is installed. The problem is that we need to rotate this servo to 90 degrees.

I could turn it manually as suggested in another tutorial here but that doesn't look very precise. Why don't attach the servo to the car and turn it?

Turn the servo to 90 degrees

Connect the servo to Port 1. See port numbers in the Motor HAT doc 
Turn on the car, connect in VSCode and run this python program:

import Adafruit_PCA9685 # Import the library used to communicate with PCA9685

pwm = Adafruit_PCA9685.PCA9685() # Instantiate the object used to control the PWM
pwm.set_pwm_freq(50) # Set the frequency of the PWM signal

pwm.set_pwm(1, 0, int((540 + 72) / 2)) # range is between 72 and 539



What is PWM?

PWM - Pulse Width Modulation. There are plenty of videos about it. For example here.
Our servo MG996R has duty cycles 1-2ms where 1ms is 0 degrees, 2ms is 180 degrees.
To control the servo you need to send a "magic" number to the pwm object. Unfortunately, Adafruit_PCA9685 is an old and deprecated library which doesn't provide to set degrees 0-180. I played with the servo and found that the most left position is at 72 and the most right is at 539. Which probably corresponds to 0 and 180. Here is the article that explains what is a duty cycles and how to convert them to degrees.
Here is whole process in a few secs:


Connecting robotic arm to the car

 I connected all 6 servos to the car:


Then connected from VSCode and played with the servos. Unfortunately, the shoulder and elbow servos couldn't hold the weight of the arm :(. I'll deal with it later. Here is a script to set arm into default position (like on the picture above):

import Adafruit_PCA9685 # Import the library used to communicate with PCA9685

pwm = Adafruit_PCA9685.PCA9685() # Instantiate the object used to control the PWM
pwm.set_pwm_freq(50) # Set the frequency of the PWM signal

#servo 2 - shoulder in almost open position (horizontal back) at 500
pwm.set_pwm(2, 0, 400) # ~45 degrees turned back
pwm.set_pwm(3, 0, 350) # ~60 degrees to shoulder
pwm.set_pwm(4, 0, 150) # ~100 degrees to elbow
pwm.set_pwm(5, 0, 300) # ~palm parallel to ground
pwm.set_pwm(6, 0, 250) # ~palm wide open

Resources

RC Servo PWM and Frequency Demonstration


Raspberry Pi: Install development environment

I'm used to nice and powerful IDEs. I looked on Thonny IDE and decided to find a better approach to develop on the Raspberry Pi.  I found this video tutorial that helped me to setup VSCode to develop remotely on my car: How to set up remote development for the Raspberry Pi using Visual Studio Code

Setup IDE (VSCode)


Steps are simple
- Install VSCode
- Install Remote Development extension pack to VSCode
- Create a new SSH connection and connect to Raspberry Pi from VSCode
It will take some time for VSCode to install the server on the Pi machine. 

Clone Github repository

Click clone repository...
Provide github URL. I used https version of the repo I forked: https://github.com/szelenin/Adeept_AWR.git
Provide existing folder where to clone
 


Configure Git

In the terminal set user name and email for git:

git config --global user.name user name
git config --global user.email your@email.com

Commit and Push

Change smth and commit from the source control: 

Click Sync Changes button to push.

Run Python with sudo

add "sudo": true into launch.json


Intellij Keybinding

Install IntelliJ IDEA Keybindings plugin

Make Raspberry use whole SD card's space

I used the provided image for the car so maybe because of that my Raspberry didn't expand the file system on the first boot. I noticed this when I tried to install Python Extension. 
To fix this open the terminal and run raspi-config:

sudo raspi-config

Then select Expand Filesystem in the Advanced Options:

After the car restarts, connect again and see how much space on the device. From the terminal run df -H command.
 

Sunday, September 22, 2024

Raspberry Pi: first encounter

It's been almost 13 years since my last post here. Quite a lot of things happened this time...

I got this Adeept AWR 4WD WiFi Smart Robot Car Kit for Raspberry Pi. It is built on Raspberry Pi and requires assembling. There are no instructions provided and after I opened the box I felt like I was going to overcome many challenges. 

Assembling and first start

I found the tutorials and samples (here) and they looked pretty good. After I installed an operation system, car server, and all dependencies I tried to start a car's webserver. The server returned an error: 'Could not determine default I2C'. I googled it and found that the webserver uses a deprecated library: Adafruit_Python_GIRO. The recommendation was to use a new library called Blinka

I installed Blinka but it didn't help to start the server. I looked in the server's code and tried to hack it so it works with the new library. No success here as well - the server requires many changes to migrate to the new library. So disappointing...

I was desperate and about to scrap everything when I suddenly realized the manufacturer had included the image file with Raspberry Pi OS and the webserver (here is the link). The tutorial described this option as a "not recommended" way to install the system. So I followed that "not recommended" approach and everything worked smoothly! My servo motor reacted and I started assembling the car following the instructions. 

Useful tip: Start from this step

Install cooling for Raspberry Pi! See Useful Tip 2 below. Then proceed with the next steps. 
 
Follow "Not recommended approach" in section 2.1.3 of the tutorial if you want your car to work :)

I configured my home WiFi in the Imager settings. I enabled ssh and configured the user name and password. Although the tutorial says you can skip it for "not recommended approach", I did it because I wasn't able to find credentials for pre-configured ssh access.

After that follow the assembling instructions from Section 4. You do not need to install anything as everything is already preinstalled in the provided image file.

Here is what I got (Front)

And back


I turned on my car, logged into it by ssh and started the server: 
sudo python3 Adeept_AWR/server/webServer.py


I ignored all errors and warnings and pointed my browser to the server : http://<server>.local:5000. I was able to control the car, camera works fine and able to move up and down.  

Here is a control screen


Useful tip 2:

The Raspberry Pi quickly overheats. Especially if there are several devices on it like servos, motors etc.  In my case after I started the car's temperature went above 65 degrees after 5 mins or so of driving. It really affects the driving experience because to cool down the processor Raspberry Pi slows down itself. I bought and installed Copper cooling for Raspberry Pi to resolve the overheating problem.

Useful links

Adeept AWR 4WD WiFi Smart Robot Car Kit for Raspberry PI

Image file (local copy)

Motor HAT documentation

Tutorials and samples (local copy)

Github repo with the car code  

Copper cooling for Raspberry Pi


Next I will install dev environment and will try to write some code...

Saturday, August 08, 2015

Мое Online обучение

Курсы, которые я прошел

Однажды мне очень сильно повезло и у меня появилось 9 относительно спокойных месяцев, когда выходные и нерабочие вечера чаще проводишь дома и никаких дальних поездок, курортов и прочих развлечений даже не планируешь. Я решил потратить это время с максимальной пользой для себя, тем более что после этого 9-ти месячного периода жизнь кардинально изменилась и свободного времени заметно поубавилось. Но это уже другая история :).
Я решил испопробовать массовое онлайн обучение (или MOOC) что называется "по максимуму". Всего удалось пройти чуть более 10 курсов, и, после двухгодичного перерыва многое стало забываться, посему и решил немого вспомнить как это было. Сейчас пока первые пару курсов "вспомнил", потом буду докидывать еще.

Стратегия прохождения

Я записывался на несколько курсов одновременно и не очень сопротивлялся соблазну подписываться на "все и сразу". Это же нереально круто, когда преподы из самого StandfordPrinceton или Berkeley выкладывают свои курсы онлайн абсолютно бесплатно, причем программа курса зачастую такая же как и для студентов именитых университетов! Естественно, что пройти "все и сразу" невозможно и после первых недели-двух я определялся стоит ли продолжать слушать курс или лучше переключиться на другие. В процессе такого "естественного отбора" я обнаружил, что моя пропускная способность - это 2, максимум 3 параллельных курса, которые я планировал пройти до конца.

Конспектирование 

Оказалось очень удобно после 3х лет пролистать конспект и вспомнить детали, просмотреть слайды и видео лекций. Кстати, на экзаменах конспект тоже иногда помогал. В качестве инструмента конспектирования и использовал XMind. В mind map я приатачивал слайды и видео лекций, иногда вставлял свои пометки. Примерно так:


Дальше я буду описывать курсы, которые прошли такую фильтрацию.
В разделе "о чем курс" сугубо моя личная отсебятина, которая не всегда совпадает с официальной версией.

Heterogeneous Parallel Programming


Страница курса: https://www.coursera.org/course/hetero
Университет: University of Illinois at Urbana-Champaign
Сложность: 3

Первый курс, который я прошел на курсере, поэтому он возглавляет мой список самых интересных курсов. Причем очень даже заслуженно :)

О чем курс

Мы как-то очень привыкли к старым добрым однопоточным машинам, прототипом которых была машина Тьюринга. Тьюринговская лента (или "нить" - thread) всего одна и поэтому нет проблем с переплетениями нескольких лент во время работы. По сути первые компьютеры и были такими себе одноленточными реализациями машины Тьюринга. Потом, в процессе эволюции, возникла необходимость делить процессорное время между несколькими операторами, для чего увеличивали мощьность процессорных устройств, повышали частоту, появились RISC процессоры, конвейерная обработка команд, процессорный кеш и много-много других усовершенствований, о которых 99.99% людей, пользующихся компьютерами даже не догадываются. В общем, однопоточные процессоры делались все сильнее, быстрее, совершеннее и отлично подходят для задач, где надо выполнять действия последовательно. Но что если такой подход неэффективен для ряда задач? Что если заменить несколько "одноленточных" суперпроцессоров на несколько тысяч не таких супер, но все же реально параллельных процессоров? Какие задачи тогда можно решать быстрее?
Задача из курса.
Предположим есть очень длинная палка колбасы (несколько км длиной), за которой стоит длинная очередь в сотни (а может и тысячи) людей. Каждый человек говорит какой длины кусок ему надо отрезать.
Традиционное последовательное решение было бы таким: каждый по очереди подходит и ему отрезают кусок такой длины, какой скажет. Понятно, что для очереди длиной, например, в миллиард, мы бы занимались этим очень долго.
Можно ли сразу у всех спросить длину отрезка, нанести разметку и, имея несколько тысяч ножей, сразу разрезать так как надо?
В этом курсе мы практиковались в решении подобного рода задач с использованием GPU, узнали много нового о многопроцессорной архитектуре. Задания надо было реализовывать на C с использованием CUDA SDK. У кого не было возможности отлаживать код локально (т.к. надо GPU от NVIDIA), те могли загружать код прямо из браузерного окна редактирования и дебажить способом просмотра логов. Форум был очень активен и там часто можно было найти подсказки на решения проблем. Очень жаль, что этот курс был всего один раз и непонятно будет ли повторяться, но есть похожий курс на Udacity.



Discrete Optimization 


Страница курса: https://www.coursera.org/course/optimization

Университет: The University of Melbourne
Сложность: 4.9

Как только я посмотрел интродактори видео я понял, что будет очень интересно и не ошибся. Профессор оказался еще тем гиком. Я вот даже не поленился добавить это интродактари видео:


О чем курс

Сколько надо цветов, чтобы раскрасить карту так, чтобы соседние государства не были окрашены в одинаковый цвет? А если государств 1000 или 10000? 
По какому маршруту должна ездить фура чтобы развезти продукты по нескольким магазинам и потратить как можно меньше горючего/времени? А если магазинов 1000, а фур всего 10?
Классическая задача комивояжера - как найти оптимальное решение для 10 городов? А для 100? А для 1000? А вообще возможно ли его найти за относительно небольшое время? А если нет, то как можно максимально приблизиться к оптимальному решению?
Вот такие задачи мы учились решать в рамках курса. Оказывается есть довольно много инструментов, которые успешно применяются для задач оптимизации. Это и constraint programming и алгоритмы локального поиска (local search), и линейное программирование (linear programming), и целочисленное программирование. (integer programming)
Практические задачи были разделены на 5 уровней сложности. Для каждого уровня свой набор входных данных. Например, для задачи комивояжера для уровня 1 было до 10 городов, для 2го от 10 до 50, для 3-го от 100 до 200, 4й -500 - 1000 и для 5-го более 50тыс. Если первые пару уровней обычно можно было решить простым перебором, то начиная с 3го все становилось очень интересно. Естественно, чтобы получить сертификат нужно было решить все задачи как минимум 3го уровня сложности, а для сертификата с отличием (with distinction) - 4го и 5го.
Попробовал тулы
- SCIP optimizer http://scip.zib.de/. Простой и быстрый оптимизатор, оптимизирует задачи с помощью constraint programming и linear-integer programming. Поддерживает стандарт языка ZIMPL. Очень хорошо ломает мозг.
- GLPK solver: http://www.gnu.org/software/glpk/. Изначально я пробовал его для некоторых задач, но потом перешел на SCIP, не помню почему
- Много кодил на Java :). Задачу комивояжера, например, оптимизировал с помощью алгоритма K-opt (local search) и Simulated annealing для поиска глобального минимума.


Tuesday, April 28, 2015

Парадокс дней рождения





Недавно, проходя мимо доски с именинниками вспомнил про так называемый "парадоск дней рождения". Подобно парадоксу Монти Холла, этот "парадокс" на самом возникает из-за неправильного решения, которое подсказывает интуиция подзабывших теорию вероятности людей.

Задача

Допустим в компании работает 25 человек. Какая вероятность того, что у двух людей из этой компании день рождения в один и тот же день?

Интуитивное решение

Ход мыслей может быть примерно такой: 25 человек, у каждого день рождения 1 раз в 365 дней. Поскольку надо 2 совпадения, то вероятности перемножаются, и, поскольку это надо повторить для всех, то еще умножить на 25:
  \(\frac{25}{365} * \frac{25}{365} * 25\), то есть \(\frac{25}{365}\).

Правильное решение 

Правильное решение и математическое доказательство хорошо описаны в вики, см. Парадокс дней рождения, его я здесь повторять не буду. Я же напишу програмку, которая покажет кто прав - интуиция или теория вероятности.

Пишу код

Для подобных экспериментов, результаты которых можно сразу же опубликовать мне очень нравится Python notebook. Его можно установить себе на компьютер, но я воспользуюсь бесплатным сервисом от https://www.wakari.io

В wakari.io создал новый файл, вставил ячейку (cell) типа Code и в ней заимпортил NumPy и вывел номер версии:

Затем создал функцию, которая создает массив размером n, каждый элемент которого случайное число от 1 до 365:

Эта функция проверяет есть ли в массиве birthdays элементы, которые повторяются больше чем 1 раз:

Запускает эксперимент несколько раз и возвращает количество успешных экспериментов (количество совпадений > 1)

Запускаю эксперимент и получаю вероятность того, что в группе из 23 человек хотя бы у двух совпадут дни рождения:

Вероятность более 50%, то есть интуитивное решение не является правильным.

Wakari.io очень прикольный сервис, он позволяет публиковать свои поделки. Этот код целиком можно глянуть тут: https://www.wakari.io/sharing/bundle/szelenin/birthdays

Ссылки на использованные материалы

Wakari.io -  online сервис для анализа данных на Python.
Парадокс дней рождения на википедиит
- Мой код  https://www.wakari.io/sharing/bundle/szelenin/birthdays


Friday, April 17, 2015

Softmax Regression Pylearn2

На установленном ранее pylearn2 пробую пройти туториал. Начну с softmax регрессии.
ссылка на туториал:
http://nbviewer.ipython.org/github/lisa-lab/pylearn2/blob/master/pylearn2/scripts/tutorials/softmax_regression/softmax_regression.ipynb

Пытаюсь установить ipython

В принципе туториал можно запустить локально. Надо только ipython установить:
Захожу на запущенную Vagrant виртуалку и запускаю команду

sudo pip install "ipython[all]"

Нельзя инсталить без [all]:
sudo pip install ipython
и вот почему: http://stackoverflow.com/questions/24995438/pyzmq-missing-when-running-ipython-notebook

дальше перехожу в папку с туториалом:
cd /home/vagrant/pylearn2/pylearn2/scripts/tutorials/

и запускаю ipython'овский notebook:
sudo ipython notebook

ноутбук запустился в аутентичном текстовом браузере w3m :)

Немного побаловался, но в хроме все-таки удобнее было бы работать :). Для этого надо "перебросить" порт, который внутри виртуальной машины "наружу", чтобы я мог с хост системы зайти браузером.
-Смотрю какой порт использовал ipython :
Добавляю в "forwarded_port" в Vagrant файл (сразу за config.vm.box):
  config.vm.network "forwarded_port", guest: 8888, host: 8888
И перегружаю vagrant (команда vagrant reload):

не заработало... :(

Update

Проблема решилась после того как сделал uninstall ipython (тот, который не [all])
sudo pip uninstall ipython 

и заново проинсталил ipython[all]:
sudo pip install ipython[all]

Оставлю пока ipython, делаю в отдельном файле train.py.


import os
import pylearn2
dirname = os.path.abspath('/vagrant/ml_invsetigaiton/pylearn2_softmax')
with open(os.path.join(dirname, 'sr_dataset.yaml'), 'r') as f:
    dataset = f.read()
hyper_params = {'train_stop' : 50000}
dataset = dataset % (hyper_params)
print dataset


Результат:

vagrant@vagrant-ubuntu-trusty-64:/vagrant/ml_invsetigaiton/pylearn2_softmax$ sudo python train.py
OpenBLAS : Your OS does not support AVX instructions. OpenBLAS is using Nehalem kernels as a fallback, which may give poorer performance.
!obj:pylearn2.datasets.mnist.MNIST {
        which_set: 'train',
        start: 0,
        stop: 50000
}

Что это было?
грубо говоря прочел YAML файл, в котором было описание датасета из набора MNIST. Этот набор поставляется с pylearn2. Всего в наборе 60000 записей, но я передал гиперпараметр, который обозначает, что стопнуть обучение нужно на 50000

короче, скопировал я все степы, запустил, но выдалась такая ошибка:

оказывается надо самому скачать MNIST датасет. Хорошо, что pylearn2 предоставляет для этого скрипт. в папке ~/pylearn2/pylearn2/scripts/datasets запускаю python download_mnist.py:


Запускаю опять, модель в процессе обучения печатает как хорошо она обучается:


Теперь чтобы расшифровать результаты запускаю скрипт print_monitor.py, который находится в /home/vagrant/pylearn2/pylearn2/scripts и передаю ему сгенерированный файл с моделью:


Процент неправильно классифирированых записей из тестового набора 7.68 (test_y_misclass: 0.0768)


Sunday, March 29, 2015

Ставлю IntelliJ Idea + Oracle JDK на Ubuntu в Vagrant (VirtualBox)

Изучаю Pylearn2 в Идее


В один прекрасный момент мне надоели эти юниксовые редакторы текста для редактирования и отладки исходников во время прохождения туториала по Pylearn2. Хочу поставить графическую оболочку и там редактировать питоновские файлы. Может даже и задебажить или пробраузить код.

Ставлю графическую оболочку xfce4.

Загуглил и пошел инсталлить по первой же ссылке:
http://stackoverflow.com/questions/18878117/using-vagrant-to-run-virtual-machines-with-desktop-environment
Выполнил все инструкции, перезапустил виртуалку (vagrant reload). В появившемся окне VirtualBox'a залогинился как vagrant/vagrant.

Ставлю Oracle JDK 8

Опять же загуглил и нашел чудовую пошаговую инструкцию как инсталлить ораковую ждк на убунту (14.10)
http://www.wikihow.com/Install-Oracle-Java-JDK-on-Ubuntu-Linux
По шагам все сделал почти по инструкции за исключением путей
Перезапускаю

Тоже по инструкции.

Из UXTerm (можно и из XTerm) набираю idea <Enter>: 

Вау, красота то какая!




Все, теперь ставлю Python plugin и дальше буду работать в нормальной IDE :)

Saturday, March 28, 2015

Установка Pylearn2 с помощью Vagrant и puppet

Добрался я наконец-то до компа, но не так чтобы для работы, а подтянуть свои практические знания по Machine learning на python. В последнее время в тренде всякие диплернинги (http://deeplearning.net), особенный пинок в этом направлении дала возможность обучения нейронных сетей с использованием GPU, что на порядки увеличивает процесс обучения.

Далее я буду пытаться утановить Pylearn2 со встроенной поддержкой Theano. Забегая вперед скажу, что сначала я описываю процесс наступления на грабли, а в конце привел исправленный процесс. Так что нетерпеливым можно сразу туда :).

Итак, начнем.

Я взял инструкцию по установке Pylearn2 отсюда: http://deeplearning.net/software/pylearn2/

1. Устанавливаю Vagrant

Актуальная версия 1.7.2
https://www.vagrantup.com/downloads.html
скачал, перезапустил комп

2. Устанавливаю VirtualBox

https://www.virtualbox.org/wiki/Downloads
и VirtualBox Extension Pack (там же)

3. Устанавливаю pylearn2 из образа

клонирую репозиторий с настройками Vagrant
git clone git@github.com:ironchief/pylearn2_vagrant.git
и в папке pylearn2_vagrant стартую Vagrant:
vagrant up


Скачивание образа застопорилось на 12%, поэтому я скачал образ вручую. В файле Vagrant указан url на образ:
config.vm.box_url = "http://files.vagrantup.com/precise64.box"
эту строку я заменил на:
config.vm.box_url = "C:/workspace/bin/images/precise64.box"

Опять запустил vagrant up
Упало с непонятной ошибкой. 

Следую рекоментациям открыть машину в GUI. Переключаюсь в VirtualBox, где появилась новая машина и пытаюсь ее стартовать:

Включаю виртуализацию в биосе, и опять запускаю vagrant up:

puppet долго конфигурирует систему...
и в результате выдал маловразумительную ошибку :(

понять что произошло помог лог файл pip.log, который лежит в папке pylearn2_vagrant. Там вот такая ошибка:
numpy.distutils.system_info.NotFoundError: no lapack/blas resources found

Гугл в помощь, на stackOverflow нашел интересный пост: http://stackoverflow.com/questions/7496547/does-python-scipy-need-blas

В puppet манифест (pylearn2_vagrant/manifest/default.pp) в раздел package добавил liblapack-dev :

и опять запустил vagrant с командой provision :
vagrant provision
опять долго инсталлируется ...

День 2

На следующий день я решил начать все сначала. Но перед экспериментами я форкнул себе репозиторий https://github.com/ironchief/pylearn2_vagrant, склонировал уже свой репозиторий (https://github.com/szelenin/pylearn2_vagrant) в новую папку и в Vagrant файле поставил версию последней убунты:
config.vm.box = "ubuntu/trusty64"

и запустил команду vagrant up из новой папки pylearn2_vagrant:
и о чудо! все проинсталлилось с первого раза!

Финальная версия

Итого чтобы поставить pylearn2 (в моем случае на винду) надо

1. Установить Vagrant

актуальная версия 1.7.2
https://www.vagrantup.com/downloads.html

2. Установить VirtualBox

https://www.virtualbox.org/wiki/Downloads
и VirtualBox Extension Pack (там же)

3. Склонировать форкнутый репозиторий 

Пулреквест отошлю чуть позднее
git clone git@github.com:szelenin/pylearn2_vagrant.git

4. Запустить Vagrant

Переходим в папку pylearn2_vagrant и запускаем команду (желательно из вменяемой консоли, я делал это из git bash)
vagrant up
* Возможно прийдется включить поддержку виртуализации в BIOS.

5. Enjoy

Дальше можно приконектиться по ssh (я использую XShell) порт 2222, пользователь vagrant/vagrant

Используемые материалы

3. Puppet провижнер для Vagrant и сам Vagrant файл: https://github.com/ironchief/pylearn2_vagrant 
4. Мои дополнения для последней версии ubuntu: https://github.com/szelenin/pylearn2_vagrant