Ubuntu18.04用 ROS環境開発構築
この記事の目的
Ubuntu18.04 LTS の開発環境(ROS/Python/VS Codeなど)構築手順についてまとめる (Ubuntu16.04からのアップデート時の防備録)
1.Ubuntu18.04 LTSについて
Ubuntuは2年おきにLTS (Long Term Support)という長期サポート(5年)の安定版をリリースする。
これまで使っていた16.04は2021年にサポート切れとなるのと、Ubuntu 18.04を使用しているネット上の事例が増えてきたのでアップデートを試みる。
参考サイト
2. Ubuntu16.04からのアップデート手順
Ubuntu16.04をすでに利用している場合アップデート用のコマンドを利用すると設定やアプリを引き継いでUbuntuの更新を実施することができる。
アップデートのコマンドは下記のようになる。
sudo apt update sudo apt upgrade sudo apt autoremove # 不要パッケージの削除 sudo apt dist-upgrade # 保留パッケージの更新 sudo apt install update-manager-core # アップデートマネージャのインストール sudo do-release-upgrade # アップデートの実施 -d を付与すると開発中のバージョンへの更新も行う
ただし、aptコマンドの依存関係が正しく判定されず保留中のパッケージが残る場合は正しくインストールできない。 原因となっているパッケージを apt-get purge xxx などで削除してすべてのパッケージを最新として保留パッケージがない状態にする必要がある。
参考サイト
3. nvidia 用 GPUドライバの更新
Ubuntu 16.04ではnvidiaのグラフィックボードドライバを公式サイトから手動でダウンロードしてインストールする必要があった。 (これによりUbuntuのパッチ更新でログインループが発生するなどの問題も多く起きていた)
Ubuntu18.04ではnvidia用ドライバの更新を下記コマンドのみで実施できる。
sudo ubuntu-drivers autoinstall #nvidia GPU用ドライバの更新 (推奨ドライバが自動的にインストールされる) sudo reboot #再起動 nvidia-smi #ドライバがインストールされていること/どのバージョンがインストールされているかの確認
続けてCUDA/cuDNNをインストールする場合はnvidiaの公式サイトの案内(debファイルをローカルに落としてインストールする場合)下記のようにできる。(CUDA10.2の場合)
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin sudo mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600 wget http://developer.download.nvidia.com/compute/cuda/10.2/Prod/local_installers/cuda-repo-ubuntu1804-10-2-local-10.2.89-440.33.01_1.0-1_amd64.deb sudo dpkg -i cuda-repo-ubuntu1804-10-2-local-10.2.89-440.33.01_1.0-1_amd64.deb sudo apt-key add /var/cuda-repo-10-2-local-10.2.89-440.33.01/7fa2af80.pub sudo apt-get update sudo apt-get -y install cuda
インストール後に.bashrcにCUDAのインストールパスを追加しておく
export PATH="/usr/local/cuda/bin:$PATH" export LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH"
CUDNNについては公式サイトからダウンロードする (要ユーザー登録) その際、CUDAのバージョンにあった『cuDNN Library for Linux』をダウンロードし、展開後に下記コマンドでコピーする。
sudo cp -a cuda/lib64/* /usr/lib/cuda/lib64/ sudo cp -a cuda/include/* /usr/lib/cuda/include/
参考サイト taktak.jp
4. ROS melodicのインストール
Ubuntu 18.04ではUbuntu 16.04のROS kineticに変わりROS melodicをインストールする。
インストール手順はROS公式のインストール手順に従えば良い。
ただし、Ubuntu16.04からアップデートした場合ROS kineticの一部のパッケージが残っていることでmelodicで導入しようとするパッケージとの依存関係の干渉が発生してしまう可能性がある。
そのため下記コマンドを実施して古いROS関連パッケージを削除してからmelodicを導入したほうが良い。
sudo apt-get purge ros-* # ROS関連のaptパッケージの削除
5. その他の開発環境のインストール
Arduino IDE
Arduino公式サイトから"Linux 64 bits" を選択してダウンロードし、ファイルを展開後下記コマンドでインストール
sudo sh install.sh
Visual Studio Code と Pycharm
Ubuntu Softwareを起動し、Visual Studio Code/Pycharmで検索してインストール
ArduinoとPCの通信(シリアル通信)
この記事の目的
ArduinoとPC間でのシリアル通信についてまとめる
1.Arduinoのシリアル通信機能
ArduinoでPCと信号の送受信を行う場合、USBケーブルを使ったシリアル通信が最も便利な手法である。
Arduino標準のSerialライブラリを使い下記の関数で信号の受け渡しを行うことができる。
参考サイト https://garretlab.web.fc2.com/arduino_reference/language/functions/communication/serial/
API名 | リンク | 概要 |
---|---|---|
Serial.begin() | リンク | シリアル通信の初期化/bpsの指定 |
Serial.end() | リンク | シリアル通信の終了 |
Serial.setTimeout() | リンク | シリアル通信タイムアウト時間の指定 |
Serial.readStringUntil() | リンク | 指定した終端文字まで文字列を読み込む |
Serial.println() | リンク | 指定した文字列を出力する |
通信の速度はbpsで選択する。(300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200 など。送受信に必要な周期とデータ量を考慮して設定する。)
上記の表で挙げたのは送受信するデータは文字列であることを想定している。数値データは文字列に変換しカンマ区切りのデータで一括して送信することができる。下記にサンプルコードを示す。下記はデータの桁数をあらかじめ定めておき、終端が区切り文字";"で出力されるデータの送受信をすることを想定している。
/* serial_com_test.cpp */ /* header file */ #include "stdafx.h" #include "serial_com_test.h" /* static variable */ static int apl_cyc_count = 0; #define READ_BUFSIZE (7) //受信バッファサイズ x.x,x.x; を想定(終端文字は含まない) #define SEND_BUFSIZE (50) //送信用バッファサイズ #define SEND_DATA_SIZE (6) //整数桁3 小数点1 小数点以下2 を想定 //デバッグ用変数 static float deb_val1 = 0.0; static float deb_val2 = 0.0; static int keta = 0; //通信の初期化用関数 void com_init (void) { //Serial Communication initialization Serial.begin(115200); //boudrate 115200 Serial.setTimeout(50); //read timeout for serial communication Serial.print("Serial Communication Start!"); return; } //シリアル通信読み込み用関数 void com_read (void) { char buff_A[4]; char buff_B[4]; if(Serial.available()) //読み込むデータが存在する場合 { //終端データ";"までのすべてのデータを読み込む String str_buf = Serial.readStringUntil(';'); keta = str_buf.length(); if (str_buf.length() == READ_BUFSIZE ) { str_buf.toCharArray(buff_A,4); deb_val1 = atoi(buff_A); Serial.println(deb_val1); str_buf.toCharArray(buff_B,4,4); //先頭バイトの指定 deb_val2 = atof(buff_B); Serial.println(deb_val2); } Serial.println(buff_A); Serial.println(buff_B); } return; } //シリアル通信読み込み用関数 void com_send (void) { float deb_send_val1; float deb_send_val2; char test_str[SEND_BUFSIZE]={'\0'}; //配列を初期化用データで埋める char *ptr = test_str; deb_send_val1 = deb_val1 + 10.0; deb_send_val2 = deb_val2 - deb_val1; /*Send Acceralation information*/ dtostrf(deb_send_val1,SEND_DATA_SIZE,2,ptr); ptr = ptr + SEND_DATA_SIZE; *ptr=','; //区切り文字_token ptr = ptr + 1; dtostrf(deb_send_val2,SEND_DATA_SIZE,2,ptr); ptr = ptr + SEND_DATA_SIZE; *ptr=';'; //end_token Serial.println(test_str); return; } /*arduino 初期化処理*/ void setup() { /*Initialize Communication */ com_init(); } /*arduinoメインループ*/ void loop() { //50msec 周期実行 interval<5000>::run([]{ switch (apl_cyc_count) { case 0: com_read(); break; case 1: //アクチュエータの制御などを実施(仮) break; case 2: com_send();; break; default: //no action //Serial.println("Default"); break; } if (apl_cyc_count>=2) { apl_cyc_count = 0; } else { apl_cyc_count++; } }); }
上記スクリプトで送受信した結果はArduino IDE / Teraterm などで確認することができる。
ここで、 PCのPythonスクリプトとArduinoを通信させたい場合はライブラリ『Pyserial』を利用すると便利である。
Pyserialは下記コマンドでインストールすることができる。
pip install pyserial
Pyserialではポート名とボーレート、タイムアウト時間を指定して関数readlineでバッファ読み込み、writeでバッファ書き込みを行う。
読み込みについては、通信状態によって不安定になることがあるため区切り文字までの文字数を明示的にしておくほうが良い。
#!/usr/bin/env python # -*- coding: utf-8 -*- import serial import threading import time import re ########################################### ### Serial Socket Communication Class ### ########################################### class Class_Serial_Socket(threading.Thread): ################################### #Connection information ########## COM_PORT_NAME = 'COM4' #for Windows #COM_PORT_NAME = '/dev/ttyACM0' #for Ubuntu BAURATE = 115200 ############################################# ### Serial Communication Initialization ### ############################################# def __init__(self): #Initialize value for threading threading.Thread.__init__(self) self.terminate_request = False #Vehicle Control Signals sending to Arduino self.debval1 = 0.0 #initialize debag value 1 self.debval2 = 0.0 #initialize debag value 2 self.counter = 1.0; #initialize serial communication socket information self.ser_sock = serial.Serial(self.COM_PORT_NAME,self.BAURATE, timeout=0.01, writeTimeout=0.01) self.send_flg = True self.RECEIVE_LENGTH = 16; time.sleep(3) #################################### ### Update RX data from Arduino ### #################################### def update_RX_data_from_arduino(self,str_b): try: str = str_b.decode() #Arduinoから受信した文字列のデコード #str_splitted =str.split(',') if (len(str) == self.RECEIVE_LENGTH): str_splitted = re.split('[,;]', str) self.debval1 = float(str_splitted[0]) #1つ目の数字の取得 print('debval1',self.debval1) self.debval2 = float(str_splitted[1]) #2つ目の数字の取得 print('debval2',self.debval2) except: pass ################################## ### Update TX data to Arduino ### ################################## def update_TX_buffer_to_arduino(self): #Generate sending buffer to Arduino #debug send_buffer = str(self.counter + 2.0) tempbuf = str(self.counter) send_buffer = send_buffer + "," + tempbuf send_buffer = send_buffer + ";" #for charactor end token self.counter = self.counter + 1.0 if self.counter > 5.0: self.counter = 1.0 try: self.ser_sock.write(str.encode(send_buffer)) except Exception as e: print("例外args:", e.args) # pass #print("write_error\n") ############################### ### Main Periodic Function ### ############################### def run(self): while(1): if self.terminate_request == True: break; #Finish (User request) if self.send_flg == True: #try: # self.update_TX_buffer_to_arduino() #except: # print("Serial Communication Error (PC->Arduino)") self.update_TX_buffer_to_arduino() self.send_flg = False else: str = "" try: str = self.ser_sock.readline() self.update_RX_data_from_arduino(str) except: print("Serial Communication Error (Arduino->PC)") self.send_flg = True time.sleep(0.050) if __name__ == '__main__': sock_controler = Class_Serial_Socket() #Initialize Serial Communication sock_controler.start()
サンプルコードはgithubで公開している。
次回はROS TopicをArduinoと送受信する方法について説明する。
pygameを用いたゲームパッド操作機能の実装
この記事の目的
pythonのライブラリpygameを用いてゲームパッドでユーザーの入力を読み込む処理を実装する。
使用したゲームパッド
ゲームパッド Logicool ロジクール F310r 国内正規品 3年間メーカー保証
参考となるサイト https://glorificatio.org/archives/1398
pygame
pygameとは
pythonのゲーム制作用ライブラリ 2Dの画面描画/音楽再生機能/ユーザー操作入力(マウス/キーボード/ゲームパッド)が充実しており、ゲーム以外にも処理結果の描画やUIとして利用することができる。
機能/使い方の詳細
インストール
windows (anacondaの場合)
pip install pygame
Ubuntu mateの場合
sudo apt-get install python-pygame
GUI描画(Hello World) とキーボード読み込み
初期化処理でスクリーンサイズなどを設定したあとで、30msec間隔をあけながらキーボードの状態を取得して 赤丸の位置を動かす処理は、下記のように記述できる。
#!/usr/bin/env python # -*- coding: utf-8 -*- import pygame from pygame.locals import * import sys SCREEN_SIZE = (640, 480) # 画面サイズ (横/縦) STEP = 10 #キーボード/ハットスイッチの反応の良さ if __name__ == '__main__': # Pygameを初期化 pygame.init() screen = pygame.display.set_mode(SCREEN_SIZE) # SCREEN_SIZEの画面を作成 pygame.display.set_caption("window test") # Windowタイトルの設定 X_CENTER = int(SCREEN_SIZE[0]/2) Y_CENTER = int(SCREEN_SIZE[1]/2) [circle_x, circle_y] = [X_CENTER, Y_CENTER] #円の初期位置を設定 # 画面描画ループ while True: screen.fill((0,0,0)) # 画面を青色で塗りつぶす # イベント処理 for event in pygame.event.get(): #×ボタンによる終了 if event.type == QUIT: # 終了イベント sys.exit() # キーボード状態の取得 pressed_keys = pygame.key.get_pressed() # 押されているキーに応じて画像を移動 if pressed_keys[K_LEFT]: circle_x = circle_x - STEP if pressed_keys[K_RIGHT]: circle_x = circle_x + STEP if pressed_keys[K_UP]: circle_y = circle_y - STEP if pressed_keys[K_DOWN]: circle_y = circle_y + STEP #描画範囲の上下限チェック if circle_x< 0: circle_x = 0 elif circle_x > SCREEN_SIZE[0]: circle_x = SCREEN_SIZE[0] if circle_y< 0: circle_y = 0 elif circle_y > SCREEN_SIZE[1]: circle_y = SCREEN_SIZE[1] #描画 pygame.draw.circle(screen, (255,0,0), (circle_x,circle_y), 10) pygame.display.update() # 画面を更新 pygame.time.wait(30) # 30msec 待ち
コントローラの読み込み
ジョイスティックの初期化
下記処理を初期化部分に追加するとpygameでジョイスティックを初期化できる。
pygame.joystick.init() try: joy = pygame.joystick.Joystick(0) # create a joystick instance joy.init() # init instance print("Joystick Name: " + joy.get_name()) print("Number of Button : " + str(joy.get_numbuttons())) print("Number of Axis : " + str(joy.get_numaxes())) print("Number of Hats : " + str(joy.get_numhats()))
F310の場合、軸やボタン数を下記のように取得できる。
Joystick Name: Controller (Gamepad F310) Number of Button : 10 Number of Axis : 5 Number of Hats : 1
ジョイスティック(アナログバー)の読み込み
アナログバーは各軸について -1~1の小数値で得られる。 F310の場合axis(2)はLRキーの強さに対応する軸なので注意。 (下記は左スティックのみ有効としている)
#ジョイスティック(アナログバー左スティック)状態の取得 circle_x = int((joy.get_axis(0)+1) * X_CENTER) #joystick(横軸)の方向キーはは-1~1の範囲で取得できる circle_y = int((joy.get_axis(1)+1) * Y_CENTER) #joystick(縦軸)の方向キーはは-1~1の範囲で取得できる # axis(2)はL2/R2キーに対応 #ジョイスティック(アナログバー右スティック)状態の取得 #circle_x = int((joy.get_axis(3)+1) * X_CENTER) #joystick(横軸)の方向キーはは-1~1の範囲で取得できる #circle_y = int((joy.get_axis(4)+1) * Y_CENTER) #joystick(縦軸)の方向キーはは-1~1の範囲で取得できる
方向ボタン(ハットスイッチ)読み込み
方向ボタン(ハットスイッチ)は縦横軸それぞれを-1,0,1の離散値として取得できる
#方向ボタン (ハットスイッチ) hat_input = joy.get_hat(0) if hat_input[0] == -1: # circle_x = circle_x - STEP elif hat_input[0] == 1: circle_x = circle_x + STEP if hat_input[1] == 1: circle_y = circle_y - STEP elif hat_input[1] == -1: circle_y = circle_y + STEP
上記の3つの入力手段を切り替えることができるpygameのスクリプトをgithubに保存した。
次回は上記の処理をROSと結合して目標速度指令を送信し、turtlesimを動かす機能を実装する。
ROS入門 ワークスペース/パッケージ/ノード (python開発環境/vscode導入)
この記事の目的
pythonを用いたROSのパッケージの作成・ノードの実装・トピックの送受信についてまとめる。 Visual studio Codeを導入し、pythonのスクリプトを実装しやすい環境を構築する。
pythonを用いたROSプロジェクト構築
ROSでは処理を実装して動作させるまでに下記のワークスペース/パッケージ/ノードを準備する必要がある。 以下に最低限のコマンドなどをまとめて記述する。
用語 | 内容 |
---|---|
workspace | ROSプロジェクト開発の作業用フォルダ |
package | 機能の集合体(開発時にmakeするプロジェクトの最小単位) |
node | プロセスとして相互にメッセージを通信する単位 |
1 ワークスペースの作成
下記チュートリアルに従ってcatkin_wsを作成する
ターミナルを開きホームフォルダ直下にcatkin_wsを作成する ここで、setup.bashはcatkin_ws内に作成したパッケージの読み込みに必要となる設定である。下記スクリプトを記載しておくと起動時に自動的に読み込まれる。
$ mkdir -p ~/catkin_ws/src # ホーム直下にcatkin_ws/srcを作成 $ cd ~/catkin_ws/src # srcに移動 $ catkin_init_workspace # ワークスペースの初期化を実施 $ cd ~/catkin_ws/ # catkin_wsに移動 $ catkin_make # ワークスペースのビルドを実施 $ echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc # bashrc にプロジェクトフォルダのsetup.bashを読み込む設定を追記 $ source .bashrc #bashrcの読み込み (入力したときのみ必要。以降は起動時にbashrcから読み込まれる)
2 パッケージの作成
下記チュートリアルに従ってcatkin_ws内にパッケージを作成する
$ cd ~/catkin_ws/src # catkin_ws/srcに移動 $ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp # catkin_create_pkg [パッケージ名] [依存ライブラリ1] [依存ライブラリ2]... #上記ではROSの標準メッセージ std_msgsとpython開発環境/C開発環境を読み込んでいる
ここでパッケージ以下には下記のようなファイル・フォルダ構成としておく。(cmakelists.txtとpackage.xml以外は必要に応じて追加する)
フォルダ・ファイル名 | 説明 |
---|---|
CMakeLists.txt | パッケージ用のcmakeファイル(ビルドの依存関係の設定など) |
package.xml | rosプロジェクトの名前/依存関係を記載したファイル |
include | パッケージのヘッダファイル(外部公開用) |
src | C言語の実装済みソフトウェア(使用するときのみ) |
script | pythonの実装済みソフトウェア(使用するときのみ) |
msg | ユーザーが型定義するros message(使用するときのみ) |
launch | ユーザーが定義するlaunchファイル(使用するときのみ) |
3 Visual Studio Codeの導入
上記まででプロジェクトの作成ができたので、pythonでのスクリプトを記述する。
pythonスクリプトの開発は標準インストールされているテキストエディタでもできるがVisual Studio Codeを用いるとコード補完などが動作するので効率が良い。
Ubuntu mate for Raspberry pi 用の Visual Studio Code のインストール手順
$ wget -qO - https://packagecloud.io/headmelted/codebuilds/gpgkey | sudo apt-key add - #GPGキーの設定 $ sudo su #管理者権限の付与 . <( wget -O - https://code.headmelted.com/installers/apt.sh ) #インストール用スクリプトの読み込み
ただし、下記記事にあるようにUbuntu mate 16.04と最新バージョンのVS codeでは正しく動作しなかったので1.29にデグレした。
sudo apt-get install code-oss=1.29.0-1539702286 -y --allow-downgrades #1.29へのデグレ sudo apt-mark hold code-oss #バージョンの固定 下記コマンドで解除可能 #sudo apt-mark unhold code-oss
実行後に下記の拡張機能を追加する。
上記設定後にコマンドパレットでpython2.7に切り替えるとVisual studio codeでROS対応したpythonコードを実行できる
下記チュートリアルに従ってtopicをノード間通信するpythonスクリプトを記述する。
talker.py
#!/usr/bin/env python # license removed for brevity import rospy from std_msgs.msg import String def talker(): pub = rospy.Publisher('chatter', String, queue_size=10) rospy.init_node('talker', anonymous=True) r = rospy.Rate(10) # 10hz while not rospy.is_shutdown(): str = "hello world %s"%rospy.get_time() rospy.loginfo(str) pub.publish(str) r.sleep() if __name__ == '__main__': try: talker() except rospy.ROSInterruptException: pass
listener.py
#!/usr/bin/env python import rospy from std_msgs.msg import String def callback(data): rospy.loginfo(rospy.get_caller_id()+"I heard %s",data.data) def listener(): # in ROS, nodes are unique named. If two nodes with the same # node are launched, the previous one is kicked off. The # anonymous=True flag means that rospy will choose a unique # name for our 'listener' node so that multiple listeners can # run simultaenously. rospy.init_node('listener', anonymous=True) rospy.Subscriber("chatter", String, callback) # spin() simply keeps python from exiting until this node is stopped rospy.spin() if __name__ == '__main__': listener()
上記の2つのファイルを記述後にそれぞれのpythonファイルを実行するとtopic通信が行われることが確認できる。 次回はpythonでジョイスティックやGUIを行いながらトピックの通信を行うスクリプトについて記述する。
ROS入門 (概要/用語/コマンド)
- この記事の目的
- ROSの考え方/用語の整理
- ROSのプロセス/通信の概念・用語
- ROSコマンドの使い方 (チュートリアルを利用)
- 1.roscoreの起動
- 2.ノードの起動
- 3.動作結果の確認
- 4.動作結果の保存
- よく使うコマンドリストのまとめ
この記事の目的
ROSを使った開発の考え方、手順(チュートリアルを通じたコマンドの使い方)についてまとめる
ROSの考え方/用語の整理
ROSの特徴や利点については下記サイトに細かく記載されている。
特に、自動運転・ロボット関連の試作に便利なライブラリ(自己位置推定など)やデバッグ用のツールが充実しており、それらに関する試作を行う場合には非常に便利なフレームワークといえる。
ROSのプロセス/通信の概念・用語
上記のようにROSは便利なフレームワークではあるが使い方や固有の用語がかなり多い。 公式チュートリアル (http://wiki.ros.org/ja/ROS/Tutorials)を参考にしても良いが、 初級の時点でファイルシステムやパッケージファイルの詳細の説明をしており、直観的な 理解が難しいと感じた。そこで、今後説明しやすいように下記にROSでアプリケーションを 構築する際のプロセス/通信に関する概念と用語をまとめてみた。
参考 http://forestofazumino.web.fc2.com/ros/ros_basics.html
用語 | 内容 |
---|---|
Node | プロセス(処理) |
Message | ノード間の送受信 |
Master | ノード・メッセージの名称管理をする |
Topic | 非同期で送受信するノード間信号 |
Subscriber | Topicを受信する側のノード |
Publisher | Topicを送信する側のノード |
Service | 同期型(受信してすぐ処理を実行する)のノード間通信 |
Service Server | Serviceを受けて実行結果を出力するノード |
Service Client | Serviceを要求して結果を受理するノード |
上記については下記参考書の解説を読むとわかりやすい。
ROSではじめるロボットプログラミング―フリーのロボット用「フレームワーク」 (I・O BOOKS)
ROSコマンドの使い方 (チュートリアルを利用)
ROSではノードの起動や通信内容の確認、可視化をROSコマンドを用いて行う。 基本的には、下記の順で使用することが多い。 公式のチュートリアルにあるturtlesimを用いて使い方をまとめる。
1.roscoreの起動
roscore
各ノード・送受信信号の名前の管理、標準入出力処理を行う ROS上で処理を動作させる場合は必ず起動する必要がある (起動していない状態で別ノードを起動させようとするとroscoreの起動待ちになる)
2.ノードの起動
下記の2つの方法で起動できる。 オプションが多い場合はlaunchファイルを作っておくと良い。
rosrunコマンド
rosrun turtlesim turtlesim_node
# rosrun [package_name] [node_name]
rosrun turtlesim turtle_teleop_key
# turtlesim_nodeとは別のターミナルで起動する
コマンド rosrunを使いパッケージ名とノード名を指定して起動する apt-getで入れたライブラリでは問題ないが、自作で作ったパッケージの 場合パスを通しておく必要がある。
複数のノードを立ち上げる場合はそれぞれターミナルを立ち上げて実行する。
roslaunch
roslaunch beginner_tutorials turtlemimic.launch #事前に下記チュートリアルに従った準備が必要 #roslaunch beginner_tutorials turtlemimic.launch
launch ファイル内に立ち上げたいノードと起動時のオプション (パラメータの有効/無効など)を渡すと1つのターミナルでノードをまとめて起動できる。ライブラリによっては最初からlaunchファイルで起動できるように提供されているものがある。(turtlesimはないのでチュートリアルに従って記述する必要がある)
3.動作結果の確認
ノードを立ち上げたあと、各ノードの状態・通信内容は下記のコマンドで確認する。
コマンドによる確認
送受信中の信号一覧の表示には下記を利用する。 rostopic list では信号の送受信が成立していなくても、 受信待ちの状態となるだけでリストに出力されることに注意する必要がある。 信号が狙いの周期で更新できているかは rostopic hzなどを用いたほうが良い。
# ROSで通信している全信号リスト rostopic list # ROSで通信している信号の出力 # rostopic echo [topic名] rostopic echo /turtle1/pose #表示例 --- x: 5.544444561 y: 5.544444561 theta: 0.0 linear_velocity: 0.0 angular_velocity: 0.0 --- # ROSで通信している信号の更新周期の出力 # rostopic hz [topic名] rostopic hz /turtle1/pose #表示例 subscribed to [/turtle1/pose] average rate: 62.515 min: 0.015s max: 0.017s std dev: 0.00047s window: 61 average rate: 62.519 min: 0.014s max: 0.017s std dev: 0.00052s window: 123
GUIによる確認
コマンドによる確認の他に、rosのGUI機能rqt_graphでノードとトピックの関係を 可視化して接続関係を確認することができる。
# GUIツール rqt_graphを用いたノードの通信状態の可視化
rosrun rqt_graph rqt_graph
また、各トピックの波形 (時系列変化)を表示することもできる。
# GUIツール rqt_graphを用いた波形の時間変化の可視化
rosrun rqt_plot rqt_plot
rvizによる確認
ROSで用意された形式に従って位置や速度情報を出力するとロボットが空間でどのような動きをしているかをrvizを使って確認することができる。 (tfの発行なども必要なので下記チュートリアルに従う)
rviz
4.動作結果の保存
動作中のノード間でどのような信号の送受信が行われたのかを保存することができる。この機能を用いることで同じカメラ信号のrosbag信号を流しながら自己位置推定処理のデバッグをシミュレーションで行うなどの使い方が可能になる。
#全ての送受信信号の保存 (ターミナルのパスにbagファイルが生成される) rosbag record -a
#bagファイルを再生する #再生中は記録時と同じタイムスタンプでトピックの送受信が行われる rosbag play recorded1.bag
よく使うコマンドリストのまとめ
https://qiita.com/tomoyafujita/items/13076d37bcac05a83530
https://raspimouse-sim-tutorial.gitbook.io/project/ros_tutorial
用語 | 内容 |
---|---|
roscore | マスターノードの起動 (rosを使用する際は必須) |
rosrun [ノード名] | ノードの起動 |
roslaunch [launchファイル名] | launchファイルを用いたノード起動 |
rostopic list | ros上で通信しているtopicのリスト出力 |
rostopic echo [topic名] | topic名の内容の出力 |
rostopic hz [topic名] | topicの更新周期の出力 |
rosbag record -a | ros上で通信しているtopicをbagファイルに保存 |
rosrun rqt_graph rqt_graph | rqt_graphの起動 |
rviz | rvizの起動 |
次回はpythonを使ったノードの開発・トピックの通信例についてまとめる。
Raspberry pi 開発環境について(Ubuntu Mate設定/ROS導入)
この記事の目的
RaspberryPi3(with ROS/Python) を使った電子工作の環境構築手順についてまとめる
ROSを使ったロボット制御のソフトウェアを実装するため下記を導入する。
Ubuntu Mate 16.04
ROS Kinetic
必要なハード
下記記事のハードを用い、Raspberry pi 3 model B を使用する。
下記の手順はWindows PC で必要なソフトのダウンロードやmicroSDカードへの書き込みなどを行うことを前提とする。
環境構築手順
1.SDカードの初期化
Raspberry pi はmicroSDカードにOSを書き込む必要がある。
公式サイトではツールSDCardFormatterでFAT32に初期化する手順を推奨しているが、SDカードのサイズが64GB以上の場合exFATに自動的に変換してしまうので注意が必要。
下記のIOデータのハードディスクフォーマッタではフォーマット時にFAT32を明示的に選択することができる。
2.OSイメージの焼き込み
現在(2019.6)時点で、公式サイトのUbuntu Mate は 18.04に更新されている。
Ubuntu Mate 18.04 に対してROSを入れることも可能なようであるが、まだリリースされてから日が浅くトラブルも多いと予想できるので、 ここではUbuntu 16.04を導入する。Ubuntu 16.04はすでに公式サイトからはダウンロードできなくなっているが、下記サイトからダウンロード可能である。 (torrent形式なのでBitTorrentなどを用いてダウンロードする必要がある)
ダウンロードしたubuntu-mate-16.04.2-desktop-armhf-raspberry-pi.img.xz は7.zipでimgファイルに展開する
展開したimgファイルを下記のWin32 Disk ImagerでmicroSDカードに焼きこむ
3.初期設定
上記までの手順でUbuntu Mateを焼きこんだmicro SDカードを、Raspberry pi の SDカードスロットに差してmicro USBから電源供給すると Raspberry pi 3が起動する。
Wifi/地域設定/キーボード設定をインストーラーはインストーラーの手順に従って実施すればできる。
システムの更新
Mate Terminalを開いて下記コマンドを実行
sudo apt-get update sudo apt-get upgrade
その他初期設定に関する記事(画面の最大化なども便利)
上記を実施するとfirefoxがクラッシュする。(バージョンによって起動しないとのこと)ブラウザにこだわりがなければ下記でchromiumを導入してしまった方が早い。
sudo apt install chromium-browser
日本語入力対応
地域設定をしておくとGUI表示はデフォルトで日本語になる 言語設定が必要なのでシステム⇒設定⇒ユーザー向け⇒言語サポートからインストールし、入力形式をfcitxに変更する 下記に画像付きの解説がされている。
IP固定
Windows PCからリモートでのログインやデータの受け渡しのために、IPを固定しておくと便利である。 Wifiであれば、画面右上のネットワークアイコン以下のGUIを使って設定が可能である
https://qiita.com/dendensho/items/ab63e4b343607d832f21
ファイル共有設定
sambaのインストールと設定行い、Raspberry pi のファイルをWindows PC からアクセス可能にできる
sudo apt-get -y install samba
上記を実施後、下記サイトにある『UI を使って samba を設定する(おまけ)』に従うとGUIを使ってsambaの共有設定ができる。
https://pinky-blog.com/raspberry-pi/nas-samba-server-ubuntu-mate/
リモートデストップの有効化
下記コマンドでxrdpをインストールする
sudo apt-get -y install xrdp
その後、下記サイトに従って暗号化レベルの変更と日本語キーボード設定を追加する (日本語キーボード設定がないと円マークなどが正しく入力できなくなる)
4. ROSのインストール
公式の手順に従いros-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-get update sudo apt-get upgrade sudo apt-get install ros-kinetic-desktop-full sudo apt install python-roslaunch
次にrosのパッケージ管理機能の初期化/更新を行う
rosdep init rosdep update
最後に環境変数にROSのパスを通す (ROSのコマンドを利用するために必要)
echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc source ~/.bashrc
上記まででRaspberry pi でROSを使う準備が整う。 ROSのcatkin_workspaceの作り方などについては今後別記事で説明する。
Raspberry pi 開発環境について(ハードウェア)
この記事の目的
Raspberry pi の電子工作の開発環境について必要なハードウェアに関する情報を忘備録として整理する。
必須ハード
Raspberry pi 本体
カメラを使った画像認識などをすることを考慮すると、なるべく高スペックなものが望ましい。
2019年6月現在、下記のRaspberry pi 3 model B+が、最新かつ高スペックなRaspberry piである。
Raspberry Pi3 Model B+ ボード&ケースセット
ただし、1つ前のモデルであるRaspberry pi 3 model Bとのスペック差はさほどない。(CPUクロック数のわずかな上昇と通信速度の上昇程度)のと、Pi3の方が発売されてからの期間が長く各種開発環境の動作報告も多いので 以降の記事ではRaspberry pi 3の利用を前提として記載する。
Raspberry Pi3 Model B ボード&ケースセット
AC電源アダプタ
Raspberry Pi 3は micro USB type B端子での電力供給が必要となる。ただし、消費電流が2.5Aとなることからスマホ等のACアダプタでは対応できない可能性が高いため動作確認できているACアダプタを利用することを推奨する。 また、電源ボタンがなくケーブルからの電力供給の有無で起動を判定するため、頻繁な起動/終了の繰り返しで本体の端子が痛む可能性がある。スイッチボタンによる電力の遮断ができる下記のようなACアダプタを使うと便利である。
Raspberry Pi用電源セット(5V 3.0A)-Pi3フル負荷検証済
micro SDカード
Raspberry PiではOS等のソフトウェアをmicroSDカードに保存する必要がある。OSイメージ+基本的なツールを導入するための最低限の必要容量は4GB程度以上だが、今回の用途ではROS環境一式やカメラでの計測データを保存する必要 があるため32GBのものを利用する。 (なお、32GBを上回る容量の場合、SDカードをFAT32でフォーマットする使うツールに気を付ける必要がある。別途記載予定)
東芝 Toshiba microSDHC 32GB + SD アダプター + 保管用クリアケース [バルク品]
また、インストール手順でPCからmicro SDカードへの書き込みをする必要がある。PCにmicro SDを読み込む手段がない場合にはUSBのSDカードリーダーが必要となる。 (速度にこだわらなければ、最近は100均などでも購入可能)
マウス/キーボード/HDMIケーブル
Raspberry pi の操作に利用する。マウス/キーボードはUSB接続のものであればよほど問題はないが、無線接続したい場合は動作実績があるものを利用する方が無難。
初期設定を済ませると、デスクトップPCからリモート接続して利用することも可能となるためあまりこだわらなくてもよい。
モバイルバッテリ
前述したように、Raspberry pi 3 は micro USB type Bによる給電が可能なのでモバイルバッテリからの電源供給ができる。ただし、最近のモバイルバッテリは消費電流が低い場合に省電力モードになってしまったり、 Raspberry pi のピーク時の2.5Aを出力できないなどの場合があるため、動作実績があるものを選んだほうが良い。下記サイトで実機での確認がされている。実際に私が試したところAnker PowerCore 10000、 cheero Power Plus 10050mAhともに問題はなかった。
消費電力が大きなRaspberry Pi3に最適のモバイルバッテリーは? - 猿まね電子工作
カメラ
Raspberry pi では専用のカメラモジュールによる画像取得とPC等で使われるUSB Webカメラによる画像取得が可能である。
カメラモジュールは小型・軽量で省電力ではあるが、取り付けなどに苦労する。下記のような台座とセットになっているものの方が良い。
For raspberry pi カメラモジュール 5MP Raspberry Pi 3 b+ / Pi Zero Camera とケース500W画素 感光チップOV5647センサー
Webカメラは、台座が安定してHD撮影可能なものとして下記などが良い。
LOGICOOL HDウェブカム フルHD動画対応 C615
ブレッドボード/ジャンパハーネス
Raspberry pi のGPIOに各種の電子部品を接続する際に必要となる。ジャンパハーネスは端子にオス-メスの組み合わせがあるので一定数まとめ買いしておいた方が良い。
ELEGOO 120pcs多色デュポンワイヤー、arduino用ワイヤ—ゲ—ジ28AWG オス-メス オス-オス メス –メス ブレッドボードジャンパーワイヤー
ブレッドボードはいろいろな場所への取り付けに対応できるよう小型/横長タイプで複数用意しておいた方が良い。
ELEGOO 400タイポイント ブレッドボード3PCS 、Arduino用ジャンパーワイヤ 4電源レール
次回はRaspberry pi の環境構築 (OS設定/ROSの導入/開発ツール類の設定)について記述する。