Quantcast
Channel: demura.net
Viewing all 757 articles
Browse latest View live

Ubuntu14.04のネットワーク設定

$
0
0

この記事は私が担当している講義ロボットプログラミングⅡ用です。

VirtualBox5.0にインストールしたUbuntu14.04でのネットワーク設定を説明します。

○ ネットワーク設定

(1) 「アプリケーション」→「システムツール」→「システム設定」を選択

proxy0a

(2) 「システム設定」のウインドウが開くので、「ネットワーク」をクリックする。

network1

(3) 「ネットワーク」ウインドウが下図のように起動する

proxy1

(4) 「有線」の下にある「ネットワークプロキシ」をクリックして選択

proxy2

 

(5) メソッド:「自動」、設定URLは大学で設定されているプロキシのアドレス(Windowsや情報処理サービスセンターを参照)にする。

proxy3

ネットワーク設定終わり。

○ Firefoxの設定
Google Chromeは標準で入っていないので、Firefoxを使用する。
(1)  「アプリケーション」→「インターネット」→「Firefoxウェブブラウザ」を選択
firefox0a
(2) Firefoxの「編集」→「設定」を選択
firefox0b
(3)  以下のようなウインドウが開く
firefox1
(4)  上右にある「設定」をクリック
firefox2
(5)  Firefoxは自動プロキシ設定スクリプトがうまく働かないようなので、手動で設定する。アドレスやポート番号はWindowsでの設定と同じ。入力したら「OK」をクリックして終了。
firefox3
以上

ロボットプログラミングⅡ:第1週 環境設定

$
0
0

この記事は私が担当している講義ロボットプログラミングⅡ用です。

turtlebot

ロボットプログラミングⅡでは、フレームワークとしてROSロボットシミュレータとしてGAZEBOを使用します。インストールは次の手順です。Panasonic Let’s Note CF-LX3 (Windows 8.1, Core i7, Memory 8GB)で試しています。

では、以下のリンクに従って第2週の授業までに作業を進めてください。

  1. VirtualBox5.0 + Ubuntu14.04のインストール
    注:仮想マシンの登録と起動 (2) に誤植がありました。バージョンは[Ubuntu(64-bit)]を選択してください。32-bitだと起動に失敗します。お詫びして訂正します(2015年10月4日17:15)。
  2. VirtualBox5.0の設定
  3. Ubuntu14.04のWindowマネージャー設定
  4. Ubuntu14.04のネットワーク設定
  5. ROS Indigoのインストール

以上

ロボットプログラミングⅡ:第2週 はじめてのROS

$
0
0

この記事は私が担当している講義ロボットプログラミングⅡ用です。ROSをインストールしたので、動作確認を兼ねて亀で遊んでみましょう。この記事は以下の記事を参考にしています。

—————————————————————

1. 亀を動かす

(1) 新しい端末を開き、「roscore」と入力しEnterキーを押し、roscoreを起動する。ノード間で通信するために必要。ノードはROSの実行プログラム。

roscore

(2) 新しい端末を開き、「 rosrun turtlesim turtlesim_node」と入力しEnterキーを押すと、亀のいる水色のウインドウが開く。rosrunコマンドの使い方は、rosrun  [パッケージ名] [ノード名]で、パッケージのノードを起動する。パッケージはある機能を実現するためのプログラムの集まり。この例では、turtlesimというパッケージの中のturtlesim_nodeノードを起動している。

turtlesim_node

turtlesim

(3) キーボードで亀を操作。新しい端末を開き「rosrun turtlesim turtle_teleop_key」と入力する。キーボードの矢印キーで亀を動かすことができる。動かない場合は、ここで入力した端末をクリックして選択する。亀のいるTurtleSimウインドウや他の端末をクリックして選択した場合は動かないので注意。

teleop

teleop2

2.解説

動作を確認するために亀と遊んだので少しお勉強。亀が矢印キーで動く仕組みは、turtle_simノードがturtle_teleop_keyノードから送られた(publish、出版)キーのデータを受け取り(subscribe、購読)、亀を動かしている。このデータのことをROSではトピック(topic)とよぶ。これはPublish/Subscribe (出版/購読型モデル)に基づいている。ROSではトピックを使った通信の他にクライアント/サーバーモデルのサービスもある。

3.演習

以下のROSチュートリアルの1.2 ROSトピックから最後まで説明に従って、自分のノートパソコンで動作を確認しよう!

4.ホームワーク

終わり

 

ROS IndigoでRealSense R200

$
0
0

realsense

ROS Indigo (Ubuntu14.04)でIntel RealSense R200を動かしたときの簡単なメモ。バイナリがないのでソースからインストール。院生に教えてもらったが少しはまる。RealSense R200はxtionと比較してもとても小さく、軽量、安価。

  • RealSense – ROS Wikiがソース。少々わかりづらい。RealSenseドライバをインストールするときは、Ubntu14.04の場合patchをあてるスクリプトpatch_ubuntu_uvc.shを行ってからインストールのスクリプト~/src/RealSense_ROS/r200_install/install.shを実行。
  • RealSenseドライバのインストール
    • sudo apt-get update
    • cd
    • mkdir src
    • cd src
    • git clone https://github.com/PercATI/RealSense_ROS.git
    • cd ~/src/RealSense_ROS/r200_install/ds_uvcdriver/scripts
    • chmod u+x patch_ubuntu_uvc.sh
    • sudo ./patch_ubuntu_uvc.sh
    • cd  ~/src/RealSense_ROS/r200_install
    • sudo ./install.sh
    • cd ~/src/RealSense_ROS/r200_install/ds_connectivity_workaround
    • chmod u+x install_rules.sh
    • sudo ./install_rules.sh
  • R200ノードレットのインストール
    • cd ~/src/RealSense_ROS/realsense_dist/2.3
    • sudo ./install_realsense_ros.sh
      エラーが出る場合は以下を実行して下の図のようrに$ROS_DISTROをindigoに変更してやり直す。
      $ gedit install_realsense_ros.shr200
  • R200ノードレットの実行
    • roslaunch  realsense  realsense_r200_launch.launch
    • rosrun rviz rviz
      • file->open configで以下のファイルを開くと上の画像open~/src/RealSense_ROS/realsense_dist/2.3/realsenseRvizConfig.rviz

終わり

ロボットプログラミングⅡ:第3週 はじめてのROSプログラミング

$
0
0

この記事は私が担当している講義ロボットプログラミングⅡ用です。ROSでHellow Worldと表示するプログラムを作り、ビルドして実行してみましょう。この記事は以下のROS Wikiの記事を参考にしています。

———————–
1. ワークスペース(作業場所)の作成
これからROSでいろいろなプログラムを作っていきます。まずは、その専用ディレクトリ(フォルダ)を作りましょう。ROSではこれをワークスペースとよびます。catkin_init_workspaceコマンドでワークスペースを作ります。以下のコマンドを実行してください。なお、先頭の$は入力を受け付けるコマンドプロンプトなので打つ必要はありません。

$ source /opt/ros/indigo/setup.bash
$ mkdir -p ~/catkin_ws/src
$ cd ~/catkin_ws/src
$ catkin_init_workspace

2. ビルドの方法
ROSではソースコードをビルドするときにcatkin_makeコマンドを使います。このコマンドを実行するときは~/catkin_wsに移動しなければいけません。重要なので覚えておきましょう。
次のコマンドを実行してください。
$ cd ~/catkin_ws
$ catkin_make
実行後にlsコマンドを実行すると、buildとdevelディレクトリが新たに作成されていることがわかります。

3.  設定
ここで作成したcatkin_wsを有効にするためには以下のコマンドを実行する必要があります。
$ source ~/catkin_ws/devel/setup.bash
毎回、実行するのは面倒なので~/.bashrcの一番最後にテキストエディターgeditを使い付け加え保存しましょう。source /opt/ros/indigo/setup.bashがない場合は、下図赤枠のように追加してください。次のコマンドを実行します。
$ cd
$ gedit .bashrc
bashrc
うまく設定されたか確認しましょう。次のコマンドを実行します。
$ source .bashrc
$ echo $ROS_PACKAGE_PATH
つぎのように表示されたら成功です。
path失敗した場合は、設定をもう一度実行してください。打ち間違えがないか注意しましょう。

4. パッケージの作成
準備ができたので早速、パッケージを作りましょう。パッケージは次のcatkin_create_pkgコマンドで作ります。依存パッケージはそのパッケージを作るために必要なパッケージです。
catkin_create_pkg <パッケージ名> [依存パッケージ1] [依存パッケージ2] [依存パッケージ3]
helloパッケージを作りましょう。ここではC++でコーディングするのでroscppパッケージしか使いません。Pythonを使う場合はrospyになります。
$ cd ~/catkin_ws/src
$ catkin_create_pkg hello roscpp
上手く作成しているか確認します。
$ cd ~/catkin_ws/src/hello
$ ls
CMakeLIsts.txt, include, package.xml, srcができていれば成功です。
package.xmlに作成者(maintainer)の情報などを書きます。ここでは省略します。ROS Wikiのpackage.xmlを参考にしてください。

5. ソースコードの作成とビルド
$ cd ~/catkin_ws/src/hello/src
$ gedit hello_node.cpp
エディタが開くので以下をソースコードを打ち込み保存する。
hello

~/catkin_ws/src/hello/src/CMakeLists.txtの129行目、136~138行目のコメントを次のように外す。
cmakelist
ビルドします。
$ cd ~/catkin_ws
$ catkin_make

6. 実行
以下のroscoreコマンドでMaster(マスター)を実行する。他のノードを実行する前に必要です。
$ roscore
ノードを実行するためにはrosrunコマンドを使います。使い方は次のとおり。
rosrun パッケージ名 実行ファイル名
別の端末を開き、rosrunコマンドでhello_nodeノードを実行する。
なお、hello_nodeは~/catkin_ws/devel/lib/hello/hello_nodeにcatkin_makeコマンドで作られたものです。
$ rosrun hello hello_node
次のように表示されたら成功。終わり。
hello_world

VirtualBoxで有線と無線LANの設定

$
0
0

VirtualBox(ホストWindows8.1, ゲストUbuntu14.04)のUbuntu上で有線と無線を両方使える設定。

1. VirtualBox マネージャーの設定をクリック
network_setting0

2. ネットワークをクリック。基本設定ではアダプタ-1しか設定されてない。network_setting1

 

3. アダプター2をクリック。下の図のように設定する。
割り当て:ブリッジアダプター
名前:ノートパソコンにより違う。無線LANのデバイスを選択
ケーブル接続に✔をいれる。
network_setting2

終わり

アンドロイドスマホからTurtlebotを動かそう!

$
0
0

アンドロイド端末(スマホやタブレット)からTurtlebotを動してみよう!

(1) 準備
アンドロイドスマホからロボットを操縦する。まず、PlayストアからRocon Remocon (Indigo)をインストールする。
ad-playstore

(2) .bashrcの設定
geditで.bashrcを開く。
$ gedit .bashrc

下図のようにROS_MASTER_URl(小文字のエル)とROS_HOSTNAMEを設定する。ROS_MASTER_URlは図と同じ、ROS_HOST_NAMEはubuntuの無線LANのIPアドレスを入力する(この例では192.168.33.33)。IPアドレスはifconfigコマンドで調べる。
bashrc

(3) 各パッケージ起動
端末を3個起動し、各端末で以下のコマンドを実行。
$ roscore
$ roslaunch kobuki_gazebo kobuki_playground.launch
$ roslaunch turtlebot_bringup minimal.launch

(4) アンドロイドアプリ起動
a. Rocon Remoconを起動
ad-icon
b. “SCAN THE LOCAL NETWORK”をタップ
ad-master
c. ネットワーク設定に問題がなければTurtlebotが見つかる。✔を入れて、”SELECT”をタップ。
ad-scan
d. “Turtlebot”をタップ。
ad-find
e. “Teleop”をタップ。
ad-teleop1
f. “Launch”をタップ。
ad-teleop2
g. 右側の円から進みたい方向に指で画面をなぞるとその方向に進む。
ad-teleop3
終わり

ROS×Python勉強会:Turtlebotを動かそう!

$
0
0

この記事は生活支援ロボット:ROS×Python勉強会用の資料です。Turtlebot2/KOBUKIを動かします。次のROS Wikiを参考にしています。

この記事は私が担当している講義ロボットプログラミングⅡ用です。シミュレータGAZEBOを使い、Turtlebotを動かします。次のROS Wikiを参考にしています。

1.  Turtlebot用のパッケージインストール
まず、Turtlebot用のパッケージをインストール。端末を開き、次のコマンドを実行。
$ sudo apt-get update
$ sudo apt-get install ros-indigo-turtlebot ros-indigo-turtlebot-apps ros-indigo-turtlebot-interactions ros-indigo-turtlebot-simulator ros-indigo-kobuki-ftdi ros-indigo-rocon-remocon ros-indigo-rocon-qt-library ros-indigo-ar-track-alvar-msgs
$ .  /opt/ros/indigo/setup.bash
$ rosrun kobuki_ftdi create_udev_rules

2. VirtualBoxの設定
VirtualBox以外の人は次に進む。なお、VirtualBoxのUbuntuからTurtlebotを動かす場合はノートパソコンにUSB2.0のポートが必要です。USB3.0しかない場合はデュアルブートでLinuxを起動できるようにする必要があります。未確認ですがVMwareなら可能かもしれません。VMwareお持ちの方は試してください。

Virtualboxを起動する。設定→USBをクリック。USBデバイスフィルター右の赤枠で囲んだ「コネクタに+のついたアイコン」をクリック。Yujin robot iCleboKobukiを選択し、「OK」をクリック。
virtualbox_setting1

3. ロボットをキーボードから動かそう
これからキーボードでシミュレータ上のロボットを操縦します。まず、デバイスファイルができているか確認する。

次のコマンドで/devにあるデバイスファイルを表示する。ttyUSB0(ゼロ)があればOK
$  ls  /dev/tty*

/dev/ttyUSB0はス―バーユーザの権限がないと使えないので、ユーザが使えるように次のコマンドでファイルのアクセス権を変更する。
$ sudo chmod  u+x   /dev/ttyUSB0

では、ロボットを動かすための最小限(minimal)ノードを起動しよう!
$ roslaunch turtlebot_bringup minimal.launch

別の端末を開き、次のコマンドでキーボードからロボットを操縦するノードを起動。
$ roslaunch turtlebot_teleop keyboard_teleop.launch 

端末に下のように表示される。u  i o  j  k  l  m , .キーでロボットを操作できる。いずれかのキーを押してロボットを動かそう!
teleop

終わり


ロボットプログラミングⅡ:第4週 シミュレータを動かそう!

$
0
0

この記事は私が担当している講義ロボットプログラミングⅡ用です。シミュレータGAZEBOを使い、Turtlebotを動かします。次のROS Wikiを参考にしています。

1.  Turtlebot用のパッケージインストール
まず、Turtlebot用のパッケージをインストール。端末を開き、次のコマンドを実行。
$ sudo apt-get update
$ sudo apt-get install ros-indigo-turtlebot ros-indigo-turtlebot-apps ros-indigo-turtlebot-interactions ros-indigo-turtlebot-simulator ros-indigo-kobuki-ftdi ros-indigo-rocon-remocon ros-indigo-rocon-qt-library ros-indigo-ar-track-alvar-msgs
$ . /opt/ros/indigo/setup.bash
上はドットコマンド(.)といい、ドット(.)の後にスペース、そのあとにコマンドを入れる。機能は現在のシェルからそのコマンドを実行する。通常はコマンドを実行すると別のシェルが呼び出されコマンドを実行するが、現在のシェル変数などは引き継がれない。また、ドットコマンドは、そのコマンドの実行権限がなくても実行できる。ドットコマンドの代わりにsourceコマンドも利用できる。
$ rosrun kobuki_ftdi create_udev_rules

2. ロボットをキーボードから動かそう
これからキーボードでシミュレータ上のロボットを操縦します。まず、roslaunchコマンドでシミュレータを起動。
$ roslaunch turtlebot_gazebo turtlebot_world.launch
初回はネットからモデルを取得するので、私の環境で10分程度かかった。しばらくすると次のようなウインドウが開く。黒い円柱状のロボットがturtlebot。
turtlebot-gazebo

次に、ロボットを動かすための最小限(minimal)ノードを起動。
$ roslaunch turtlebot_bringup minimal.launch

別の端末を開き、次のコマンドを入力するとキーボードからロボットを操縦するノードを起動。
$ roslaunch turtlebot_teleop keyboard_teleop.launch

端末に下のように表示される。u  i o  j  k  l  m , .キーでロボットを操作できる。いずれかのキーを押してロボットを動かそう!

これで動かない場合は、minimal.launchを起動している端末ごと終了させて、再度、新しい端末を開いて、minimal.launchを起動してください。
teleop

3. キーボードから動かすプログラムを作ろう!
キーボードからロボットを操縦するmy_teleopパッケージを作りましょう。
第3週と同じ要領でmy_teleopパッケージを作ります。今週の例ではhello, hello_nodeをmy_teleopに置き換えてください。

以下のプログラムはmy_teleop.cpp。エディタにコピペして名前を付けて保存。
保存ディレクトリは~/catkin_ws/src/my_teleop/srcの中。

#include "ros/ros.h"  // rosで必要はヘッダーファイル                                    
#include <geometry_msgs/Twist.h> // ロボットを動かすために必要                          
using namespace std;

int main(int argc, char **argv)
{
  ros::init(argc, argv, "my_teleop");
  // initでROSを初期化し、my_teleopという名前をノードにつける                        
  // 同じ名前のノードが複数あるとだめなので、ユニークな名前をつける                 

  ros::NodeHandle nh;
  // ノードハンドラの作成。ハンドラは必要時に起動される。                         

  ros::Publisher  pub;
  // パブリッシャの作成。トピックに対してデータを送信。                                 

  ros::Rate rate(10);
  // ループの頻度を設定。この場合は10Hz、1秒間に10回数、1ループ100ms。                  

  geometry_msgs::Twist vel;
  // geometry_msgs::Twist この型は並進速度と回転速度(vector3:3次元ベクトル) を合わせたもので、速度指令によく使われる                                           

  pub= nh.advertise<geometry_msgs::Twist>("/cmd_vel_mux/input/teleop", 10);
  // マスターにgeometry_msgs::Twist型のデータを送ることを伝える                         
  // マスターは/cmd_vel_mux/input/teleopトピック(1番目の引数)を購読する                
  // 全てのノードにトピックができたことを知らせる(advertise)。                          
  // 2番目の引数はデータのバッファサイズ                                                

  std::cout << "f: forward, b: backward, r: right, l:left" << std::endl;

while (ros::ok()) // このノードが使える間は無限ループ                                 
    {
      char key;  // 入力キーの値                                                        

      cin >> key;
      cout << key << endl;

      switch (key) {
      case 'f': vel.linear.x  =  0.5; break;
      case 'b': vel.linear.x  = -0.5; break;
      case 'l': vel.angular.z =  1.0; break;
      case 'r': vel.angular.z = -1.0; break;
        // linear.xは前後方向の並進速度(m/s)                                            
        // angular.zは回転速度(rad/s)                                                   
      }

      pub.publish(vel); // 速度メッセージを送信                                         
      ros::spinOnce();  // コールバック関数を呼ぶ                                       
      vel.linear.x  = 0.0; // 並進速度の初期化                                              
      vel.angular.z = 0.0; // 回転速度の初期化
      rate.sleep();     // 指定した周期でループするよう寝て待つ                         

     
    }

  return 0;
}

では、以下のコマンドでビルドして実行しよう。

$ cd ~/catkin_ws
$ catkin_make

先ほどの、roslaunch turtlebot_teleop keyboard_teleop.launch の代わりに、次のコマンドを実行する。
$ rosrun my_teleop my_teleop

f, b, l, rキーでロボットが移動したら成功。

終わり

終わり

ロボットプログラミングⅡ:第5週 双方向通信しよう(サービス)!

$
0
0

この記事は私が担当している講義ロボットプログラミングⅡ用です。今回はROSのサービスを理解しましょう。次のROS Wikiを参考にしています。

サービスはROSの通信方法の一つで、双方向通信に使います。ある仕事をお願いするクライアントとそれを処理して返すサーバーからなります。今回、作成するプログラムは速度指令値を送るクライアントと、それをロボットへ伝え(リクエスト)、ロボットから現在の速度を取得しクライアントに返す(レスポンス)サーバーです。次の手順でやりましょう。この例は、前回学んだトピック通信も入れていますので、実践的な内容です。

1.my_serviceパッケージの作成
$ cd ~/catkin_ws/src
$ catkin_create_pkg my_service std_msgs rospy roscpp

2.srvファイルの作成。srvファイルはやり取りするデータの型を表すテキストファイル。拡張子がsrv、この例のファイル名はWheel.srv。
$ cd ~/catkin_ws/src/my_service
$ mkdir srv
$ cd srv
$ gedit Wheel.srv
内容は次のコード。——-の上が入力(リクエスト)、下が出力(レスポンス)を表す。

float64 target_linear_velocity
float64 target_angular_velocity
---------------
float64 current_linear_velocity
float64 current_angular_velocity

並進、回転速度指令値target_linear_velocity, target_angular_velocityがリクエストされると、
現在の並進、回転速度current_linear_velocity, current_angular_velocityがリスポンスされる。

3.Package.xmlの変更
~/catkin_ws/src/my_service/Package.xmlの35、39行目のコメントタグを次のように外す。message_generation, message_runtimeを有効にする必要あり。

  <!-- Use build_depend for packages you need at compile time: -->              
  <build_depend>message_generation</build_depend>
  <!-- Use buildtool_depend for build tool packages: -->
  <!--   <buildtool_depend>catkin</buildtool_depend> -->
  <!-- Use run_depend for packages you need at runtime: -->                     
  <run_depend>message_runtime</run_depend>

4.CMakeLists.txtの変更
~/catkin_ws/src/my_service/CMakeLists.txtの11行目、std_msgsの下にmessage_generationを追加。

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospyp
  std_msgs
  message_generation
)

次の54~59行目を

## Generate services in the 'srv' folder                                        
# add_service_files(                                                            
#   FILES                                                                       
#   Service1.srv                                                                
#   Service2.srv                                                                
# )   

以下に変更。

## Generate services in the 'srv' folder                                        
 add_service_files(
   FILES
   Wheel.srv
 )

次の70~74行目

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

のコメントを外し、次にする。
## Generate added messages and services with any dependencies listed here
generate_messages(
DEPENDENCIES
std_msgs
)

次に示す102~107行目

#catkin_package(                                                                
#  INCLUDE_DIRS include                                                         
#  LIBRARIES my_service                                                         
#  CATKIN_DEPENDS roscpp rospy std_msgs                                         
#  DEPENDS system_lib                                                           
#)   

を次に変更

catkin_package(                                                                
  INCLUDE_DIRS include                                                         
  LIBRARIES my_service                                                         
  CATKIN_DEPENDS roscpp rospy std_msgs message_runtime                                        
  DEPENDS system_lib                                                           
)   

5.ビルド
ソースコードを書く前にサービスのライブラリを作成するためにcatkin_makeしてビルドする。
$ cd ~/catkin_ws
$ catkin_make
ビルド時にエラーがでたら、Package.xml, CMakelists.txtに間違えがないか確認し、直して再度ビルド。

6.サービスサーバーのソースコード作成
では、依頼された仕事を処理するサーバープログラムを作ります。次のプログラムをgeditなどを使いwheel_server.cppというファイル名を付けて~/catkin_ws/src/my_service/src/wheel_server.cppと保存。一字でも打ち間違えると動かないのでコピペする。

#include "ros/ros.h"
#include <geometry_msgs/Twist.h>
#include "nav_msgs/Odometry.h"
#include "my_service/Wheel.h"  // 自動的に作られる                                         

class Server {
public:
  Server();      // コンストラクタ                                                         
  ~Server() {};  // デストラクタ                                                           
  // オドメトリのコールバック関数                                                          
  void odomCallback(const nav_msgs::Odometry::ConstPtr& odom);
  // サーバーのコールバック関数(サービスの本体)                                          
  bool wheelService(my_service::Wheel::Request  &req,
                    my_service::Wheel::Response &res);
  void loop(); // ループ関数                                                               

private:
  ros::Publisher cmd_pub;     // パブリッシャ                                              
  ros::Subscriber odom_sub;   // サブスクライバ                                            
  ros::NodeHandle nh;         // ノードハンドルの宣言                                      
  ros::ServiceServer service; // サービス                                                  
  double tmp_linear_velocity; // 現在の並進速度                                            
  double tmp_angluar_velocity; // 現在の回転速度                                           
  const static double max_linear_velocity =  0.7; // 最大並進速度                          
  const static double min_linear_velocity = -0.7; // 最小並進速度                          
  const static double max_angular_velocity =  1.2; // 最大回転速度                         
  const static double min_angular_velocity = -1.2; // 最小回転速度    
  geometry_msgs::Twist target_vel, tmp_vel; // 目標速度、現在の速度                        
};

// コンストラクタ                                                                          
Server::Server()
{
  ROS_INFO("Ready to wheel");

  //サービスの設定                                                                         
  service = nh.advertiseService("wheel",&Server::wheelService,this);

  // パブリッシャ(配信)の設定:                                                             
  cmd_pub= nh.advertise<geometry_msgs::Twist>("/mobile_base/commands/velocity", 10);

  // サブスクライバ(購読)の設定                                                            
  // /odomトピックはロボットの速度情報を持っている                                         
  odom_sub = nh.subscribe("/odom", 10, &Server::odomCallback, this);

  // 速度の初期化                                                                          
  target_vel.linear.x  = 0.0;
  target_vel.linear.y  = 0.0;
  target_vel.linear.z  = 0.0;
  target_vel.angular.x = 0.0;
  target_vel.angular.y = 0.0;
  target_vel.angular.z = 0.0;
  tmp_vel.linear.x  = 0.0;
  tmp_vel.linear.y  = 0.0;
  tmp_vel.linear.z  = 0.0;
  tmp_vel.angular.x = 0.0;
  tmp_vel.angular.y = 0.0;
  tmp_vel.angular.z = 0.0;
}

// サーバーのコールバック関数                                                              
bool Server::wheelService(my_service::Wheel::Request  &req,
                          my_service::Wheel::Response &res)
{
  ROS_INFO("Set velocity: linear=%.2f angular=%.2f",
           req.target_linear_velocity, req.target_angular_velocity);
  // 指令速度が最小、最大速度内かチェック                                                  
  if (min_linear_velocity  > req.target_linear_velocity ||
      max_linear_velocity  < req.target_linear_velocity)  return false;
  if (min_angular_velocity > req.target_angular_velocity ||
      max_angular_velocity < req.target_angular_velocity) return false;
  // クライアントからの速度をロボットの速度指令とする                                      
  target_vel.linear.x  = req.target_linear_velocity;
  target_vel.angular.z = req.target_angular_velocity;
  // /odomトピックからサブスクライブした速度情報をクライアントに返す                       
  res.current_linear_velocity  = tmp_vel.linear.x;
  res.current_angular_velocity = tmp_vel.angular.z;
  return true;
}
// オドメトリのコールバック関数(現在速度を知る)                                          
void Server::odomCallback(const nav_msgs::Odometry::ConstPtr& odom)
{
  tmp_vel = odom->twist.twist; // 現在の速度ゲット                                         
}

// ループ関数                                                                              
void Server::loop()
{
  ros::Rate loop_rate(30); // Hz                                                           

  while(ros::ok()) {
    // ロボットを動かすため目標速度をパブリッシュ                                          
    cmd_pub.publish(target_vel);
    // コールバック関数を呼ぶ                                                              
    ros::spinOnce();
    // 決められた周期でループするため寝て待つ                                              
    loop_rate.sleep();
  }
}

int main(int argc, char **argv)
{
  //ROSの初期化 wheel_serverはノード名                                                     
  ros::init(argc, argv, "wheel_server");

  Server svr;
  svr.loop();
  return 0;
}

7.サービスクライアントのソースコード作成
次に仕事を依頼するのクライアントのソースコートを作成する。以下のソースコードをwheel_client.cppという名前で~/catkin_ws/src/my_service/src/wheel_client.cpp保存する。

#include "ros/ros.h"
#include "my_service/Wheel.h"  // 自動的に作られる                                         

int main(int argc, char **argv)
{
  // 初期化 wheel_clientノード                                                            
  ros::init(argc, argv, "wheel_client");

  ros::NodeHandle nh;
  // サービスクライアントの設定                                                            
  ros::ServiceClient client = nh.serviceClient<my_service::Wheel>("wheel");

  my_service::Wheel srv;

  std::cout << "Input target linear  velocity:";
  std::cin >> srv.request.target_linear_velocity;
  std::cout << "Input target angular velocity:";
  std::cin >> srv.request.target_angular_velocity;

  // サービスを呼ぶ                                                                        
  if (client.call(srv)) {
    // 成功したらサーバーからのレスポンスを表示                                            
    ROS_INFO("Current linear_vel=%f  angular_vel=%f",
             (double) srv.response.current_linear_velocity,
             (double) srv.response.current_angular_velocity);
  }
  else {
    // 失敗したらエラー表示                                                                
    ROS_ERROR("Faild to call service wheel");
    return 1;
  }
  return 0;
}

8.CMakeLists.txtの変更とビルド
以下をCMakeLists.txtに追加

## Declare a C++ executable                                                                
add_executable(wheel_server src/wheel_server.cpp)
add_dependencies(wheel_server my_service_gencpp)
target_link_libraries(wheel_server ${catkin_LIBRARIES})

add_executable(wheel_client src/wheel_client.cpp)
add_dependencies(wheel_client my_service_gencpp)
target_link_libraries(wheel_client ${catkin_LIBRARIES})

$ cd ~/catkin_ws
$ catkin_make

9.実行
端末を4つ開き、各端末で以下のコマンドを実行
$ roslaunch turtlebot_gazebo turtlebot_world.launch
$ roslaunch turtlebot_bringup minimal.launch 
$ rosrun my_service wheel_server
サーバーは次のように表示される。
server1

$ rosrun my_service wheel_client
クライアントはキーボードから入力(速度指令値)をサーバーへ送る。速度指令値が最小、最大値の範囲外ならエラーを返す。それ以外は、シミュレータ上のロボットが動きます。
client1
成功したら終わり。うまく動かない場合は、打ち間違えや手順に間違いがないか確認し、再度実行しましょう。

なお、今回のソースコードをまとめてここmy_service.tgzに置いておきます。
解凍の仕方は次の通り。
$ cp ./my_service.tgz ~/catkin_ws/src
$ cd ~/catkin_ws/src
$ tar xvzf my_service.tgz

turtlebot

ロボットプログラミングⅡ:第6週 簡単なゴール(ActionLib)!

$
0
0

この記事は私が担当している講義ロボットプログラミングⅡ用です。今回はActionLibを使った以下のROSチュートリアルを実行しましょう。

ソース

 
// 本プログラムは
// http://wiki.ros.org/ja/navigation/Tutorials/SendingSimpleGoals
// を改変しています。
#include <ros/ros.h>
#include <move_base_msgs/MoveBaseAction.h>
#include <actionlib/client/simple_action_client.h>

typedef actionlib::SimpleActionClient<move_base_msgs::MoveBaseAction> MoveBaseClient;

struct MyPose {
  double x;
  double y;
  double yaw;
};

int main(int argc, char** argv){
  MyPose way_point[] = {{5.0, 0.0, 0.5 * M_PI}, {0.0, 5.0, 0.5 * M_PI}, 
	                {999, 999, 999}};

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

  // アクションクライアンを作成。1番目の引数は接続するアクションサーバー名。
  // アクションサーバーが立ち上がっていないとだめ。
  // 2番目の引数はtrueならスレッドを自動的に回す(ros::spin()。
  MoveBaseClient ac("move_base", true);
  // アクションサーバーが起動するまで待つ。引数はタイムアウトする時間(秒)。
  // この例では5秒間待つ(ブロックされる)
  while(!ac.waitForServer(ros::Duration(5.0))){
      ROS_INFO("Waiting for the move_base action server to come up");
  }

  ROS_INFO("The server comes up");
  move_base_msgs::MoveBaseGoal goal;
  // base_link座標系(ロボット座標系)
  goal.target_pose.header.frame_id = "base_link";
  // 現在時刻                                                                       
  goal.target_pose.header.stamp = ros::Time::now();


  int i = 0;
  while (ros::ok()) {
    // ROSではロボットの進行方向がx座標、左方向がy座標、上方向がz座標
    goal.target_pose.pose.position.x =  way_point[i].x;
    goal.target_pose.pose.position.y =  way_point[i].y;
    goal.target_pose.pose.orientation.w = 1; 

    ROS_INFO("Sending goal: No.%d", i+1);
    // サーバーにgoalを送信
    ac.sendGoal(goal);

    // 結果が返ってくるまで30.0[s] 待つ。ここでブロックされる。
    bool succeeded = ac.waitForResult(ros::Duration(30.0));

    // 結果を見て、成功ならSucceeded、失敗ならFailedと表示
    actionlib::SimpleClientGoalState state = ac.getState();

    if(succeeded) {
      ROS_INFO("Succeeded: No.%d (%s)",i+1, state.toString().c_str());
    }
    else {
      ROS_INFO("Failed: No.%d (%s)",i+1, state.toString().c_str());
    }
    i++;
  }
  return 0;
}
  • packageのディレクトリ毎、圧縮したファイル
  • 展開・ビルド方法
    • $  cp  simple_goal.tgz    ~/catkin_ws/src/.
    • $  cd  ~/catkin_ws/src
    • $  tar  xvzf  simple_goal.tgz
    • $  cd  ~/catkin_ws
    • $  catkin_make

演習

  • 上で展開したsimple_goalを次の要領で実行しよう。
    • $ roslaunch turtlebot_gazebo turtlebot_world.launch
    • $ roslaunch turtlebot_gazebo amcl_demo.launch
    • $ rosrun simple_goal simple_goal
  • simple_goal.cppをベースに1周するプログラムを作ろう!

 

 

ロボットプログラミングⅡ:第7週 地図作成・自己位置推定(SLAM, AMCL)

$
0
0

rviz2この記事は私が担当している講義ロボットプログラミングⅡ用です。今回は地図作成(SLAM)と自己位置推定(AMCL)のパッケージを使いロボットにナビゲーションをさせましょう! 本記事を以下のチュートリアルを参考にしています。

1. 地図生成

(1) 端末を3つ開き以下のコマンドを実行する。

gazeboシミュレータを起動

  • $ roslaunch turtlebot_gazebo turtlebot_world.launch

地図生成のgmappingを起動

  • $ roslaunch turtlebot_gazebo gmapping_demo.launch

ROSのビジュアライションツールrvizを起動

  • $ roslaunch turtlebot_rviz_launchers view_navigation.launch

注:rvizがOpenGL関係のエラーで落ちる場合は、以下の1行を.bashrcの最後に付け加える。

  • export LIBGL_ALWAYS_SOFTWARE=1

(2) 端末を開き、以下のコマンドでロボットを動かし、地図を作る。

  • $ roslaunch turtlebot_teleop keyboard_teleop.launch

(3)  端末を開き、以下のコマンドで地図を保存する。mymapは保存する地図名なので適宜変更する。

  • $ mkdir  ~/maps
  • $ rosrun map_server map_saver -f  ~/maps/mymap

2. ナビゲーション

(1) 自己位置推定ノードの起動
上で作成した地図を使ってナビゲーションできるが、ここではすでに作られている地図を使う。

  • $ roslaunch turtlebot_gazebo amcl_demo.launch map_file:=/opt/ros/indigo/share/turtlebot_gazebo/maps/playground.yaml

(2) ロボット初期位置の設定
上図rvizの”2D Pose Estimation”をクリックして選択し、下図シミュレータのロボットの向きと位置が合うように、rviz上でロボットの位置と向きを設定する。ロボットの位置にマウスのカーソールを持って行き、ロボットの向きにドラッグすると設定終わり。

(3) ゴールの設定
次にrvizの”2D Nav Goal”をクリックして、初期位置を設定したのと同様に、ゴールの位置と向きを設定する。設定するとロボットが自動で動き出す。

gazebo終わり

ロボットプログラミングⅡ:第7週(2) ウェイポイントナビゲーション(ActionLib)

$
0
0

wp_navi2

この記事は私が担当している講義ロボットプログラミングⅡ用です。今回は第6週のプログラムを少し改良してウェイポイントナビゲーションのプログラムを作りましょう。これを応用するだけで、つくばチャレンジに出場できますよ。

ソース

 
// 本プログラムは
// http://wiki.ros.org/ja/navigation/Tutorials/SendingSimpleGoals
// を元に作成しています。
#include <ros/ros.h>
#include <move_base_msgs/MoveBaseAction.h>
#include <actionlib/client/simple_action_client.h>
#include <tf/transform_broadcaster.h>

typedef actionlib::SimpleActionClient<move_base_msgs::MoveBaseAction> MoveBaseClient;

struct MyPose {
  double x;
  double y;
  double yaw;
};

int main(int argc, char** argv){
  MyPose way_point[] = {
    {-2.0, 3.0,-0.5 * M_PI},
    { 3.0, 3.0, 0.0 * M_PI},
    { 3.0,-4.5, 0.5 * M_PI},
    { 0.0,-4.5, 1.0 * M_PI},
    { 0.0, 0.0, 0.0 * M_PI},
    {999, 999, 999}};

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

  // アクションクライアンを作成。1番目の引数は接続するアクションサーバー名。          
  // 2番目の引数はtrueならスレッドを自動的に回す(ros::spin()。                       
  MoveBaseClient ac("move_base", true);

  // アクションサーバーが起動するまで待つ。引数はタイムアウトする時間(秒)。          
  // この例では5秒間待つ(ブロックされる)                                             
  while(!ac.waitForServer(ros::Duration(5.0))){
      ROS_INFO("Waiting for the move_base action server to come up");
  }

  ROS_INFO("The server comes up");
  move_base_msgs::MoveBaseGoal goal;
  // map(地図)座標系(第6週のプログラムとの大きな変更点)                             
  goal.target_pose.header.frame_id = "map";
  // 現在時刻                                                                         
  goal.target_pose.header.stamp = ros::Time::now();


  int i = 0;
  while (ros::ok()) {
    // ROSではロボットの進行方向がx座標、左方向がy座標、上方向がz座標                 
    goal.target_pose.pose.position.x =  way_point[i].x;
    goal.target_pose.pose.position.y =  way_point[i].y;

    if (goal.target_pose.pose.position.x == 999) break;

    goal.target_pose.pose.orientation
      = tf::createQuaternionMsgFromYaw(way_point[i].yaw);

    ROS_INFO("Sending goal: No.%d", i+1);
    // サーバーにgoalを送信                                                           
    ac.sendGoal(goal);

    // 結果が返ってくるまで30.0[s] 待つ。ここでブロックされる。                       
    bool succeeded = ac.waitForResult(ros::Duration(60.0));

    // 結果を見て、成功ならSucceeded、失敗ならFailedと表示                            
    actionlib::SimpleClientGoalState state = ac.getState();
   
    if(succeeded) {
      ROS_INFO("Succeeded: No.%d (%s)",i+1, state.toString().c_str());
    }
    else {
      ROS_INFO("Failed: No.%d (%s)",i+1, state.toString().c_str());
    }
    i++;
  }
  return 0;
}
  • packageのディレクトリ毎、圧縮したファイル
  • 展開・ビルド方法
    • $ cp wp_navigation.tgz ~/catkin_ws/src/.
    • $ cd ~/catkin_ws/src
    • $ tar xvzf wp_navigation.tgz
    • $ cd ~/catkin_ws
    • $ catkin_make

演習

  • 上で展開したsimple_goalを次の要領で実行しよう。
    • $ roslaunch turtlebot_gazebo turtlebot_world.launch
    • $ roslaunch turtlebot_gazebo amcl_demo.launch map_file:=/opt/ros/indigo/share/turtlebot_gazebo/maps/playground.yaml
    • $ roslaunch turtlebot_rviz_launchers view_navigation.launch
    • $ rosrun wp_navigation wp_navigation

プチプロジェクト

  • もう少し規模の大きい建物内でのナビゲーションを考えましょう。以下のワールドファイルを使い、ロボットの初位置から右奥にあるポールまでウェイポイントナビゲーションをするプログラムをつくりましょう。
  • 準備
    • $ cd
    • $ mkdir  downloads
    • fmt_world.tgzをダウンロードして~/downloadsの中に保存。
    • $ cd downloads
    • $ tar xvzf fmt_world.tgz
    • $ cd fmt_world
    • $ sudo cp fmt_world.launch  /opt/ros/indigo/share/turtlebot_gazebo/launch
    • $ sudo cp fmt.world  /usr/share/gazebo-2.2/worlds
    • $ cp -r  fmt  ~/.gazebo/models
    • $ roslaunch turtlebot_gazebo  fmt_world.launch
  • 下のような建物とロボットが表示されたら終わり。右奥のボールがゴール。

fmt

ROS×Python勉強会:ウェイポイントナビゲーション(ActionLib:Python)

$
0
0

wp_navi2

この記事はROS×Python勉強会用です。今回はActionLibを使いウェイポイントナビゲーションのプログラムを作りましょう。これを応用するだけで、つくばチャレンジに出場できますよ。

ソース

 
#!/usr/bin/env python                                                            
# -*- coding: utf-8 -*-                                                          

import rospy
import tf
import actionlib
from actionlib_msgs.msg import *
from geometry_msgs.msg import Pose, PoseWithCovarianceStamped, Point, Quaternion\
, Twist
from move_base_msgs.msg import MoveBaseAction, MoveBaseGoal
from math import pi

class WpNavi():
    def __init__(self):  # コンストラクタ                                        
        # ノードの初期化                                                         
        rospy.init_node('wp_navi')

        # シャットダウン時の処理                                                 
        rospy.on_shutdown(self.shutdown)

        # アクションクライアントの生成                                           
        self.ac = actionlib.SimpleActionClient('move_base', MoveBaseAction)

        # アクションサーバーが起動するまで待つ。引数はタイムアウトの時間(秒)    
        while not self.ac.wait_for_server(rospy.Duration(5)):
            rospy.loginfo("Waiting for the move_base action server to come up")

        rospy.loginfo("The server comes up");

        # ゴールの生成                                                           
        self.goal = MoveBaseGoal()
    self.goal.target_pose.header.frame_id = 'map'         # 地図座標系       
	self.goal.target_pose.header.stamp = rospy.Time.now() # 現在時刻         

        way_point = [[-2.0, 3.0,-0.5 * pi], [ 3.0, 3.0, 0.0 * pi], [ 3.0,-4.5, 0\
.5 * pi],[ 0.0,-4.5, 1.0 * pi], [0.0, 0.0, 0.0 * pi], [999, 999, 999]]

        # メインループ。ウェイポイントを順番に通過                               
	i = 0
        while not rospy.is_shutdown():
            # ROSではロボットの進行方向がx座標、左方向がy座標、上方向がz座標     
            self.goal.target_pose.pose.position.x =  way_point[i][0]
            self.goal.target_pose.pose.position.y =  way_point[i][1]

  if way_point[i][0] == 999:
		break

            q = tf.transformations.quaternion_from_euler(0, 0, way_point[i][2])
            self.goal.target_pose.pose.orientation = Quaternion(q[0],q[1],q[2],q\
[3])
            rospy.loginfo("Sending goal: No" + str(i+1))

            # サーバーにgoalを送信                                               
            self.ac.send_goal(self.goal);

            # 結果が返ってくるまで30.0[s] 待つ。ここでブロックされる。           
            succeeded = self.ac.wait_for_result(rospy.Duration(30));
 # 結果を見て、成功ならSucceeded、失敗ならFailedと表示                
            state = self.ac.get_state();

	    if succeeded:
		rospy.loginfo("Succeeded: No."+str(i+1)+"("+str(state)+")")
            else:
                rospy.loginfo("Failed: No."+str(i+1)+"("+str(state)+")")

            i = i + 1

    def shutdown(self):
        rospy.loginfo("The robot was terminated")
	# ゴールをキャンセル                                                     
        self.ac.cancel_goal()

if __name__ == '__main__':
    try:
         WpNavi()
         rospy.spin()
    except rospy.ROSInterruptException:
         rospy.loginfo("WP navigation finished.")

演習

  • 上で展開したwp_navigationを次の要領で実行しよう。
    • $ roslaunch turtlebot_gazebo turtlebot_world.launch
    • $ roslaunch turtlebot_gazebo amcl_demo.launch map_file:=/opt/ros/indigo/share/turtlebot_gazebo/maps/playground.yaml
    • $ roslaunch turtlebot_rviz_launchers view_navigation.launch
    • $ rosrun wp_navigation wp_navigation.py

プチプロジェクト

  • もう少し規模の大きい建物内でのナビゲーションを考えましょう。以下のワールドファイルを使い、ロボットの初位置から右奥にあるポールまでウェイポイントナビゲーションをするプログラムをつくりましょう。
  • 準備
    • $ cd
    • $ mkdir downloads
    • fmt_world.tgzをダウンロードして~/downloadsの中に保存。
    • $ cd downloads
    • $ tar xvzf fmt_world.tgz
    • $ cd fmt_world
    • $ sudo cp fmt_world.launch /opt/ros/indigo/share/turtlebot_gazebo/launch
    • $ sudo cp fmt.world /usr/share/gazebo-2.2/worlds
    • $ cp -r fmt ~/.gazebo/models
    • $ roslaunch turtlebot_gazebo fmt_world.launch

Turtlebotでの地図生成・保存・ナビゲーションコマンド

$
0
0

TurtlebotでROSのパッケージを使った地図生成・保存・ナビゲーションコマンド

地図生成
1. roslaunch turtlebot_bringup minimal.launch
2. rqt -s kobuki_dashboard
3. roslaunch turtlebot_bringup 3dsensor.launch
4. roslaunch turtlebot_teleop ps3_teleop.launch
5. roslaunch turtlebot_navigation gmapping_demo.launch
6. roslaunch turtlebot_rviz_launchers view_navigation.launch

地図保存
rosrun map_server map_saver -f ~/map/mymap

ウェイポイント・ナビゲ―ション
このウェブサイトのサンプルプログラム使用例(6のコマンド)
1. roslaunch turtlebot_bringup minimal.launch
2. rqt -s kobuki_dashboard
3. roslaunch turtlebot_bringup 3dsensor.launch
4. roslaunch turtlebot_navigation amcl_demo.launch map_file:=/home/demulab/map/fmt2.yaml
5. roslaunch turtlebot_rviz_launchers view_navigation.launch –screen
6. サンプルプログラム
C++: ここを参照
rosrun wp_navigation wp_navigation
Python:ここを参照
rosrun wp_navigation wp_navigation.py


ROS IndigoでRealSense R200

$
0
0

realsense

ROS Indigo (Ubuntu14.04)でIntel RealSense R200を動かしたときの簡単なメモ。バイナリがないのでソースからインストール。院生に教えてもらったが少しはまる。RealSense R200はxtionと比較してもとても小さく、軽量、安価。

  • RealSense – ROS Wikiがソース。少々わかりづらい。RealSenseドライバをインストールするときは、Ubntu14.04の場合patchをあてるスクリプトpatch_ubuntu_uvc.shを行ってからインストールのスクリプト~/src/RealSense_ROS/r200_install/install.shを実行。
  • RealSenseドライバのインストール
    • sudo apt-get update
    • cd
    • mkdir src
    • cd src
    • git clone https://github.com/PercATI/RealSense_ROS.git
    • cd ~/src/RealSense_ROS/r200_install/ds_uvcdriver/scripts
    • chmod u+x patch_ubuntu_uvc.sh
    • sudo ./patch_ubuntu_uvc.sh
    • cd  ~/src/RealSense_ROS/r200_install
    • sudo ./install.sh
    • cd ~/src/RealSense_ROS/r200_install/ds_connectivity_workaround
    • chmod u+x install_rules.sh
    • sudo ./install_rules.sh
  • R200ノードレットのインストール
    • cd ~/src/RealSense_ROS/realsense_dist/2.3
    • sudo ./install_realsense_ros.sh
      エラーが出る場合は以下を実行して下の図のようrに$ROS_DISTROをindigoに変更してやり直す。
      $ gedit install_realsense_ros.shr200
  • R200ノードレットの実行
    • roslaunch  realsense  realsense_r200_launch.launch
    • rosrun rviz rviz
      • file->open configで以下のファイルを開くと上の画像open~/src/RealSense_ROS/realsense_dist/2.3/realsenseRvizConfig.rviz

終わり

Xtion Pro LiveをUSB3.0とROS Indigoで使うメモ

$
0
0

xtion

 

Xtion Pro LiveをUSB3.0しかないパソコンで、Ubuntu 14.04 + ROS Indigo環境で使用するためのメモ。

  • Xtion Pro Liveのファームウェアをアップグレードする。詳しい方法は以下のウェブサイトを参照。なお、ファームウェアのアップグレードはWindowsを使いUSB2.0のポートを使う。Windows用のドライバはXtion Pro Live付属のCD-ROMを使用した。
  • Ubuntu14.04を立ち上げ、XtionをUSB3.0のポートに接続する。
  • ROS IndigoのOpenNI2を使用する。以下のコマンドで必要なパッケージをインストールする。
    • $ sudo apt-get install ros-indigo-rgbd-launch ros-indigo-openni2-camera ros-indigo-openni2-launch
  • Viewer関連のパッケージをインストールする。
    • $ sudo apt-get install ros-indigo-rqt ros-indigo-rqt-common-plugins ros-indigo-rqt-robot-plugins
  • ROSの必要なラウンチファイルを起動する。
    • $ roslaunch openni2_launch openni2.launch
  • rqtを起動する。rqtはGUI開発のフレームワーク。詳細はここを参照。
    • $ rqt
      • rqtでImage Viewを表示する方法。rqtのメニューバーで次のように指定する。
      • Plugins -> Visualization -> Image View
      • depthセンサの表示 /camera/depth/image
      • irセンサの表示 /camera/ir/image
      • rgbセンサの表示 /camera/rgb/image_raw

なお、OpenNI2に関する記述は以下のサイトを参考にした。

ROS×Python勉強会: cv_bridge

$
0
0

opencv

この記事はROS×Python勉強会用です。今回はcv_bridgeを使い、ROSでOpenCVを使いxtionのカメラから取得した画像を処理します。
この記事は、以下のROSチュートリアルと「ROSで始めるロボットプログラミング、小倉著」を参考にしています。

ソース:ROSのチュートリアルと「ROSで始めるロボットプログラミング」をベースに改変しています。

 
#!/usr/bin/env python                                                                        
# -*- coding: utf-8 -*-                                                                      

import roslib
roslib.load_manifest('cv_bridge_tutorial')
import sys
import rospy
import cv2
import numpy as np
from std_msgs.msg import String
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError

class image_converter:
  def __init__(self):
    self.image_pub = rospy.Publisher("image_topic", Image, queue_size=1)
    self.bridge = CvBridge()
    self.image_sub = rospy.Subscriber("/camera/rgb/image_raw",Image,self.callback)

  def callback(self,data):
    try:
      cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
    except CvBridgeError as e:
      print(e)

    # RGB表色系からHSV表色系に変換                                                           
    hsv_image = cv2.cvtColor(cv_image, cv2.COLOR_BGR2HSV)

    # しきい値の設定(ここでは赤を抽出)                                                     
    color_min = np.array([150,100,150])
    color_max = np.array([180,255,255])

    # マスク画像を生成                                                                       
    color_mask = cv2.inRange(hsv_image, color_min, color_max);
    # 画像配列のビット毎の倫理席。マスク画像だけが抽出される。                               
    cv_image2  = cv2.bitwise_and(cv_image, cv_image, mask = color_mask)

    # RGBからグレースケールへ変換                                                            
    gray_image = cv2.cvtColor(cv_image, cv2.COLOR_BGR2GRAY)
    cv_image3  = cv2.Canny(gray_image, 15.0, 30.0);

 # 円を描画                                                                               
    color  = (0, 255, 0)
    center = (100, 100)
    radius = 20
    cv2.circle(cv_image2, center, radius, color)

    # ウインドウのサイズを変更                                                               
    cv_half_image = cv2.resize(cv_image,   (0,0),fx=0.5, fy=0.5)
    cv_half_image2 = cv2.resize(cv_image2, (0,0),fx=0.5,fy=0.5);
    cv_half_image3 = cv2.resize(cv_image3, (0,0),fx=0.5,fy=0.5);

    # ウインドウ表示                                                                         
    cv2.imshow("Origin Image", cv_half_image)
    cv2.imshow("Result Image", cv_half_image2)
    cv2.imshow("Edge Image",   cv_half_image3)
    cv2.waitKey(3)
   
    try:
      self.image_pub.publish(self.bridge.cv2_to_imgmsg(cv_image2, "bgr8"))
    except CvBridgeError as e:
      print(e)

def main(args):
  ic = image_converter()
  rospy.init_node('image_converter', anonymous=True)
  try:
    rospy.spin()
  except KeyboardInterrupt:
    print("Shutting down")
  cv2.destroyAllWindows()

if __name__ == '__main__':
    main(sys.argv)

準備

  • $ cd ~/catkin_ws/src
  • $ catkin_create_pkg  cv_bridge_tutorial sensor_msgs opencv2 cv_bridge rospy std_msgs
  • $ cd cv_bridge_tutorial
  • $ mkdir  scripts
  • $ cd scripts
  • $ gedit cv_bridge_tutorial.py
    上のソースコードをgeditにコピペして保存する。
  • $ chmod u+x cv_bridge_tutorial.py

実行方法

  • $ roslaunch openni2_launch openni2.launch
  • $ rosrun cv_bridge_tutorial  cv_bridge_tutorial.py

終わり

ロボットプログラミングⅡ:第8週 GAZEBOで画像処理(cv_bridge)

$
0
0


coke_can

この記事は私が担当している講義ロボットプログラミングⅡ用です。今回はcv_bridgeを使います。ROSでOpenCVを使いgazeboシミュレータのRGB-Dセンサから取得した画像を処理します。赤色の抽出とエッジ抽出を行います。

この記事は、以下のROSチュートリアルと「ROSで始めるロボットプログラミング、小倉著」を参考にしています。

ソース:ROSのチュートリアルと「ROSで始めるロボットプログラミング」をベースに改変しています。

 
#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

static const std::string OPENCV_WINDOW = "Image window";

class ImageConverter
{
  ros::NodeHandle nh_;
  image_transport::ImageTransport it_;
  image_transport::Subscriber image_sub_;
  image_transport::Publisher image_pub_;

public:
  // コンストラクタ
 ImageConverter()
    : it_(nh_)
  {
    // カラー画像をサブスクライブ                                                                
    image_sub_ = it_.subscribe("/camera/rgb/image_raw", 1,
      &ImageConverter::imageCb, this);
    // 処理した画像をパブリッシュ                                                                                          
    image_pub_ = it_.advertise("/image_topic", 1);
 }

  // デストラクタ
  ~ImageConverter()
  {
    cv::destroyWindow(OPENCV_WINDOW);
  }

  // コールバック関数
  void imageCb(const sensor_msgs::ImageConstPtr& msg)
  {
    cv_bridge::CvImagePtr cv_ptr, cv_ptr2, cv_ptr3;
 try
    {
      // ROSからOpenCVの形式にtoCvCopy()で変換。cv_ptr->imageがcv::Matフォーマット。
      cv_ptr    = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
      cv_ptr3   = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::MONO8);
    }
    catch (cv_bridge::Exception& e)
    {
      ROS_ERROR("cv_bridge exception: %s", e.what());
      return;
    }

    cv::Mat hsv_image, color_mask, gray_image, cv_image2, cv_image3;
    // RGB表色系をHSV表色系へ変換して、hsv_imageに格納
    cv::cvtColor(cv_ptr->image, hsv_image, CV_BGR2HSV);

    // 色相(Hue), 彩度(Saturation), 明暗(Value, brightness) 
    // 指定した範囲の色でマスク画像color_mask(CV_8U:符号なし8ビット整数)を生成  
    // マスク画像は指定した範囲の色に該当する要素は255(8ビットすべて1)、それ以外は0                                                      
    cv::inRange(hsv_image, cv::Scalar(150, 100, 50, 0) , cv::Scalar(180, 255, 255, 0), color_mask);
    // ビット毎の論理積。マスク画像は指定した範囲以外は0で、指定範囲の要素は255なので、ビット毎の論理積を適用すると、指定した範囲の色に対応する要素はそのままで、他は0になる。
    cv::bitwise_and(cv_ptr->image, cv_ptr->image, cv_image2, color_mask);
    // グレースケールに変換
    cv::cvtColor(cv_ptr->image, gray_image, CV_BGR2GRAY);
    // エッジを検出するためにCannyアルゴリズムを適用
    cv::Canny(gray_image, cv_ptr3->image, 15.0, 30.0, 3);

    // ウインドウに円を描画                                                
    cv::circle(cv_ptr->image, cv::Point(100, 100), 20, CV_RGB(0,255,0));

    // 画像サイズは縦横半分に変更
    cv::Mat cv_half_image, cv_half_image2, cv_half_image3;
    cv::resize(cv_ptr->image, cv_half_image,cv::Size(),0.5,0.5);
    cv::resize(cv_image2, cv_half_image2,cv::Size(),0.5,0.5);
    cv::resize(cv_ptr3->image, cv_half_image3,cv::Size(),0.5,0.5);

    // ウインドウ表示                                                                         
    cv::imshow("Original Image", cv_half_image);
    cv::imshow("Result Image", cv_half_image2);
    cv::imshow("Edge Image", cv_half_image3);
    cv::waitKey(3);
 
    // エッジ画像をパブリッシュ。OpenCVからROS形式にtoImageMsg()で変換。                                                            
    image_pub_.publish(cv_ptr3->toImageMsg());
  }
};

int main(int argc, char** argv)
{
  ros::init(argc, argv, "image_converter");
  ImageConverter ic;
  ros::spin();
  return 0;
}

準備

  • $ cd ~/catkin_ws/src
  • $ catkin_create_pkg cv_bridge_tutorial sensor_msgs opencv2 cv_bridge roscpp std_msgs
  • $ cd cv_bridge_tutorial/src
  • $ gedit cv_bridge_tutorial.cpp
    上のソースコードをgeditにコピペして保存する。
  • $ cd ~/cakin_ws
  • $ catkin_make

簡単な準備:時間のない方は以下で準備してください。CMakeLists.txtやPackage.xmlを編集する必要がありません。

  • 以下のファイルを~/catkin_ws/srcの下にコピーする
  • $ cd ~/catkin_ws/src
  • $ tar xvzf cv_bridge_tutorial.tgz
  • $ cd ~/catkin_ws
  • $ catkin_make

実行方法

  • $ roslaunch turtlebot_gazebo turtlebot_world.launch
  • $ rosrun cv_bridge_tutorial cv_bridge_tutorial
  • 次のコマンドでロボットを動かしてカメラ画像が変わるのを確認しよう
    • $ roslaunch turtlebot_teleop keyboard_teleop.launch

演 習

  • シミュレータにコカ・コーラの缶(Coke Can)を挿入して、それを追うプログラムを作ろう

終わり

ROSのOpenCVではまる

$
0
0

ROS Indigoでcatkin_makeしたときに以下のエラーではまったのでメモ

CMake Error at /opt/ros/indigo/share/catkin/cmake/catkinConfig.cmake:75 (find_package):
Could not find a package configuration file provided by “OpenCV” with any
of the following names:

OpenCVConfig.cmake
opencv-config.cmake

Add the installation prefix of “OpenCV” to CMAKE_PREFIX_PATH or set
“OpenCV_DIR” to a directory containing one of the above files. If “OpenCV”
provides a separate development package or SDK, be sure it has been
installed.

解決した手順

1.OpenCVをインストール

  • $ sudo apt-get install ros-indigo-vision-opencv libopencv-dev python-opencv
  • $ rospack profile

2.CMakeLists.txtに以下を追加

  • find_package(OpenCV REQUIRED)
  • include_directories(/usr/local/include ${catkin_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} ${PCL_INCLUDE_DIRS} )
  • target_link_libraries(dfollow ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES})

3. package.xmlに以下を追加

  • <build_depend>opencv2</build_depend>
  • <run_depend>opencv2</run_depend>

以上

Viewing all 757 articles
Browse latest View live