Ros ve Fake Turtlebot 3 Node kullanılarak Uygulama Örneği

Bu dokümanda ROS Kinetic sürümü ve Fake Turtlebot 3 kullanılarak harita üzerinde işaretlenen yerlere göre turtlebot 3 robotunun en yakın olduğu nesnenin ismini ve uzaklığını ekrana mesaj yazdıran bir uygulama geliştirilecektir. Önceden Gazebo ile hazırlanmış bir haritadaki nesnelerin konumlarının kayıt altına alınması gerekmektedir. Turtlebot 3 robotu Şekil 1’deki gibi nesnelere yaklaştığında önceden tanımlanmış nesne ismi ekrana yazdırılacaktır. 

Şekil 1 Gazebo ile hazırlanmış bir haritada nesnelerin konumları

 

Bu dokümandaki adımları uygulamadan önce Ros Kinetic Kurulumu ve Turtlebot 3 Fake Node Uygulaması adımlarını tamamlamış olmanız gerekmektedir. 

Aşağıdaki komutu Linux terminal ekranında çalıştırarak bilgisayarınıza Ros Kinetic ve Turtlebot 3 Fake node uygulamalarının eksiksiz yüklendiğinden emin olabilirsiniz. Gerçek bir turtlebot 3 robotuna gerek kalmadan daha önce tanınmlanmış bir dünya üzerinde çalışmalarımız gerçekleştirilecektir. 

roslaunch turtlebot3_gazebo turtlebot3_world.launch

Eğer yukarıdaki komut çalıştırıldığında “environment variable ‘TURTLEBOT3_MODEL’ is not set” hatası alıyorsanız

Linux terminal penceresinde aşağıdaki komutu çalıştırmanız gerekmektedir. Fakat her yeni pencere açıldığında bu işlemin yapılması gerektiğinden eb kısayolu ile veya gedit .bashrc komutu ile .bashrc dosyasına aşağıdaki satırı eklemeniz tavsiye edilir. source .bashrc ile tekrar .bashrc komutlarını aktif hale getirebilirsiniz.

export TURTLEBOT3_MODEL=burger

Geliştirilecek uygulamanın çalışabilmesi için yukarıdaki komutun çalışır durumda kalması gerekmektedir.

 

Odometri Nedir ?

Odometri, zaman içindeki pozisyonu değiştirmek için hareket sensörlerinden gelen verilerin kullanılmasıdır. Bir başlangıç noktasına göre pozisyonlarını tahmin etmek için robotikte bazı bacaklı veya tekerlekli robotlar tarafından kullanılır. Bu yöntem, hız ölçümlerinin zamana göre konumlandırılması için zamana bağlı entegrasyona bağlı olarak hatalara duyarlıdır. Hızlı ve doğru veri toplama, cihaz kalibrasyonu ve işleme, çoğu durumda etkin bir şekilde kullanılması için gereklidir.

Ros Master çalıştığından emin olduktan sonra aşağıdaki komutlar Linux Terminal ekranından yazılarak topic listesi alınarak, odom topic ile ilgili bilgi alınabilir. 

rostopic list
rostopic info odom

 

Odom Topic nav_msgs/Odometry nav_msgs paketi içinde Odometry tipinde mesaj yayınladığı bilgisi görülmektedir. http://docs.ros.org/api/nav_msgs/html/msg/Odometry.html adresinde bu mesaj tipi ile ilgili bilgi bulunmaktadır. 

Ros mesajları ile Linux Terminal ekranından da yardım alınabilmektedir. Bunun için rosmsg komutu kullanılmalıdır.

 

 

 

 

Ön Kabul : kullanıcının ev dizininde catkin_ws/src klasörünün olması gerekmektedir. 

Geliştirilecek uygulama için catkin_ws çalışma uzayı (workspace) içinde yeni bir paket açılmalıdır. Paket ismi olarak robotun_konumu seçilmiştir. Bu paket için std_msgs , roscpp ve nav_msgs isimli bağımlılıklar gerekmektedir. Yeni  bir paket aşağıdaki komut Linux Terminal ekranından girilerek açılır. 

catkin_create_pkg robotun_konumu std_msgs roscpp nav_msgs

Açılan paket içerisinde robotun_konumu.cpp isimli dosyada ros c++ tutorial adresindeki başlangıç kodları ile başlanmalıdır.Fakat önce robotun konumunu odom topic’e abone olarak yayınlayan bir kod geliştirilecektir. Şekil 2’deki kod parçasını robotun_konumu.cpp isimli bir dosyaya kaydedip, derleyip çalıştırınız.

cd ~/catkin_ws/src/robotun_konumu/src
gedit robotun_konumu.cpp &

 

 

#include "ros/ros.h"
#include "nav_msgs/Odometry.h"


void OdomCallback(const nav_msgs::Odometry::ConstPtr& msg){
   double x=msg->pose.pose.position.x;
   double y=msg->pose.pose.position.y;
   ROS_INFO("x: %f, y: %f",x,y);

}

int main (int argc, char** argv){
	ros::init(argc,argv,"robotun_konumu");
	ros::NodeHandle nh;
	ros::Subscriber sub=nh.subscribe("odom",10,OdomCallback);
	ros::spin();
	return 0;
}

 

Şekil 2. Robotun konumunu ekrana yazdıran c++ kodu

 

Yazılan kodun derleme işleminin yapılabilmesi için CMakeLists.txt dosyasının içinde robotun_konumu.cpp dosyası ile ilgili değişikler yapılması gerekmektedir. src klasörü içindeki CMakeLists.txt dosyası bir metin düzenleyici ile açılır. Aşağıdaki satırların tamamını CMakeLists.txt dosyasının içeriği ile değiştirmeniz gerekmektedir.

cd ~/catkin_ws/src/robotun_konumu
gedit CMakeLists.txt &
cmake_minimum_required(VERSION 2.8.3)
project(robotun_konumu)

find_package(catkin REQUIRED COMPONENTS
  nav_msgs
  roscpp
  std_msgs
)

include_directories(
  ${catkin_INCLUDE_DIRS}
)

add_executable(${PROJECT_NAME} src/robotun_konumu.cpp)

set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME robotun_konumu PREFIX "")

add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

target_link_libraries(${PROJECT_NAME}
  ${catkin_LIBRARIES}
)

 

Derleme işlemi için cm kısayolu çalıştırılabilir veya aşağıdaki komut çalıştırılmalıdır.

cd ~/catkin_ws && catkin_make

Derleme hatası verilmediyse geliştirilen uygulamanın çalıştırılması için aşağıdaki komut Linux terminal penceresinden çalıştırılmalıdır. robotun_konumu isimli paketin içinden robotun_konumu isimli düğüm çalıştırılmış oldu. 

rosrun robotun_konumu robotun_konumu

 

Robotun konumu sürekli ekrana yazdırılacaktır. Robotun konumunu değiştirmek için teleop işlemi yapılabilir. Aşağıdaki komut ile teleop ekranından verilen komutlara göre turtlebot3 robotun konumu değiştirilebilmektedir.

roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch

 

 


Projenin 2. Aşaması

Ön Kabul: kullanıcının ev dizininde catkin_ws/src klasörünün olması gerekmektedir. 

Geliştirilecek uygulama için catkin_ws çalışma uzayı (workspace) içinde yeni bir paket açılmalıdır. Paket ismi olarak location_monitor seçilmiştir. Bu paket için std_msgs ve roscpp bağımlılıkları tanımlanmıştır. Fakat nav_msgs isimli bağımlılık ise sonradan elle eklenecektir. Yeni  bir paket aşağıdaki komut Linux Terminal ekranından girilerek açılır. 

catkin_create_pkg location_monitor std_msgs roscpp

Açılan paket içerisinde location_monitor.cpp isimli dosyada ros c++ tutorial adresindeki başlangıç kodları ile başlanmalıdır.Fakat önce robotun konumunu odom topic’e abone olarak yayınlayan bir kod geliştirilecektir. Şekil 2’deki kod parçasını robotun_konumu.cpp isimli bir dosyaya kaydedip, derleyip çalıştırınız.

#include <vector>
#include <string>
#include <math.h>

#include "ros/ros.h"
#include "nav_msgs/Odometry.h"
#include "location_monitor/LandmarkDistance.h"

using std::vector;
using std::string;
using location_monitor::LandmarkDistance;

class Landmark {
  public:
    Landmark(string name, double x, double y)
      : name(name), x(x), y(y) {}
    string name;
    double x;
    double y;
};

class LandmarkMonitor {
  public:
    LandmarkMonitor(): landmarks_() {
      InitLandmarks();
    }

    void odomCallback(const nav_msgs::Odometry::ConstPtr& msg) {
      double x = msg->pose.pose.position.x;
      double y = msg->pose.pose.position.y;
      LandmarkDistance ld = FindClosest(x, y);
      ROS_INFO("name: %s, distance: %f", ld.name.c_str(), ld.distance);
    }

  private:
    vector<Landmark> landmarks_;

    LandmarkDistance FindClosest(double x, double y) {
      LandmarkDistance result;
      result.distance = -1;
      
      for (size_t i = 0; i < landmarks_.size(); ++i) {
        const Landmark& landmark = landmarks_[i];
        double xd = landmark.x - x;
        double yd = landmark.y - y;
        double distance = sqrt(xd*xd + yd*yd);

        if (result.distance < 0 || distance < result.distance) {
          result.name = landmark.name;
          result.distance = distance;
        }
      }
      return result; 
    }

    void InitLandmarks() {
      landmarks_.push_back(Landmark("Engel1", 0.31, 0.31));
      landmarks_.push_back(Landmark("Engel2", 0.31, 0.31));
      landmarks_.push_back(Landmark("Engel3", 0.31, 0.31));
      landmarks_.push_back(Landmark("Engel4", 0.31, 0.31));
    }
};



int main(int argc, char **argv) {
  ros::init(argc, argv, "location_monitor");
  
  ros::NodeHandle n;
  
  LandmarkMonitor monitor;

  ros::Subscriber sub = n.subscribe("odom", 10, &LandmarkMonitor::odomCallback, &monitor);

  ros::spin();

  return 0;
}

 

Yazılan kodun derleme işleminin yapılabilmesi için CMakeLists.txt dosyasının içinde location_monitor.cpp dosyası ile ilgili değişikler yapılması gerekmektedir. src klasörü içindeki CMakeLists.txt dosyası bir metin düzenleyici ile açılır. Aşağıdaki satırların tamamını CMakeLists.txt dosyasının içeriği ile değiştirmeniz gerekmektedir.

cd catkin_ws/src/location_monitor/src
gedit CMakeLists.txt &

Açılan CMakeLists.txt dosyasında aşağıdaki resimde görüldüğü gibi değişiklikler yapılması gerekmektedir.

 

 

 

 

CMakeList.txt dosyasının en son hali yukarıda verilen resimlerde olduğu gibi olması gerekir. 

cmake_minimum_required(VERSION 2.8.3)
project(location_monitor)
find_package(catkin REQUIRED COMPONENTS
  roscpp
  std_msgs
  nav_msgs
  message_generation
)

## Generate messages in the 'msg' folder
 add_message_files(
   FILES
   LandmarkDistance.msg
 )

## Generate added messages and services with any dependencies listed here
generate_messages(
   DEPENDENCIES
   #std_msgs
)

include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)

## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
add_executable(${PROJECT_NAME}_node src/location_monitor.cpp)

## Add cmake target dependencies of the executable
## same as for the library above
add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

## Specify libraries to link a library or executable target against
target_link_libraries(location_monitor_node
   ${catkin_LIBRARIES}
)

 

package.xml dosyasında ise aşağıdaki değişikliklerin yapılması gerekmektedir : 

Projenin bulunduğu lokasyonda msg adlı bir klasör oluşturulur ve bunun altında LandmarkDistance.msg adında bir belge açılır ve Resim ’de görülen kodlar girildikten sonra uygulamaya devam edilir.

mkdir msg
cd msg
gedit LandmarkDistance.msg
string name # Name of the landmark
float64 distance # Distance to the landmark, in meters.

 

 

catkin_ws/devel/include/location_monitor içerisinde bulunan LandmarkDistance.h resim’de verildiği gibi düzenlenir.

cd catkin_ws/devel/include/location_monitor
gedit LandmarkDistance.h

cd ~/catkin_ws
catkin_make

 

rosrun location_monitor location_monitor_node 

Geliştirilen node problemsiz olarak çalışmalıdır. Bundan sonraki adım olarak .launch dosyasında değişiklik yaparak turtlebot3_world.world dosyası yerine kendi world dosyanızı çalıştırmanız gerekmektedir. Ayrıca c++ kodundaki engel isimlerini ve konumlarını da güncelleyerek kodu derleyip tekrar çalıştırmanız gerekecektir.