ROSによるプログラミング(C++)

目的

ROSにおけるワークスペース及びファイルシステムの概念を理解します.また,演習によりワークスペース及びパッケージの作成方法,ROSにおけるC++によるプログラミング方法を習得します.本内容は1週(1コマ)を想定しています.

ワークスペースの作成及びビルド

ワークスペース及びパッケージの作成方法,ROSによるプログラミング方法を学びます.まず,ワークスペースを作成しましょう.ここでは,practice_wsというワークスペースを作成します.まず,ワークスペースとなるディレクトリを作成後,その一つ下の階層にsrcというディレクトリを作成します.最後にcatkin_init_workspaceというコマンドによりワークスペースを作成します.

$ mkdir practice_ws
$ cd practice_ws
$ mkdir src
$ cd src
$ pwd
/home/yuu/practice_ws/src
$ catkin_init_workspace

実行するとディレクトリにCMakeLists.txtというファイルが作成されます.このファイルは,catkin_makeする際に必要なファイルです.catkinとは,ROSにおけるビルドシステムを指します.ビルドシステムにより,作成したプログラムから実行可能な形式に変換します.CMakeと似ていますが,ROSに特化することで汎用性が高いビルドシステムとなっています.実際にビルドしてみましょう.ビルドするためには,ワークスペースの最上位のディレクトリに移動し,catkin_makeを実行します.

$ cd ../
$ pwd
/home/yuu/practice_ws
$ catkin_make

実行すると下記のように出力されます.

yuu@VB:practice_ws$ catkin_make
Base path: /home/yuu/practice_ws
Source space: /home/yuu/practice_ws/src
Build space: /home/yuu/practice_ws/build
Devel space: /home/yuu/practice_ws/devel
Install space: /home/yuu/practice_ws/install
####
#### Running command: "cmake /home/yuu/practice_ws/src -DCATKIN_DEVEL_PREFIX=/home/yuu/practice_ws/devel -DCMAKE_INSTALL_PREFIX=/home/yuu/practice_ws/install" in "/home/yuu/practice_ws/build"
####
-- The C compiler identification is GNU
-- The CXX compiler identification is GNU
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Using CATKIN_DEVEL_PREFIX: /home/yuu/practice_ws/devel
-- Using CMAKE_PREFIX_PATH: /home/yuu/turtlesim_practice/devel;/opt/ros/indigo
-- This workspace overlays: /home/yuu/turtlesim_practice/devel;/opt/ros/indigo
-- Found PythonInterp: /usr/bin/python (found version "2.7.3")
-- Using PYTHON_EXECUTABLE: /usr/bin/python
-- Python version: 2.7
-- Using Debian Python package layout
-- Using CATKIN_ENABLE_TESTING: ON
-- Call enable_testing()
-- Using CATKIN_TEST_RESULTS_DIR: /home/yuu/practice_ws/build/test_results
-- Looking for include files CMAKE_HAVE_PTHREAD_H
-- Looking for include files CMAKE_HAVE_PTHREAD_H - found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Found gtest sources under '/usr/src/gtest': gtests will be built
-- catkin 0.5.90
-- BUILD_SHARED_LIBS is on
-- Configuring done
-- Generating done
-- Build files have been written to: /home/yuu/practice_ws/build
####
#### Running command: "make -j1 -l1" in "/home/yuu/practice_ws/build"
####

ROSのバージョンが同じであれば,アカウント名以外は全く同じ内容が出力されます.正常にビルドできた人は,lsコマンドを使用してpractice_wsの中に変化がないか確認しましょう.catkin_makeにてdevel及びbuildという名前のディレクトリが作成されているはずです.これらのディレクトリの中に実行ファイルやライブラリが保存されます.作成されるファイルの一つにsetup.bashがあります.このファイルは,作成したワークスペース及びパッケージの情報が記述されています.ROSに関連する環境変数にsetup.bashを用いてワークスペースのパスを追加します.

$ source devel/setup.bash

上記は,新しくワークスペース内にパッケージやノードを作成した際に実行する必要があります.また,それ以外にも新しい端末(新しいタブ)を開いた際にも上記を実行する必要があるので,覚えておきましょう.(作成したノードを実行しようとしても見つからない場合には,環境変数の設定ができていない場合が多いです.注意してください.)環境変数にパスが追加されているか確認します.下記を実行しましょう.

$ echo $ROS_PACKAGE_PATH

下記のように作成したワークスペースのsrcのパスが出力されていれば問題ありません.

/home/yuu/practice_ws/src:/opt/ros/indigo/share:/opt/ros/indigo/stacks
パッケージの作成

次にパッケージを作成しましょう.パッケージの作成にはcatkin_create_pkgを実行します.

$ catkin_create_pkg [パッケージ名] [依存パッケージ1 依存パッケージ2 ...]

今回は依存するパッケージはroscppパッケージのみです.roscppは,C++でプログラミングする際に必要なパッケージです.下記のように実行してください.

$ cd src
$ pwd
/home/yuu/practice_ws/src
$ catkin_create_pkg practice roscpp

上記を実行することにより,幾つかのファイルとディレクトリが作成されます.その中の一つであるpackage.xmlには,パッケージに関する情報が記述されます.中身を見てみましょう.

$ cd practice
$ pwd
/home/yuu/practice_ws/src/practice
$ vim package.xml

パッケージ作成者はパッケージの説明や作成者及び連絡先,ライセンス,依存関係について記述します.書き方の例もありますので,参考に書くと良いでしょう.今回はpackage.xmlの記述内容の詳細は省略します.

プログラミング

今回は画面にhello という言葉を出力するプログラムを作成します.なお,言語はC++を使用しますが,C++の講義は2年生後期ですので,C言語に近い書き方に留めます.C++を勉強後,本演習内容を復習すると良いと思います.

$ cd src
$ pwd
/home/yuu/practice_ws/src/practice/src
$ vim hello.cpp

それでは,hello.cppに下記を入力しましょう.

#include "ros/ros.h"

int main(int argc, char **argv){
    ros::init(argc, argv, "hello");
    ros::NodeHandle nh;
    ROS_INFO("hello");

    return 0;
}

1行ずつ説明します.

#include "ros/ros.h"

ROSで使用する多くのヘッダーファイルを読み込むことができます.どのようなヘッダーファイルを読み込むかについては,こちらのページを参照してください.

int main(int argc, char **argv){

main文の開始です.こちらはロボットプログラミングの講義で勉強しています.

ros::init(argc, argv, "hello");

ノードを初期化します.””の中にはノードの名前を記述してください.内容が前後してしまいますが,ノードについては次の演習で学びます.

ros::NodeHandle nh;

ノードハンドルを生成し,初期化します.詳しい説明はもう少し先の演習の時間に行います.

ROS_INFO("hello");

c言語では,printf関数により文字を画面に出力しました.ROSではROS_INFO関数を使用します.使用方法はprintf関数と非常に似ていて,””の間の文字を出力できます.それでは,ビルドしましょう.ビルドするためにCMakeLists.txtを編集する必要があります.

cd ../
$ pwd
/home/yuu/practice_ws/src/practice
$ vim CMakeLists.txt

CMakeLists.txtの一番最後に下記を追加してください.

add_executable(hello src/hello.cpp)
target_link_libraries(hello ${catkin_LIBRARIES})

それでは,catkin_makeでビルドしましょう.

$ cd ../../
$ pwd
/home/yuu/practice_ws
$ catkin_make

パッケージを作成したので,下記を実行する必要があります.

$ source devel/setup.bash

それでは,いよいよプログラムを実行します.実行する前に,新しい端末を開き下記のコマンドを実行してください.
roscoreについては次回の演習にて説明します.

$ roscore

元の端末に戻り,下記のようにコマンドを入力してください.プログラムの実行はrosrunを使用します.roscoreを終了させるときは,cntl+c(または、cntl+shift+c)を押してください.

yuu@VB:practice_ws$ rosrun practice hello
[ INFO] [1429117039.438860201]: hello

画面にhelloという文字が表示されましたか?ROSによるプログラムでは,ワークスペースの作成,パッケージの作成が必須となります.また,プログラミングを通して行った作業は,ROSにおけるロボットプログラミングで最低限必要作業となります.覚えることが多いので,もし忘れてしまったらこのwebページを参考に復習してください.次回以降も同様の作業が必要となりますので,繰り返し作業して一連の流れを覚えましょう.