More Related Content
Similar to ROSチュートリアル ROBOMECH2018
Similar to ROSチュートリアル ROBOMECH2018 (20)
More from Ryuichi Ueda (20)
ROSチュートリアル ROBOMECH2018
- 8. テスト
• 一般的に
終了ステータスを利用
– プログラムを実行後、
echo $?で調査
• Pythonの場合
– sys.exit
• sys.exit(0): 正常
• sys.exit(0でない数字):
何らかの異常
– モジュールの場合、
if __name__ ...
の下に書くことが可能
2018年6月3日 ROS講習会@ROBOMECH2018 8
#!/usr/bin/env python
def plus(a,b):
return a + b
if __name__ =='__main__':
importsys
ifplus(1,2) !=3:
sys.exit(1)
ifplus(1.1,2.2) <3.299999 orplus(1.1,2.2) > 3.300001:
sys.exit(2)
ifplus("abc","def") !="abcdef":
sys.exit(3)
sys.exit(0)
- 9. unittestを使う
• unittest: Pythonのユニットテストフレームワーク
2018年6月3日 ROS講習会@ROBOMECH2018 9
#!/usr/bin/envpython
importunittest
fromplusimportplus
classTestPlus(unittest.TestCase): # unittestクラスからTestPlusを派生
deftest_int(self): #テスト用のメソッドはtest_...と書く
self.assertEqual(plus(1,2),3,"erroron int")
deftest_float(self):
self.assertTrue(3.299999<plus(1.1,2.2)<3.300001,"erroronfloat")
deftest_str(self):
self.assertEqual(plus("ab","cd"),"abcd", "erroronstr")
unittest.main() #unittestのmainメソッドを呼ぶ
- 10. unittestの出力
• 右: テストにパス
• 下: エラー
2018年6月3日 ROS講習会@ROBOMECH2018 10
ueda@remote:~/tmp$./test_plus.py
...
--------------------------------------------Ran 3testsin0.000s
OK
ueda@remote:~/tmp$./test_plus.py
..F
======================================================================
FAIL:test_str(__main__.TestPlus)
----------------------------------------------------------------------
Traceback(mostrecentcall last):
File "./test_plus.py",line15, in test_str
self.assertEqual(plus("a","cd"),"abcd", "erroron str")
AssertionError:erroronstr
----------------------------------------------------------------------
Ran3testsin 0.000s
FAILED(failures=1)
ueda@remote:~/tmp$echo $?
1 #終了ステータスでも成否がわかるようになっている(自動化のため)
- 11. GitHub + Travis CI
• CI(continuous integration、継続的インテグレーション)サービス
– コードを常に改善しながらシステムに反映するためのもの
– 機能: コードをテストしてから本番投入(デプロイ)
– 今回はTravis CIを使います
• 他の方が良いかもしれませんが今回はこれで
• GitHubへコードを公開するとテストが走るように設定
2018年6月3日 ROS講習会@ROBOMECH2018 11
- 12. 今のテストをTravis CI上で実行
• まず、GitHubにリポジトリを作る
– テストのテストリポジトリなので「testtest」としましょう
– 今までラズパイで書いたコードをtesttestディレクトリに置く
• Plus.py, main.py, test_plus.py
– GitHubにプッシュ
• 次のページのように操作
– Travis CIと連携
• 次々ページのように操作
2018年6月3日 ROS講習会@ROBOMECH2018 12
- 13. GitHubの操作
2018年6月3日 ROS講習会@ROBOMECH2018 13
ueda@remote:~/tmp/testtest$ git init #ローカルリポジトリ初期化
Initialized empty Git repository in /home/ueda/tmp/testtest/.git/
ueda@remote:~/tmp/testtest$ git add-A #ステージング
ueda@remote:~/tmp/testtest$ git commit -m “Addfiles” #コミット
[master (root-commit) 8f04172] Addfiles
3 files changed, 40 insertions(+)
create mode 100755 main.py
create mode 100755 plus.py
create mode 100755 test_plus.py
ueda@remote:~/tmp/testtest$ git remote add origin #次の行も続けて
https://github.com/ユーザ名/testtest
ueda@remote:~/tmp/testtest$ git push originmaster #プッシュ
(略。IDとパスワードを聞かれる。)
*[new branch] master -> master
- 14. Travis CIの設定
• Sign in with GitHubを押してサインイン
• 右上のユーザのアイコンを押してProfileに行く
• 「testtest」のスイッチをONに
• リポジトリに.travis.ymlというファイルを置く
– 中身は次の1行
• push
2018年6月3日 ROS講習会@ROBOMECH2018 14
ueda@remote:~/tmp/testtest$ git add -A
ueda@remote:~/tmp/testtest$ git commit -m"Add .travis.yml"
(略)
ueda@remote:~/tmp/testtest$ git push origin master
(略)
8f04172..6646392 master ->master
script: ./test_plus.py
- 16. GitHub上にテスト結果を表示
• Travis CIの「build passing」と書いたアイコンを押す
• Markdownを選択して下のコードをコピー
• コピーしたコードを
README.mdにコピー
– README.mdは
リポジトリのディレクトリ
直下に作成しましょう
• GitHubのリポジトリにテストの
合否が表示される
2018年6月3日 ROS講習会@ROBOMECH2018 16
- 20. ロボットの動作確認(デバイスドライバ)
• デバイスドライバのセット
• デバイスドライバの動作確認
2018年6月3日 ROS講習会@ROBOMECH2018 20
ubuntu@ubuntu:~$cd ~/RaspberryPiMouse/src/drivers/
ubuntu@ubuntu:~/RaspberryPiMouse/src/drivers$sudo insmod
###距離センサ###
ubuntu@ubuntu:~$cat /dev/rtlightsensor0
211292312
###モータ###
ubuntu@ubuntu:~$echo 5005001000> /dev/rtmotor0
- 21. ロボットの動作確認(ROS)
• ビルド
• 起動
• 「トピック」を使ってセンサ値を読み出し
2018年6月3日 ROS講習会@ROBOMECH2018 21
ubuntu@ubuntu:~/catkin_ws$sudo apt install ros-kinetic-tf
ubuntu@ubuntu:~/catkin_ws$sudo apt install ros-kinetic-tf2-ros
ubuntu@ubuntu:~$cd ~/catkin_ws/
ubuntu@ubuntu:~/catkin_ws$catkin_make
ubuntu@ubuntu:~/catkin_ws$source ~/.bashrc
ubuntu@ubuntu:~/catkin_ws$roslaunch raspimouse_ros_2 raspimouse.launch
ubuntu@ubuntu:~$ rostopic echo /lightsensors
right_forward:0
right_side: 0
left_side: 0
...
- 22. ロボットの動作確認(ROS, 続き)
• 「サービス」、「トピック」を使ってモータを動かす
2018年6月3日 ROS講習会@ROBOMECH2018 22
ubuntu@ubuntu:~$ rosservice call /motor_on
success: True
message: "ON"
ubuntu@ubuntu:~$ rostopic pub/cmd_vel geometry_msgs/Twist "linear:
x:0.2
y:0.0
z:0.0
angular:
x:0.0
y:0.0
z:0.0"
publishing andlatching message. Press ctrl-C to terminate
^Cubuntu@ubuntu:~$ #Ctrl+Cで止める(1秒後にモータ停止)
ubuntu@ubuntu:~$ rosservice call /motor_off
success: True
message: "OFF"
- 24. ロボットのテスト
• なるべくロボットを動かさずに入出力を確認
• デバイスドライバに値を書き込むと読めないので
普通のファイルに置き換えてテスト
2018年6月3日 ROS講習会@ROBOMECH2018 24
###こいつらを普通のファイルに置き換え###
ubuntu@ubuntu:~$ ls /dev/rt*
/dev/rtbuzzer0 /dev/rtled0 /dev/rtlightsensor0 /dev/rtmotoren0
/dev/rtcounter0 /dev/rtled1 /dev/rtmotor0 /dev/rtswitch0
/dev/rtcounter_l0 /dev/rtled2 /dev/rtmotor_raw_l0 /dev/rtswitch1
/dev/rtcounter_r0 /dev/rtled3 /dev/rtmotor_raw_r0 /dev/rtswitch2
###再起動すると消えます###
ubuntu@ubuntu:~$ reboot
- 26. ROSを使ったテスト
• まず、一通りダミーファイルを作る
2018年6月3日 ROS講習会@ROBOMECH2018 26
### スクリプトがパッケージに準備されてます ###
ubuntu@ubuntu:~/catkin_ws/src/raspimouse_ros_2$ cat test/travis_prepare_dummy_files.bash
#!/bin/bash -xve
sudo touch /dev/rt{buzzer,motor,motoren,motor_raw_{l,r}}0
sudo chmod 666/dev/rt{buzzer,motor,motoren,motor_raw_{l,r}}0
echo "0000" | sudo tee /dev/rtlightsensor0
sudo chmod 666/dev/rtlightsensor0
echo "0"| sudo tee /dev/rtswitch{0,1,2}
sudo chmod 666/dev/rtswitch{0,1,2}
### 実行 ###
ubuntu@ubuntu:~/catkin_ws/src/raspimouse_ros_2$ ./test/travis_prepare_dummy_files.bash
- 27. テストスクリプト
• 例: パッケージのtest/travis_test_lightsensors.py
• コードの主要な部分
– Lightsensorsトピックにデータを送るオブジェクト
(サブスクライバ)を作成
– Unittestのassert...を利用している部分
2018年6月3日 ROS講習会@ROBOMECH2018 27
9 def setUp(self):
10 self.count =0
11 rospy.Subscriber('/lightsensors', LightSensorValues, self.callback)
12 self.values =LightSensorValues()
18 def check_values(self,lf,ls,rs,rf):
19 vs =self.values
20 self.assertEqual(vs.left_forward, lf,“different value: left_forward”)# unittestのasserEqualを利用
21 ...
- 28. テストスクリプト(続き)
– テストを実行するメソッド
2018年6月3日 ROS講習会@ROBOMECH2018 28
31 def test_get_value(self):
32 (略)
33 (略)
34 with open(“/dev/rtlightsensor0”,“w”) asf:#ダミーの値の書込
35 f.write("-1 0 123 4321n")
36
37 time.sleep(3)
38 ###コールバック関数が最低1回は呼ばれ、値が取得できているかを確認###
39 self.assertFalse(self.count ==0,“cannot ...
40 self.check_values(4321,123,0,-1) #値の確認
- 29. ROSでのテストの実行
• launchファイル
– ノードを一斉に立ち上げるための設定を書いたファイル
– パッケージのlaunchディレクトリにはロボットを動作させる
ためのlaunchファイルとテスト用のlaunchファイルが存在
• 特に分ける必要はないが事情により
2018年6月3日 ROS講習会@ROBOMECH2018 29
ubuntu@ubuntu:~/catkin_ws/src/raspimouse_ros_2$ ls launch/
raspimouse.launch test.launch
ubuntu@ubuntu:~/catkin_ws/src/raspimouse_ros_2$ cat launch/test.launch
<launch>
<node pkg="raspimouse_ros_2" name="buzzer" type="buzzer.py" required="true" />
(略)
<test test-name="test_buzzer" pkg="raspimouse_ros_2"
(略)
</launch>
- 30. ROSでのテストの実行(続き)
2018年6月3日 ROS講習会@ROBOMECH2018 30
ubuntu@ubuntu:~$ rostest raspimouse_ros_2 test.launch
...
[ROSTEST]-----------------------------------------------------------------------
(略)
[raspimouse_ros_2.rosunit-test_motors/test_put_freq][passed]
[raspimouse_ros_2.rosunit-test_motors/test_put_value_timed][passed]
SUMMARY
*RESULT: SUCCESS
*TESTS: 11
*ERRORS: 0
*FAILURES: 0
rostest log fileis in /home/ubuntu/.ros/log/rostest-ubuntu-5841.log
- 31. Travis CIでのテスト
• 毎回ROSをセットアップしてからテスト
– Dockerで手間を減らせそうですが試してません
– 下図: パッケージ内の.travis.yml
2018年6月3日 ROS講習会@ROBOMECH2018 31
1 sudo: required
2 dist: trusty
3 install:
4 - bash -xve ./test/travis_ros_install.bash
5 - source ~/catkin_ws/devel/setup.bash
6 before_script:
7 - bash -xve ./test/travis_package_make.bash
8 - source ~/catkin_ws/devel/setup.bash
9 - bash -xve ./test/travis_prepare_dummy_files.bash
10 script:
11 - rostest raspimouse_ros_2 test.launch
- 34. 参考資料
• ROS Wiki
– http://wiki.ros.org/action/show/Quality/Tutorials/UnitTesting
– http://wiki.ros.org/CIs
• 上田: Raspberry Piで学ぶ ROSロボット入門, 日経BP,
2017
– テストを扱ってます
2018年6月3日 ROS講習会@ROBOMECH2018 34