コンテンツへスキップ

以前、Raspberry Pi 3 B + に Ubuntu MATE(16.04) を入れ、ROSでhelloworldしました。 基本的な機能を確認します。
catkin_makeは重いかも。ラズパイちゃんが固まるので注意。

目次

  • ROSとは
  • Topic
  • Topicのサンプルコード
  • 動作
  • 雑記
  • 参考

ROSとは

ロボット開発を促進するミドルウェアです。ROSではすべてモジュールとモジュール間通信の形式で構成されています。誰かが作ったプログラムを、詳細を知らないままに使用できます。1つ1つのモジュールをノードと呼びます。

ROSではすべての処理が「ノード(Node)とノードがメッセージ(Message)をやりとりする」という構造になっています。それらの集合がパッケージ(Package)と呼ばれます。ノードとノードの通信を行うのがマスタ(Master)で、roscoreコマンドで起動します。

ビルドはすべてパッケージフォルダ内のCMakeLists.txtに記述され、catkinで行われます。(Hydroバージョン以降)

  • Topic
  • Service
  • Parameter

この投稿では参考の本のtopicついてさわりのみ扱います。

topic

濃い青が実際に作るプログラム、薄い青がプログラムによって作られたもの、矢印がデータの流れを表しています。

Topic はノード間でやり取りされるデータの入れ物(話題)です。データを送る動作をpublish、データを受け取る動作をSubscribeといいます。

Publisherはノードの起動時にTopic名をMasterに登録し、Messageで定めた形式で他のノードに送信します。 Subscriverは指定されたTopicを発振しているPublisherを問い合わせます。

名前と型などが設定されていて、Topicの名前を指定すればどのノードからでもデータを読み取ることができます。また一度接続されればメッセージ送受信が継続されます (非同期通信)ので、高頻度の通信を行うセンサ信号の送受信などに使用されます。

topicのサンプルコード

$cw
$catkin_create_pkg tutorial_topic roscpp std_msgs

まず上のようにパッケージを作成します。catkin_create_pkg パッケージ名 依存パッケージ のように書きます。

publisher.cpp

#include <ros/ros.h>
#include <std_msgs/Int32.h>

int main(int argc, char **argv)
{
  ros::init(argc, argv, "publisher");
  ros::NodeHandle nh;
  ros::Publisher pub = nh.advertise<std_msgs::Int32>("number", 10);
  
  ros::Rate loop_rate(1);
  std_msgs::Int32 cnt;
  cnt.data = 0;
  
  while(ros::ok())
  {
    ROS_INFO("Count : %d", cnt.data);
    pub.publish(cnt);
    cnt.data++;
    loop_rate.sleep();
  }
  return 0;
}
  • ros::init(argc, argv, ノード名)はノードの初期化を行う関数です。
  • ros::NodeHandle はROSシステムにアクセスし、他のノードと通信を行うクラスです。
  • ros::NodeHandle::.advertise(topicの名前,バッファ容量)でtopicの登録を行っています。
  • loop_rate(1)で1Hzのウェイトをかけてループしています。
  • std_msgs::Int32は32bit符号付整数のラッパークラスです。ラッパークラスとは、別のプログラム(群)を包んで隠蔽し、使いやすくしたクラスです。今はデータはcnt.dataに格納されています。
  • ros::ok()は基本的にtrue、CNTR+Cで停止したときにfalseを返します。

subscriber.cpp

#include <ros/ros.h>
#include <std_msgs/Int32.h>

void onNumberSubscribed(const std_msgs::Int32 &msg)
{
  ROS_INFO("I heard: [%d]", msg.data);
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "subscriber");
  ros::NodeHandle nh;
  ros::Subscriber sub = nh.subscribe("number", 10, onNumberSubscribed);
  ros::spin();
  return 0;
}
  • ros::NodeHandle::subscribe(topic名, バッファ容量, コールバック関数名)でSubscribeするTopicを設定しています。今は"number"というTopicを受信するたびにonNumberSubscribedが呼び出されます。
  • ros::spin()は無限ループで、CNTR+Cで中断されると、以降の処理は行われません。

CMakeLists.txt

cmake_minimum_required(VERSION 2.8.3)
project(tutorial_topic)

find_package(catkin REQUIRED COMPONENTS
  roscpp
  std_msgs
)

catkin_package()
include_directories(${catkin_INCLUDE_DIRS})

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

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

CMakeLists.txtはファイルを作成する指示書みたいなものです。自動で作成されるものを編集します。

  • cmake_minimum_requiredにはバージョン、prjectにはproject名、find_packageには依存パッケージが入っていると思います。
  • catkin_packageはcatkinビルドのオプションを指定します。
  • include_directories()はインクルードフォルダを指定します。今は各パッケージのincludeフォルダのヘッダーファイルを指定しています。

add_executable(実行ファイル名 src/実行ファイル名.cpp)以下をそれぞれ書き足します。add_executableはビルド後に実行するファイルを、target_link_librariesには生成時に必要なファイルを指定します。以下で ビルドします。

$cd ~/catkin_ws
$caikin_make -DCATKIN_WHITELIST_PACKAGES="パッケージ名"
$roscore
$rosrun tutorial_topic subscriber
$rosrun tutorial_topic publisher

指定したパッケージのみビルドし、それぞれ実行します。rosrunなどは起動したままにするので、端末は複数開いてください。

topicの動作

出力はこんな感じ。下のコマンドでノードとデータの移動をグラフとして表示できます。

$rosrun rqt_graph rqt_graph

publisherノードとsubscriberノードがnumberというtopicを受け渡ししているのがわかります。

topicはプリミティブ型は使えないので、ラッパーされたメッセージ型を使わなければなりません。int型の代わりにstd_msgsパッケージのInt32というメッセージ型を使っています。

その他

参考にした本には以下についてのサンプルコードが載っています。

  • 独自型の定義
  • spinOnce
  • AsyncSpinner
  • 同期

ROSでは独自型を定義する事ができます。ただし、ROSの「他の人のコードも利用できる」という性質上、独自型を作成するのは最低限にすべきでしょう。 また、上のサンプルコードにはspin関数を使っているので複数のTopicをSubscribeする事はできません。ノンブロッキングなspinOnceなどを使う必要があります。

また、Lidarの情報を扱う際には同期が活躍します。

雑記

モーターとセンサを取り付けたい。こいつ単体で何かできるようにしてやりたい。

参考

私はC++でROSのコードを書いているんですが、補完機能が使えないとdebugが大変。以前ROSを入れたラズパイに入れようとしたもののROSが入ってないと補完出来ないため、ひとまず仮想マシン上でやることにしました。

目次

  • 目的とROSに関して
  • Ubuntu
  • VMware
  • ROSのインストール
  • VScode
  • 雑記
  • 参考

目的とROSに関して

ROSはロボットソフトウェアプラットホームで、ロボットのプログラムをやる場合にメリットがたくさん。ROSを利用するには別にOSを用意する必要があり、一般的にUbuntuやLinuxが利用されています。

=>過去記事[Raspberry Pi 3 B+ + Ubuntu MATE + ROSのセットアップ]

私はコードはwindows上のVScodeで書いていますが、これではTabで補完できないのですべてのコード自分で書かなくてはならず、タイプミスがかなり多くて困っています。そこでエディタをパワーアップしたいんですが、補完機能を使用するにはROSが必要であり、windowsと相性が悪いとよく言われます。

この記事の目的はROSのコードを補完してくれるエディタを用意することです。

windows10, intel CORE i5 2.3GHz 2.40GHz 実装RAM 4.00GBです。VScodeをインストールして以降、デュアルディスプレイで作業すると重いかも知れませんのでご注意ください。

Ubuntu

Ubuntu is 何 =>
過去記事[Raspberry Pi 3 B+ + Ubuntu MATE + ROSのセットアップ]

Ubuntu は、Linuxベースで無償で提供されており日本人コミュニティのサポートが厚いOSです。 本来はラズパイに合わせてubuntu 16シリーズを入れるべきでしたが、間違って ubuntu 18.04を入れてしまいました。 参考のQiitaによると、ROSのバージョンはubuntuのバージョンが対応していないと動かないらしいので、注意してください。

最新の長期保証版はUbuntu 18.04で、過去の記事で入れたUbuntu MATEは16.04という扱いです。 以下からIOSファイルをダウンロードしてください。

ROSUbuntu
Kinetic16.04
Melodic18.04

VMware

仮想環境を構築します。仮想技術とは、ソフトウェアを活用してハードウェアを再現することで、限りある計算資源がジ歳以上にあるように見せる技術です。

要するに、本当はない架空のPCを用意するようなものです。

VMwareさんの「VMware Workstation Player 15」を使用します。ダウンロード/無償製品のダウンロードからVMware Workstation Playerのfor windowsをインストールします。

Windows または Linux PC 上での仮想マシンの実行に最適な製品です。管理対象の企業デスクトップの配信、教育機関での学習やトレーニングなどの用途に使用できます。

VMware Workstation Player の試用 -VMware より引用

インストーラを起動し、さっきダウンロードしたubuntuをVMにインストールをして、今回私はメモリが残り少ないのでFドライブを指定しました。ここまで10分くらい。

この後結構かかります。途中キーボードを聞かれましたが、私はgeneric101でした。しばらくすると終了してホーム画面がでます。

この時、横でメモ用にwindowsのVScodeを開いていたらだいぶ遅かったです。仮想環境のコア数を設定します。VMware上でPlayer(P)/設定/フリプロセッサを4にすます。動きが多少スムーズになりました。

ROSのインストール

ROS merodicを入れました。Ubuntu18をVMにインストールしてしまったが故の過ち。以下は入れるバージョンによってmerodicの部分を適宜kineticに変換してください。 下記コードを実行します。詳細は過去記事へ。

$sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
$sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116
$sudo apt update
$sudo apt install ros-melodic-desktop-full 
$sudo rosdep init
$rosdep update
$echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc //毎回sourceが読み込まれるように設定
$source ~/.bashrc
$roscore //テスト用に実行

このsourceでは、ROSをインストールしたディレクトリに自動で環境変数を登録してくれるスクリプトファイルを読み込んでいます。

以下のように表示されればOK。

作業ファイルの初期化をします。ROSでは専用ビルドシステムcatkinをcatkin_ws上でおこないます。 catkin_wsを作成、初期化

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

ROSでは今後catkin_ws上で作業することになります。ウィキペディアによれば「catkin」という名前は開発したウィローガレージ社のウィロー(Willow = ヤナギ)の木にみられる尾状花序に由来するそうです。

VScode

VScodeを入れます。ページからダウンロードして使用します。

Download Visual Studio Code

Ubuntu上でDebian、Ubuntu用の.debファイルをダウンロードしてインストールします。コマンドからやる場合は以下を入力します。

$cd ~/ダウンロード
$sudo dpkg -i code_*.deb

インストールができたら拡張機能をいじって行きます。まずは下記コマンドまたはVScodeアイコンをクリックして開きます。

$code

左上の縦に並んだアイコンのうち一番下の四角マーク「拡張機能」を選択して、検索バーを使ってインストールしたい拡張機能を入力していきます 。インストールしたのは「Japanese Language Pack for Visual Studio Code」「C/C++」「Python」「ROS」「CMake Tools」「CMake」です。 インストールしたらVScodeを再起動して、ファイル/フォルダーをワークスペースに追加 からcatkin_wsを追加します。

するとcatkin_ws/.vscodeディレクトリに設定ファイル c_cpp_properties が作成されているので、これを編集します。

c_cpp_properties.jsonの変更点

"includePath": [
        "/opt/ros/melodic/include",
        "$HOME/catkin_ws/devel/include",//ここ
        "/usr/include"
      ],

以降はこれで作成したコードを使用します。

ここでROSの設定に戻って、自動でソースを読み込むようにしつつ、コマンドを加えておきます。

$code ~/.bashrc 
# Set ROS melodic
source /opt/ros/melodic/setup.bash //ここはすでに書き込んであります。
source ~/catkin_ws/devel/setup.bash

# Set alias command
alias cw='cd ~/catkin_ws'
alias cs='cd ~/catkin_ws/src'
alias cm='cd ~/catkin_ws && catkin_make'
$source ~/.bashrc //読み込み

ここで試しに下記を実行してみます。

$cs

~/catkin_ws/srcに移動していたらOKです。 次回起動するときはVMwareで△マークでパワーオンします。

雑記

kineticのが場合はmelodicの部分を書きかえばOKのはずです。しばらく使ってみて、ROSのバージョンの違いでどんな違いが出るかわかったら追記しようと思います。 少なくとも今週やっていた参考本の Scamperによる ROS & Raspberry Pi製作入門 の「topic」「service」「param」の章では記法に変化は見つかりませんでした。

参考