15 Ocak 2017 Pazar

Single Responsibility Principle





Tek Sorumluluk Prensibi  S.O.L.I.D prensiplerinden biridir. Bir yazılım modülünün (sınıfın, metodun, fonksiyonun, arayüzün, algoritmanın) sadece tek bir sorumluluğu olması fikrini ön plana çıkartır. Bu ifadeyi tersten okuduğumuzda bir yazılım modülü, sadece tek bir nedenden dolayı değiştirilebilir olmalıdır sonucuna erişebiliriz.

Yazılım birimi, finans birimi, IK birimi olan bir kurumda kullanılan yazılım uygulamasında aşağıdaki sınıf tasarımı olduğunu varsayalım.


Employee sınıfı, yazılım temel katmanında (domain) modellediği varlığın (soyut ya da somut) özelliklerini sunan bir model sınıf olması gerekirken, sanki servis katmanındaki bir sınıf gibi duruyor. Model ve servis sorumlulukları iç içe girmiş gibi gözüküyor. Bu durumu düzeltmek adına temel katmanda Employee model sınıfı varmış gibi düşünüp yukarıdaki sınıfın ismini ve metodlarını aşağıdaki gibi değiştirip tekrar ele alalım.


Servise çalışan maaş hesaplaması, mesai raporlama ve özlük bilgisi saklama sorumluluklarının
yüklenmiş olduğu bilgisi sunduğu metodlardan görülebilmektedir.

IK birimi,  maaş hesaplamasında iş kurallarını değiştirdiğinde servis değişime gidecektir. Departmanlardan herhangi biri yeni bir rapor ya da raporlamalarda farklılık istediğinde servis değişecektir. Özlük bilgilerinde veya veritabanı şemalarında değişim olduğunda servis değişecektir.

Bu değişimleri yazılım birimi nasil el alacaktır ?
Aynı anda aynı yazılım modülünde çalışmak durumuna düşmeyecekler midir ?

Bütün yollar Roma' ya çıkabilir ama farklı neden ve sorumluluklarla açılan değişimler aynı yazılım modülüne çıkıyor ise tasarım hatası yapıyor ve sanırım Nero' nun izinden gidiyoruz demektir.


https://tr.wikipedia.org/wiki/Neron

Yukarıdaki servisi tek bir sorumluluk alacak şekilde tekrar düzenleyelim.



Tek sorumluluk prensibine sadık kalmak amacı ile servis sınıfları (Facade tasarım kalıbı), servis katmanında sorumluluklarına göre ayrıldı. Ayrıca sistemin bütününe girmeden tek bir noktadan kullanıcıya bu servisler EmployeeServis sınıfı üzerinden sunuldu (Yine Facade).

Fakat prensip ihlali devam etmekte. Bütün sınıflar tek bir (.cs) dosyası içine koyulmuş.  (.cs) dosyasına birden fazla neden ile gitme ve değişim yapmak söz konusu olmakta. Ayrıca EmployeeServis sınıfı sorumluluklarını diğer sınıflara dağıtmış ama hangi sınıflarla çalışacağını bilmek ve onları oluşturmak görevini almak durumunda kalmış. En azından sorumluluğu dağıttığı diğer sınıfların ismi değişse bu EmployeeServis sınıfında da değişime neden olacak. Bahsedilen bulgulara göre tekrar düzenleme yapalım.

Aşağıda EmployeeServis sınıfı, son kullanıcının kullanımına açtığı diğer sınıflarla iletişimini arayüzler üzerinden yapmaktadır. İşlevi bilmekte ama bu işlevi yerine getiren öznenin kendisini bilmemektedir. Diğer sınıfların dağılımını sizlere bırakmaktayım.



Görüldüğü üzere prensip sadece kod bazında değil organizasyon bazında da kullanılmaktadır.
Çok katmanlı yazılım mimarisi denildiğinde sizce bu prensip orada da kendini göstermekte midir ?
Cevabı size bırakıyorum.


5 Ocak 2017 Perşembe

ROS Turtlesim Robot Simülasyonu


Bir önceki yazımızda Matlab Ros paketine giriş yapmış ve temel ROS komutlarıyla çalışmıştık. Bu yazımızda ilk robot simülasyon programı olan Turtlesim ile Matlab üzerinden çalışacağız ve ağ üzerinden ROS düğümleriyle haberleşeceğiz. Gereken ağ yapılandırmaları önceki yazılarda anlatıldığı için o kısma tekrar girilmeyecek.

Matlab üzerinde rosinit ile ROS platformunu başlatalım.
Ubuntu makinaya geçelim ve makinalar birbirini görüyor mu kontrolünü aşağıdaki komutu terminal üzerinde çalıştırarak yapalım.
rosnode list
Gelen cevap aşağıdaki gibidir. Matlab global düğümü listelenmiştir.
/matlab_global_node_74764
dikkat ederseniz Ubuntu üzerinde ROS komutlarını roscore komutunu çağırmadan çalıştırdım. Ubuntu makinada ROS_MASTER_URI değerini Matlab makina verdiğim için Ubuntu üzerindeki ROS platformu, Matlab makinadaki master 'a bağlanarak düğüm listesini çekti. Bu bilgiyi alamasaydım komut askıda bekleyecek ve bir müddet sonra hata bildirecekti. Bağlantı kontrolünü düğüme ping atarak da yapabilirdim. 
rosnode ping /matlab_global_node_74764
Bağlantı kontrolünden sonra Turtlesim simülatör programımızı aşağıdaki komutla çalıştıralım. Bu simülasyon her seferinde farklı ROS sürümlerine ait turtle1 isimli bir deniz kaplumbağası ve düğümü oluşturur. Dilerseniz ismini aşağıdaki komuta parametre geçerek değiştirebilirsiniz.Bu durumda düğüm ismi turtle1 değil verdiğiniz isim olacaktır. 

Bu kaplumbağa bizim robotumuzdur. ROS platformunda robot demek ise düğümler, topikler, mesajlar, servisler (daha önce hiç bahsedilmedi.) demektir.
rosrun turtlesim turtlesim_node
rosrun turtlesim turtlesim_node __name:=minik



rosrun [paket ismi] [koşturulabilir dosya ismi ] komutu turtlesim paketinin lokasyonuna gitmeden (cd/rosrun kullanmadan) paket ismi üzerinden  bize programın çalıştırılmasını sağladı.

Paketin bulunduğu dizine roscd komutu ile gidebilirsiniz. roscd paket ismini verdiğimizde ilgili klasöre gitmemizi sağlayan bir ROS komutudur.
roscd turtlesim
komut cevabı olarak /opt/ros/indigo/share/turtlesim dizinine gideriz.

rosnode list komutunu çalıştırıp robot kaplumbağanın sunduğu düğümler nelerdir diye baktığımızda /turtlesim düğümü ile karşılaşıyoruz. 

Bu düğüm hakkında bilgi almak için aşağıdaki komutunu koşturalım. 
rosnode info /turtlesim
Ekran görüntüsü aşağıdaki gibidir.


ROS Grafik gösterimi ile düğümler ve birbirleriyle ilişkilerini görsel olarak görmek için aşağıdaki komutu koşturuyorum.
rqt_graph
Ekran görüntüsü aşağıdaki gibidir.



Yukarıdaki grafikte turtlesim isim uzayi altında /turtlesim düğümünü görmekteyiz. Oklara dikkat edersek, Bu düğüm turtle1 isim uzayı altında /turtle1/color_sensor topiğini yayınlıyor,
/turtle1/cmd_vel topiğine abone ve /turtle1/pose düğümünü yayınlıyor. rqt_gui_ öneki ile başlayanlar ise rqt_graph komutu ile çalışan uygulamanın oluşturduğu düğüme ait grafiklerdir.Onları dikkate almanıza gerek yoktur.

Robot kaplumbağayı ilk gördüğümde acaba rengini değiştirebilir miyim gelmişti aklıma. Şu ana kadar verilen bilgiler ışığında yukarıdaki bilgilere bakarak buna nasıl bir cevap verebiliriz ?

Robotumuz /turtle1/color_sensor topiği üzerinden turtlesim/Color tipinde mesaj yayınlıyor. Yayınladığı bilginin içeriğine bakalım.
rostopic echo /turtle1/color_sensor
robotumuz renk bilgisini sürekli yayınlamakta, bu yüzden akan bir veri gelmektedir.


echo komutundan sonra ROS grafiğine bir daha bakalım.



rostopic echo komutu /turtle1/color_sensor topiğini dinlemek için anlık bir düğüm oluşturup bu düğüm üzerinden topiğe abone olmuştur. (/rostopic_4913_1483531062271)  

Topikden gelen değerler {r:69 g:86,b:255} gözüküyor. Bu rengi görüntülemek için rapidtables sitesine giderek renk tablosunda değerleri yerine koyduğumda rengin robota ait değil simülasyon arka plan rengine ait olduğunu gözlemledim. Yukarıdaki robot renk bilgisi yayınlıyor cümlesini artık simülasyon renk bilgisi yayınlıyor diye değiştirmem gerekiyor. Bu düğümler simülasyona ait ve onunla robot üzerinde işlem yapabiliyoruz demem gerekir. 

Bu durumda soruyu güncelleyelim; Acaba simülasyon arka plan rengini /turtle1/color_sensor topiği üzerinden turtlesim/Color tipinde mesaj göndererek değiştirebilir miyim.? Cevabı aşağıdaki adımları izlemeden direk rosnode info komutu çıktısına veya ROS grafiğine bakarak verebilirsiniz.

Mesaj tipini inceleyelim. Bunun için yeni bir terminal açıyorum ve aşağıdaki komutu koşturuyorum.
rosmsg show turtlesim/Color
Gelen cevap aşağıdaki gibidir.


Var olan terminali kapatmadan yeni bir terminal açıyorum ve aşağıdaki komutla topiğe arka plan rengini {r:255,g:0,b:0} kırmızı yapmasını söyleyen mesajı saniyede 10 (100 ms de bir kere.) kere gönderecek şekilde koşturuyorum. (10Hz)
rostopic pub -r 10 /turtle1/color_sensor turtlesim/Color '{r:255,g:0,b:0}'  
Simülasyon programına bakıyorum ve arka plan renginin değişmediğini görüyorum. 
rosnode echo komutunu çalıştırdığım terminale gidiyorum ve (r,g,b) değerinin değişmediğini görüyorum. rqt_graph komutunu tekrar çalıştırıyorum. Ekran görüntüsü aşağıdaki gibidir.

Önce ROS grafik bilgilerine bakalım. rostopic pub komutu ile birlikte yeni bir düğümümüz oluşmuş (kırmızı renkli düğüm) ve  /turtlesim/color_sensor  topiği yayınlamaktadır. Yayına abone olan bir düğüm gözükmemektedir. 

rosnode info terminalindeki bilgilere bakıyorum. /turtle1/color_sensor topiği /turtle1 düğümü tarafından yayınlanıyor ama abone değil. Abone olmadığı için bizim gönderdiğimiz topik mesajını almamış ve arka plan rengi değiştirilmemiş oluyor. 

Biraz önceki sorunun cevabı da böylelikle açıklık kazanıyor. Rengi bu şekilde değiştiremeyiz. 

Robotumuzu hareket ettirebilir miyiz.?  Evet. ROS grafiğe, yahut rosnode info geri dönüşüne baktığımda /turtlesim düğümünün, turtle1/cmd_vel topiğine abone olduğunu görmekteyiz.

Simülasyon hariç tüm terminalleri kapatalım ve rostopic pub komutuna kadar tüm adımları turtle1/cmd_vel topiği için tekrarlayalım. rostopic echo komutunu koşturduğunuzda robot durduğu için gelen bir bilginin olmadığını, ayrıca mesaj tipinin de geometry_msgs/Twist olduğunu göreceksiniz.  Hız bilgisini düzlemsel ve açısal olmak üzere iki parça şeklinde vermektedir. Bunlar uzaydaki (x,y,z) doğrusal hızı (m/sn) ve (r,p,y) açısal hızı (radyan/sn) şeklindedir.



rostopic pub komutunu aşağıdaki gibi düzenleyip koşturalım.
rostopic pub -r 10 /turtle1/cmd_vel geometry_msgs/Twist '{linear: {x: 0.1, y: 0, z: 0}, angular: {x: 0, y: 0, z: 0}}'  
ROS SI (International System of Units) ölçü birimlerini kullanmaktadır. Doğrusal uzunluk birimi metre ve açısal uzunluk birimi radyan olarak geçmektedir. ROS ölçü birimleri ve dönüşümleri ile ilgili bilgiyi bu linkten edinebilirsiniz.

Yukarıdaki komutta girdiğimiz parametre ifadesi YAML formatındadır.
'{linear: {x: 0.1, y: 0, z: 0}, angular: {x: 0, y: 0, z: 0}}'

Dogrusal x bilgisi dışında bir bilgi kullanmadığım için bu parametre ifadesini aşağıdaki gibi yazabilirim.
'{linear: {x: 0.1}}'

Yukarıdaki komut ile  mesajı 10 Hz ile yayınlamaktayız. Bu robotumuza x ekseni boyunca 1 sn de 10* (0.1) = 1 metre lineer hızla git demek anlamına gelmemektedir.  Robota 1 sn'de 10 kere (100 ms de bir) 0.1 m/sn hızla git demekteyiz. Simülatörümüz bir fizik motoru içermez ve robotu hareket ettirmek için sürekli komut göndermek durumundayız.

Komut çalışmaya başladığında, echo komutunu çalıştırdığımız terminalde bilgilerin aktığını göreceksiniz. Simülatör uygulamasında ise robotumuzun x ekseni boyunca hareket etmeye başladığını göreceksiniz. Kaplumbağa robotumuz kum üzerinde hareket ediyormuş gibi iz bırakmaktadır. Robotumuz bir müddet sonra simülatörün sınırlarına gelecek ve daha ileri gidemeyecektir. rostopic echo komutunu koşturduğumuz terminalde "Oh no ! I hit the wall!" mesajını alacaksınız.




















robotumuza geometry_msg/Twist mesajı göndermeyi durduralım.
Robotumuzu başlangıç noktasına tekrar getirmek için yukarıda rosnode info komutunun çıktısında yer alan servis bilgilerine bakacağız.  (Dilerseniz x = -0.1 vererekte robotunuzu geri döndürebilirsiniz.)

/turtlesim düğümünün sunduğu servislerden biri /reset olarak gözükmektedir. Aşağıdaki komutu bu bilgiye göre koşturuyorum.
rosservice call /reset
Turtlesim simülatörüne baktığımızda yeni bir kaplumbağanın geldiğini ve başlangıç noktasına konumlandığını göreceksiniz.

Düğümler birbirleriyle topikler üzerinden mesaj üye/yayıncı ilişkisi içerisinde haberleşmekte idi.
Bu haberleşme yöntemi tek taraflıdır. Sadece mesaj alabilirsiniz yahut yayabilirsiniz. Servis kavramı düğümlerin birbirlerine talep göndermelerine ve cevap almalarına imkan verir.

Kaplumbağanın iz rengini değiştirmek için /turtle1/set_pen servisini parametreleri ile çağıralım.Önce servis hakkında bilgi alalım.
rosservice info /turtle1/set_pen
Ekran görüntüsü aşağıdaki gibidir.



Servisin parametre tipi turtlesim/SetPen olduğu görülmektedir.
Servisin parametreleri (r, g, b, width, off) şeklindedir.
width : kalınlık, off: görünülürlük şeklinde açıklanabilir.

Dilerseniz aşağıdaki komut ile de servisin parametresi hakkında bilgi alabilirsiniz.
rossrv show turtlesim/SetPen
Ekran görüntüsü aşağıdaki gibidir.


Aşağıdaki komutu yukarıda elde ettiğimiz bilgiler ışığında çağıralım.
rosservice call /turtle1/set_pen 255 0 0 3 1
rostopic pub ile tekrar robotu hareket ettirdiğinizde izin kırmızı olduğunu göreceksiniz. /reset servisini çağırırsanız izin rengi varsayılan haline gelecektir.

robotumuza ait hız bilgilerini grafik olarak görmek için aşağıdaki komutu koşturuyoruz.
rqt_plot
Aşağıdaki gibi bir ekran açılacaktır. Ek bilgi; karşılaştığımız rqt_plot ve rqt_graph komutlarında geçen r= ros qt= QT (Platform bağımsız yazılım geliştirme platformu) şeklinde okunabilir.



Topik kısmına /turtle1 yazdığımda abone olabileceğim topikler listelenecektir. Bunlardan /turtle1/pose topiğini seçiyorum ve (+) butonuna basıyorum (/turtle1/cmd_vel topiği neden çıkmıyor diye soracak olursanız yanıtı size bırakıyorum. ). Topik turtlesim/Pose tipinde mesaj yayınlamaktadır. Bu mesaj içeriği {x,y,theta,linear_velocity, angular_velocity} şeklindedir. Bunlardan şu aşamada sadece linear_velocity ile ilgileniyorum. (-) butonuna tıklayarak ilgilenmediğim diğer bilgileri çıkarıyorum. Robotu hareket ettirmeye başlattıktan sonra  rqt_plot uygulamasında başlat butonuna basarsanız 10 Hz lik örnekleme ile grafik bilgilerini göreceksiniz.

Son olarak simülatörümüzün arka plan rengini değiştirelim. Hatırlarsanız ilk aklımıza gelen fikir buydu. Bunu değiştirebileceğimiz bir servis yada topik mesajı bulunmamaktadır. Burada ROS parametre servisinden yararlanacağız. Parametre servisini sistem bazında konfigürasyon servisi gibi düşünebiliriz. Çalışma anında erişime açık olan servis parametrelerine, düğümler erişebilir ve değiştirebilir. Aşağıdaki komutu koşturarak parametre servisinin bize sunduğu parametreleri keşfedelim.

rosparam list

Ekran görüntüsü aşağıdaki gibidir.


Arka planı güneşli bir gündeki kumsal rengine büründürmek için (r, g, b) = (238, 236, 201) renk bilgisini verelim.

rosparam set /background_r 238
rosparam set /background_g 236
rosparam set /background_b 201
Değişikliklerin etkin olabilmesi için aşağıdaki komutu koşturalım.
rosservice call /clear
Ekran görüntüsü aşağıdaki gibidir.



ROS temel komutları ile simülatör uygulamasında çalıştık. Bu komutlar ile sistem üzerinde test ve diagnostik işlemler yapabilir hale gelmiş olduk.

Son bir bilgi olarak şunu ekleyelim; ros pub komutuyla o an bir topik oluşturabilir ve ros echo ile dinleyebilirsiniz.
rostopic pub -r 10 /test_topic std_msgs/String 'merhaba ros'
rostopic echo /test_topic
Yukarıdaki komutları çalıştırdıktan sonra rqt_graph ile analiz edebilirsiniz.
Bir sonraki yazıda, kaplumbağa robotu, matlab ortamında komutla hareket ettireceğiz.

3 Ocak 2017 Salı

Matlab Robotik Paketi ve ROS

Bir önceki yazımızda ROS ve kurulumu hakkında bilgi vermiştik. Bu yazımızda Matlab Robotik paketi kullanımı hakkında bilgi vereceğiz. Bunu yaparken de temel ROS komutlarına değinmiş olacağız.

Çalisma ortamimizda iki adet makina var. Bir adet windows 7 pc ve bir adet windows 10 dizüstü bilgisayar. Windows 7 pc de matlab R2015b kurulu. Dizüstü makina üzerinde vmware sanal makinada Ubuntu 14.4 kurulu. Ubuntu 14.4 isletim sistemini Osboxes sitesinden edinebilirsiniz.

Dizüstü makina mobil robotumuz olup, wifi üzerinden ağ ortamina bagli. Iki makinayi robotun özellesmis isler yapan parçalariymis gibi düsünecegiz. Hatirlarsaniz ROS ag ortaminda dagitik mimariyi desteklemektedir. Masaüstü makinaya ubuntu kurmadigima dikkat etmissinizdir. Matlab robotik paketi sayesinde windows üzerinde iken, Ubuntu üzerindeki bir ROS düğümü ve ROS master ile baglanti sağlayabilirsiniz.

Windows 7 makina başlangıçta türkçe dil desteği ile kuruluydu. Matlab kurulumu gerçekleştirdikten sonra ROS Master 'i matlab komut satırından çalıştırmak istediğimde komut hata verdi. Yegane çözüm olarak işletimin dilini ingilizceye çevirdim ve tekrar denediğimde hatanın ortadan kalktığını ve ROS Master'in çalıştığını gördüm. Bu zaman kurtaran bilgiden sonra ilk olarak Matlab robotik paketi üzerinde çalışmaya başlayalım.

Aşağıdaki komutu Matlab komut penceresine yazarak makinanızın ip bilgisini öğrenelim. Üzerinde çalıştığım, Matlab kurulu makinada bu değer 192.168.1.2 olarak gözüktü.

system('ipconfig')
Bir önceki yazida bahsedilen ROS sistem değişkenlerini kontrol edelim.

getenv('ROS_MASTER_URI')
getenv('ROS_IP')
Bu değerler varsayılan olarak boş gelecektir.  Bu şekilde ROS master modülünü çalıştıralım. (Matlab komut penceresi temizleme komutu clc, değişkenleri silme komutu clear dir.)

rosinit
Aşağıda komut cevabına baktığımda makina ismi "ev" olduğu için URI bilgiside aşağıdaki şekilde gözüktü. Sizde de kendi makina isminiz gözükecektir. Ayrıca Master URI port numarası siz değiştirmedikçe Ubuntu ve Matlab için varsayılan olarak aşağıda görüldüğü gibi 11311 değerindedir.

Initializing ROS master on http://ev:11311/.
Initializing global node /matlab_global_node_40973 with NodeURI http://ev:3988/

Network üzerinde haberleşme problemi oluşmaması için ROS_MASTER_URI ve ROS_IP değerlerini uygun değerleriyle değiştireceğim.

ROS Master, Matlab kurulu makinada olacak. ROS_MASTER_URI değerini de doğal olarak 192.168.1.2 olarak girmek istersem Matlab ROS master çalışmayacaktır. Ubuntu üzerindeki ROS platformundan bu yönüyle farklılık gösterir. Matlab, ROS_MASTER_URI 'ye yazdığınız ip bilgisini ağ üzerinde master makina olarak düşünüp bağlanmaya çalışır (Bu zaten benim ip değerim demez.). Halbuki siz o sırada Ros master'i çalıştırmaya çalışmaktasınız. Ubuntu üzerinde bu değişikliği yaparsanız sorunsuz çalışır. ROS_MASTER_URI değişkeninde değişiklik yapmayıp, varsayılan değer olarak boş bırakacağım. IP değerini ise aşağıdaki gibi değiştireceğim.

setenv('ROS_IP','192.168.1.2') 
Yeni değerlerin etkin olabilmesi için ROS platformunu kapatıp tekrar devreye alacağım.

rosshutdown
rosinit
Aşağıda komut geri dönüş mesajına baktığımızda yukarıda girilen değerler kullanılarak ROS platformunun master ve bir global düğümle başlatıldığını göreceksiniz.

Initializing ROS master on http://ev:11311/.
Initializing global node /matlab_global_node_94215 with NodeURI http://192.168.1.2:4050/
Bu aşamada ROS master çalışmaya başladı. Şimdi komut penceresinde ROS ortamında var olan düğümleri listelemek için rosnode komutunu çalıştıralım. Bu ve yazacağımız komutlar ROS platformu komut kümesine aittir, yani Ubuntu üzerinde kullanılır. Matlab robotik paketi bize ROS simülasyonunu sağladığı için bu komutları windows makina üzerinde kullanabilmekteyiz.

rosnode list

/matlab_global_node_94215 şeklinde bir sonuç geldi. Ubuntu makinada master açmak için roscore ile başlayıp bu komutu çalıştırsaydim matlab'den farklı olarak /rosout  diye bir düğüm ile karşılaşacaktım.

Düğümlerin koşturulabilir ve diğer düğümlerle mesajlar üzerinden haberleşebilir programlar olduğunu tekrar hatirlayalim. Haberleşebilmek için düğümlerin birbirlerine mesaj göndermesi (publisher) ve alabilmesi(subscriber) gerekir. ROS platformunda mesajın bir konusu (topic) ve tipi olmak zorundadır. Aradaki ilişkiyi böylede göstermek mümkündür; (Node<---->Topic---->Message)
Bir düğüm birden fazla topik yayınlayabilir ve birden fazla topiğe üye olabilir. Gerek düğüm ve gerekse topik isimleri sistem bazında tekil olmalıdır.

Sistemdeki tüm düğümler log, diagnostik mesajlarını /rosout topiği üzerinden yayabilir (Publisher).
/rosout düğümüde /rosout topiğine üye olduğu (Subscriber) için bu mesajları alabilir ve bunları bir log dosyasında saklar ve/veya  bu log mesajlarını diğer abone düğümlere /rosout_agg topiği üzerinden yayınlayabilir (Publisher). Aşağıda /rosout düğümünün bu bilgi ışığında Ubuntu üzerinde inceleyebilirsiniz.


Düğüm isimlendirmeye dikkat ettiğimizde C dili değişken isimlendirme standardı kullanılmakta olduğunu görmekteyiz (küçük harfle başla, küçük harf kullan, kelimeler arası alt çizgi kullan) .
Mesaj tipi isimlendirmesinde ise [C dili] / [PascalType] olduğunu görmekteyiz.

(/) işareti ise bize düğümün global isim uzayı (namespace) altında olduğunu gösterir. Isim uzayı, tıpkı diğer karmaşık ve birden fazla modülün iç içe kullanıldığı ve tekilliğin sağlanması gereken sistemlerde olduğu gibi ROS platformunda da önemli bir yer tutar. Bunu dosya sistemindeki dizin yapısına benzetebiliriz. /home/user1/readme.txt  ile /home/user2/readme.txt farklı dosyalardır. Isim çakışmasının önüne isim uzayı kullanılarak geçilir.

Düğüm hakkında detaylı bilgi almak için aşağıdaki komutu çalıştıralım.

rosnode info /matlab_global_node_94215

Cevap olarak gelen bilgi aşağıdadır.

Node: [/matlab_global_node_94215]
URI: [http://192.168.1.2:4050/]
 
Publications (1 Active Topics): 
 * /rosout
 
Subscriptions (0 Active Topics): 
 
Services (0 Active): 
Publications kısmında  düğümün yayınladığı topic /rosout olarak gözükmektedir. Matlab Global düğümümüz sanki Ubuntu daki /rosout düğümü gibi işlev görmektedir (Ubuntu'da roscore ile master çalışmaya başladığında oluşan loglama düğümü).

Topik hakkında detay bilgi almak için aşağıdaki komutu çalıştıralım.

rostopic info /rosout
Cevap olarak gelen bilgi aşağıdadır.

Type: rosgraph_msgs/Log
 
Publishers:
* /matlab_global_node_94215 (http://192.168.1.2:4050/)
 
Subscribers:

Topiğin mesaj tipi rosgraph_msgs/Log olarak verilmiş.
Topiği yayınlayan düğüm /matlab_global_node_94215  olarak verilmiş.
Topiğin ürettiği mesaja abone olan herhangi bir düğüm gözükmemekte.

Şimdide rosgraph_msg/Log mesaj tipi hakkında bilgi alalım.

rosmsg show rosgraph_msgs/Log

Cevap olarak gelen bilgi aşağıdadır. (% işareti Matlab için açıklama satırıdır. )

%%
%% Severity Level constants
%%
int8 DEBUG=1  %debug Level
int8 INFO=2   %general Level
int8 WARN=4   %warning Level
int8 ERROR=8  %error Level
int8 FATAL=16 %fatal/critical Level
%%
%% Fields
%%
std_msgs/Header Header
int8 Level
char Name     % Name of the node
char Msg      % message 
char File     % File the message came from
char Function % Function the message came from
uint32 Line   % Line the message came from
char[] Topics % topic names that the node publishes

Bu aşamaya kadar ROS üzerinde sıklıkla kullanılan komutları konu ile ilişkilendirerek anlattım.
Komutları Ubuntu üzerinde kullanabilir, parametreli kullanımlarini -h  yardım dosyaları ile öğrenebilirsiniz. Örnek : rosmsg -h

Matlab'de ise F1 ile yardım dosyaları açılacaktır.

Bundan sonraki yazımızda Ubuntu makinasini da devreye alip ağ ortamında haberleşme kısmına geçeceğiz.

1 Ocak 2017 Pazar

ROS (Robot Operating System ) nedir, nasıl kurulur ?

Robot İşletim Sistemi (ROS), robotu oluşturan parçaların birbirleriyle ve dış dünya ile etkileşimini basitleştirmeyi amaçlayan bir yazılım platformudur. Temel amacı kullanıcı, işletim sistemi (Ubuntu) ve ekipmanlar (sensör, kamera, joystick, vb) ile etkileşimi sağlamaktır. Bir işletim sisteminde donanım ile ilgili nasıl bir soyutlama var ise ROS içinde bu soyutlamadan bahsedebiliriz. Robotun tüm donanımsal detaylarına girmeden kontrol imkanı sunar. Örneğin bir robot kolunu hareket ettirmek için, robot kolunun donanımsal tasarımını yapanların phyton, c++ da hazırlamış olduğu kütüphaneler içindeki komutları kullanırsınız. ROS dağıtık mimari yapısını destekler. Robotun kamera görüntülerinden haritayi çıkartan ve gideceği yolu oluşturan yazılım ve donanım başka bir makinada iken, robotun tekerleğini hareket ettiren modülü başka bir makinada olabilir.

ROS sürümleri (ROS paketlerinin versiyonlanması.) kar amacı gütmeyen Open Source Robotics Foundation (OSRF) kontrolünde yayınlanır. ROS hakkında detaylı bilgi edinebileceğiniz sitesi organizasyon linkinde sunulmuştur. Sürümlere ait detaylı bilgiyi dağıtımlar linkinden bulabilirsiniz.

Ubuntu (Xenial) üzerine ilk kurulumu son sürüm olan (tavsiye edilen) Kinetic sürümü ile gerçekleştirdim. Lakin ROS un Indigo sürümünde kurulum paketi ile birlikte gelen Gazebo robot simulasyon programı desteği bu yazıyı yazarken Kinetic için yoktu ve bende öğrenme aşamasında olduğum için, iş gazebo simülatör kismina gelince kaldım. Bunun üzerine ROS Indigo sürümünü, Ubuntu 14.4 Trusty üzerine sil baştan kurmaya karar verdim.

Microsoft ortamında yazılım geliştirmeye aşina biri olup linux konusunda temel seviyede bilgi sahibi olmama rağmen kurulumu sitesindeki adımları izleyerek Kinetic için kolayca, Indigo için biraz uğraşarak gerçekleştirebildim. Sebebi ise  gazebo' ya ait modellere normal kurulumla erişemedim. Tüm modelleri ayrıca indirmek zorunda kaldım. Kinetic'den Indigo dağıtımına Gazebo simülatörünü kullanayım diye yola çıkmış ve böyle bir espri ile karşılaşmış olduk.

Sitedeki linklerin ROS sürümlerine göre bir yapılanması mevcut.

http://wiki.ros.org/<sürüm adı>/Installation/Ubuntu adresindeki <sürüm adı> değişkenine Kinetic yazarsaniz Kinetic sürümüne ait kurulum sayfalarına gidersiniz. Biz Indigo kurulumuna gideceğiz.

Şimdi ROS sitesinde Indigo kurulum talimatlarını aşağıdaki gibi terminal üzerinde sırasıyla işletelim.

ROS paketlerini alabilmek için Ubuntu program paketleri listesine (sources.list) packages.ros.org sitesini ekleyelim. Aşağıdaki tek bir komut satiridir.

sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
listeyi güncellemek için ROS deposuna ait anahtar bilgilerini girelim.

sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116

ROS kurulumuna geçmeden paketlerimizi güncelleyelim

sudo apt-get update

Şimdi ROS  ve yanında çeşitli yardımcı araçlar (rviz, rq, gazebo 2, turtlesim simulator, robot kütüphaneleri) olan paket kurulumuna geçelim. Ek bilgi olarak, ROS sürümlerinde gördüğümüz kaplumbağa (Ilk sürüm olan ROS Box Turtle'in her sürümde evrimleşmiş hali) turtlesim simulator çalıştırıldığında karşınıza çıkar.

sudo apt-get install ros-indigo-desktop-full

ROS platformunu çalıştırmak için gerekli olan ROS harici işletim sistemi bağımlılıklarını yüklemek  için aşağıdaki komutlari çalıştırıyoruz.

sudo rosdep init
rosdep update

ROS platformuna ait komutların tanınması ve çalıştırılması için ROS'a ait dosyalarin yollarının bilinmesi  gerekir. Her bir terminal oturumunda (terminal ekrani açtığınızda) bunun otomatik yapılabilmesi için aşağıdaki komutları çalıştırıyoruz. (terminalde bash kabuğu kullanıyorsak.)

echo "source /opt/ros/indigo/setup.bash" >> ~/.bashrc
source ~/.bashrc

rosintall komutunu ros paketlerini indirmek için kullanırsınız. Bu komutu kullanabilmek için sisteme kurmaniz gerekmektedir. Bunuda aşağıdaki komutla yaparız.

sudo apt-get install python-rosinstall

kurulumu bu şekilde tamaladıktan sonra aşagıdaki komutla ROS sistem değişkenlerini kontrol edebilirsiniz.

 export| grep ROS

declare -x ROSLISP_PACKAGE_DIRECTORIES=""

declare -x ROS_DISTRO="indigo"

declare -x ROS_ETC_DIR="/opt/ros/indigo/etc/ros"

declare -x ROS_MASTER_URI="http://localhost:11311"

declare -x ROS_PACKAGE_PATH="/opt/ros/indigo/share:/opt/ros/indigo/stacks"

declare -x ROS_ROOT="/opt/ros/indigo/share/ros"


Eğer değişkenleri yukarıdaki gibi göremedi iseniz setup.bash dosyasini tekrar source etmeyi denemelisiniz. Indigo sürümünü kurduğumuz için ROS_DISTRO="indigo" olduğunu gözlemleyiniz.

ROS Indigo kurulumumuzu böylelikle tamamladık. Şu aşamada terminal ekranını açıp ROS komutları girebilirsiniz.

ROS üzerinde yazılım geliştirecekseniz (ROS paketleri oluşturmak veya var olan ROS paketleri değiştirip derlemek)  catkin çalışma ortamını kurmanız gerekmektedir.

Açık kaynaklı yazılım geliştirme kalıpları, yeni problemleri çözmek için mevcut çözümleri tekrar kullanma kolaylığı nedeniyle güçlüdür. ROS'da bu mantığı kullanır. Birçok robotik uygulaması, diğer robot uygulamalarda karşılaşılan problemleri içerir veya çok benzer alt sistemlere sahiptir. Çözüm için diğer paketleri kullanmak beraberinde örgütsel zorlukları getirir. Her bir paketin kendine ait derleme şekli, bağımlı oldukları kütüphaneler bulunur.  catkin bu zorlukların üstesinden gelmek için oluşturulmuş bir dizin yapısıdır. Kurulumu için aşağıdaki komut satırlarını çalıştıralım.

$ mkdir -p ~/catkin_ws/src
$ cd ~/catkin_ws/src
$ catkin_init_workspace

catkin_ws dizinine baktığınızda /src dizininin oluştuğunu ve içinde CMakelist.txt dosyası olduğunu göreceksiniz. catkin_make komutunu aşağıdaki gibi çalıştırdığınızda

$ cd ~/catkin_ws/
$ catkin_make
/build
/devel dizinlerinin ve //devel dizininin içinde ise setup.*sh dosyalarını göreceksiniz. Bunlardan setup.bash dosyasini source komutu ile çalıştirarak ROS sistemine dahil ediyoruz.

$ source ~/catkin_ws/devel/setup.bash
$ echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc
İşlemi kontrol için aşağıdaki komutu çalıştırarak catkin dizininin en başa eklendiğini gözlemleyiniz.

$ echo $ROS_PACKAGE_PATH

Böylece ROS kurulumuna catkin kurulumunu da ekleyerek kurulum safhasini tamamlamış olduk.

Terminal penceresini açarak ilk komutumuz olan roscore komutunu girelim. Bu komut ROS sisteminin çalışması için gereken modül ve programların yüklenmesini sağlar. Bunlar sırası ile ROS Master, ROS Parameter service, rosout loglama modülleridir.

$ roscore

ROS platformunda aynı veya farkli bilgisayarlarda çalişan her bir kod modülü Node (düğüm) olarak geçer. Her bir düğüm robotunuzla ilgili özelleşmiş bir iş yapar. Bir düğüm oluşturmanın iki yolu vardır; birincisi terminal üzerinden ikincisi ise phyton veya c++ kodu ile düğüme ilişkin kodlamayla olur. Düğümler birbirleriyle mesajlaşabilir. Mesajlaşma ancak düğümlerin kendilerini ROS platformuna kaydettirmeleri ile mümkündür. Düğümlerin kaydedildiği ve izlendiği modül ROS Master olarak geçer. Düğümler arası haberleşme TCP/IP veya TCPROS kullanılarak yapılır. Yukarıdaki roscore komutu ile ROS Master'i devreye almış oldunuz.  Terminal ekraninda komut cevabını incelediğinizde aşağıdaki URI, master'in lokasyonunu belirtir. <makina_ismi_veya_ip> değişkeni bende osboxes gozukuyor. Bu sanal makinamin ismi. Sizde de kendi makinanizin ismi gozukecektir.

ROS_MASTER_URI=http://<makina_ismi_veya_ip>:11311/
Biraz önce açtığınız ve roscore komutunu çalıştırdığınız terminali kapatırsanız ROS sistemide kapanır. Terminali kapatmadan ctrl + c ile de ros mater modulunu kapatabilirsiniz.

Yukaridaki URI bilgisine bu haliyle müdahale etmez isek network ortamında birden fazla makinaya dağilmiş bir yapıda düğümlerin master'i bulması ve master'in düğümleri izlemesinde sıkıntı yaşayabilirsiniz. Matlab üzerinden (robotik paketi içerir ve ros platformu desteği verir.) Ubuntu kurulu makinaya erişirken  (ros platformu kurulu makinam) bu sıkıntıyı yaşadım. Çözüm olarak düğümlerin birbirlerini URI üzerinden çözmesini kolaylaştırmak için ROS_MASTER_URI ve ROS_IP platform değişkenlerini uygun ip değerleri ile her bir makina da set etmeniz gerekir.

ROS Master modülünü kapatarak aşağıdaki komutlarla önce değişkenlerin varsayılan değerlerine bakmak istiyorum.

ROS_MASTER_URI : roscore çalıştırılan makinanin ip adresini barindirmali. Ros platformunda birden fazla düğüm olabilir ama tek bir master vardir. Bizim örneğimizde master ve düğümlerin tek bir makinada olduğuna dikkat edelim.

echo ROS_MASTER_URI
komut cevabı olarak  herhangi bir değer göremedim. Bu makinada yani  192.168.1.7 nolu makinada ros master modülünün çalışmasını istediğimden dolayı aşağıdaki gibi komutu çalıştırıyorum.

echo export ROS_MASTER_URI=http://192.168.1.7:11311
yukarıdaki işlemi terminali açıp roscore çalıştırmadan önce her seferinde yapmanız gerekir. Terminal her açıldığında bu bilgileri kendisi alsın istiyorsanız bunu bash kabuğuna yazmalısınız.

echo export ROS_MASTER_URI=http://192.168.1.7:11311 >> ~/.bashrc

ROS_IP : Bulunduğunuz makinanın ip adresidir. Düğümleriniz bu bilgiyi kullanarak kendilerini master 'a kaydederler.

echo ROS_IP
komut cevabı olarak  herhangi bir değer göremedim. Bu makinada yani 192.168.1.7 de olduğum için komutu aşağıdaki gibi yazarak çalıştırıyorum.

echo export ROS_IP=192.168.1.7 >> ~/.bashrc

Bu aşamadan sonra roscore komutuyla ROS master modulunu tekrar çalıştırıp yeni master URI bilgisini gözlemleyiniz.

Aşağıdaki komutla .bashrc dosyası içinde en altta export işlemlerimiz ve source işlemlerimizin nasıl dosyaya eklendiğini görebilir ve IP, URI  değişikliklerini artık buradan da yapabilirsiniz.

gedit ~/.bashrc

Eğer sanal makinada ubuntu kurmuşşsaniz sanal makinanizda network bağlantı yöntemini bridge olarak düzenlemeniz gerekir.  Ayrıca güvenlik duvarı kullanıyorsanız (firewall) ilgili portlara erişim izni vermeniz gerekmektedir.

Böylelikle ROS nedir ve kurulumu nasıl yapılır sorularına cevap vermiş olduk. Bir sonraki yazımızda temel ros komutlarını kullanarak iki makinalı bir sistemde matlab üzerinden ROS 'a erişmek ve haberleşmeyi göstermek adına bir örnek yapacağız.