読者です 読者をやめる 読者になる 読者になる

空飛ぶロボットのつくりかた

ロボットをつくるために必要な技術をまとめます。ロボットの未来についても考えたりします。

rosのCMakeListsのお勉強

T・B・D

install

install(DIRECTORY launch/
  DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch
  FILES_MATCHING PATTERN "*.launch"

)
  • .launchだけをコピー
install(DIRECTORY launch/
  DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch
  PATTERN ".svn" EXCLUDE)
  • .svnを除き、それ以外をコピー

mockテストのお勉強

Python Test

mock.return_value

  • 返り値を指定できる

mock.called

mock.call_count

  • 何回呼ばれたか確認できる

mock.call_args

mock.call_args_list

  • 引数のリストがわかる

mock.side_effect

  • いろんなものが指定できる

例えば(イテレート)

side_effect = chain([1,2,3,4])

mock.method_calls

mock.mock_calls

  • mock_calls は、メソッド,特殊メソッド,戻り値のモックまで、モックオブジェクトに対するすべての呼び出しを記録する

mock.assert_called

mock.assert_called_once

mock.assert_called_with

mock.assert_called_once_with

mock.assert_any_call

assert_has_calls

参考:

26.5. unittest.mock — モックオブジェクトライブラリ — Python 3.6.1 ドキュメント

パッチデコレータ

@patch

参考:

Pythonのテストコードでmockを使ってみた | Developers.IO

mock(Pyhtonモックライブラリ)についてのメモ - Qiita

Pythonのデバッグとテストモジュール - Qiita

Pythonで学ぶ 基礎からのプログラミング入門 (34) Pythonのテスト手法 | マイナビニュース

ユニットテスト

# @raises 例外のテスト
@raises(Error)
def test_invalid_arg():
    actual = add(None, 1)

参考:

Python nose でユニットテストを書いてみた / 桃缶食べたい。

rospyのお勉強

Python ROS

rospy.get_param

  • パラメータサーバーから値をとってくる
rospy.get_param(param_name, default)

参考: rospy/Overview/Parameter Server - ROS Wiki

rospy.Time

  • rate,sleep,durationなどよく使うものが多い
  • rospy.Timer(period, callback, oneshot=False)
    • periodで指定した周期で定期的にcallbackが呼ばれる

参考:

rospy/Overview/Time - ROS Wiki

rospy.wait_for_message(topic, topic_type, timeout)

  • トピックを一回だけサブする関数

rospy.ROSInterruptException

  • KeyboardInterruptなどInterruptの操作のException

pythonモジュールとパッケージ

参考:

Python: モジュールとパッケージ - CUBE SUGAR CONTAINER

Python: モジュールとパッケージ - CUBE SUGAR CONTAINER

Python/setup.pyによるインストール - Glamenv-Septzen.net

Python入門 - パッケージとモジュール

[http://samurait.hatenablog.com/entry/init.py%E3%81%AE%E5%BD%B9%E5%89%B2:title]

pythonのお勉強

Python

引数

可変引数
  • *のときタプルになる
>>> def func(*hoge):
...   print hoge
...
>>> func("1","2","3")
('1', '2', '3')
  • **のとき辞書型になる
>>> def func(**hoge):
...   print hoge
...
>>> func(a=1,b=2,c=3)
{'a': 1, 'c': 3, 'b': 2}
>>>

イテレータ

参考;

10.1. itertools — 効率的なループ実行のためのイテレータ生成関数 — Python 3.6.1 ドキュメント

スコープ

参考:

RubyプログラマがPythonを学び始めて知ったこと10選 ④ - donghai821の日記

Pythonのクラスメンバのスコープまとめ - Qiita

Pythonメモ: privateやprotectedは

pythonにprivate変数がない件:千里の道も一歩から:So-netブログ

Python - Pythonの変数やメソッドの命名について(アンダーバー)(41277)|teratail

ソケット通信

  • connect : サーバーに接続
  • send : データ送信
  • sendall : すべて送りきるまで終わらない
  • settimeout : タイムアウト値を設定する
  • recv : データ受信
  • socket.timeout : exception OSErrorのサブクラス
  • socket.error : exception OSErrorの非推奨のエイリアス

参考:

Pythonのソケット通信 - Your life is beautiful...

Pythonでネットワークプログラミング | saito's memo

python - What is the difference between socket.send() and socket.sendall()? - Stack Overflow

Pythonでソケットタイムアウト値の設定と取得 - 珠玉の誤訳

18.1. socket — 低水準ネットワークインターフェース — Python 3.6.1 ドキュメント

スレッド

参考:

スレッド - Python入門から応用までの学習サイト

Pythonでマルチスレッド処理 - Qiita

クラス継承

参考:

[Python]クラス継承(super) - Qiita

Pythonの super() 関数の使い方 - Life with Python

その他

  • struct.pack(“i”,data) : int型でdataをパックする
  • unicode() : unicodeへ変換
  • .split() : 単語を分割してリストへ
  • ~[-1] : リストの最後のもの
  • ~[0:-1] : リストの最初から最後から一つ手前まで
  • .append : リストの最後に追加
  • time.sleep : ~s待つ
  • .first()
  • .join() : 連結して一つの文字にする
  • .items() : 辞書をリストに変換
  • continue : 現在のループを終了して次のループへ

参考:

pythonのstructモジュールを触ってみる | KentaKomai Blog

Unicode文字列(ユニコード文字列) - 文字列 - Python入門

文字列の分割・結合 split, join,rsplit | Python Snippets

要素の追加と連結(appendメソッド, extendメソッド) - リスト - Python入門

http://www.yukun.info/blog/2008/09/python-file-write-writelines.html

python - What is the difference between .one() and .first() - Stack Overflow

キーと値のリストを取得(keysメソッド, valuesメソッド, itemsメソッド) - 辞書 - Python入門

Pythonでスリープを使う time.sleep() - 何でも屋さんの備忘録

Pythonによる通信処理 - Qiita

Pythonのコードをきれいに書くためのTips | TRIVIAL TECHNOLOGIES 4 @ats のイクメン日記

continue - Python入門から応用までの学習サイト

スクリプト言語コンパイル言語の違い

参考:

【みんな知ってる?】スクリプト言語とコンパイル言語の違いとは?

はじめに | 学生のためのPython講座

lint

https://www.pylint.org

http://qiita.com/betweens/items/1b10b870538d90b07cef

http://qiita.com/kiyotaman/items/7749e4998e0bdcc61199

http://pylint-messages.wikidot.com/all-codes

*args **kwargs

*args **kwargsの意味

rosでテストを書いてみる

ROS Test

unittest

CMakeLists.txt

if(CATKIN_ENABLE_TESTING)
  find_package(rostest REQUIRED)
  add_rostest(test/mytest.test)
endif()

package.xml

<test_depend>rostest</test_depend>
<test_depend>python-nose</test_depend>

↑テストにnoseをつかう場合

mytest.test

<launch>
  <node pkg="mypkg" type="mynode" name="mynode" />
  <test test-name="test_mynode" pkg="mypkg" type="test_mynode.py" />
</launch>

test_mynode.py

#!/usr/bin/env python

from nose.tools import eq_, raises

import unittest
import rostest, rospy

from mypkg.mytest import MyTest


class TestMyTest(unittest.TestCase):
    def setUp(self):
        pass

    @raises(rospy.ROSException)
    def test_mytest1(self):
        instance = MyTest()
        
    def test_mytest2(self):
        eq_(10 / 5, 2)

if __name__ == '__main__':
    rospy.init_node('test_sample')
    rostest.rosrun('mypkg',
                   'test_sample',
                   TestMyTest)

実行

$rostest test_rospy/test/mytest.test

参考:

ROS勉強記録: catkinでのpythonのtestについて

ROS C++コード用テストライブラリgtestの使い方(日本語訳) - MyEnigma

rostest - ROS Wiki

rostest - Minimum Working Example - ROS Answers: Open Source Q&A Forum

nose まとめ 1 - kuma8の日記

noseで気軽にテストを書く(+geventの場合) - Qiita

Pythonのデコレータについて - Qiita

ROSにおけるUnit/Integration/Regression Test (日本語訳) - MyEnigma

「rostest」 の使い方 - うごくものづくりのために

google test のインストールでハマったのでメモ - Qiita

pythonのテストを書いてみる

Python Test

unittest

Robot and Animal

roboani.py

class Robot:
    def get_name(self):
        return "robot"
    def get_legs(self):
        return 2

class Animal:
    def get_name(self):
        return "animal"
    def get_legs(self):
        return 4

def calc_roboani_legs(robot,animal,heads,legs):
    robo_l = robot.get_legs()
    ani_l = animal.get_legs()
    robot_name = robot.get_name()
    animal_name = animal.get_name()
    animal_num = (legs - (robo_l*heads)) // (ani_l-robo_l)
    robot_num = heads - animal_num
    print "------"
    print "head",heads,"leg",legs
    print robot_num,animal_num
    return robot_num,animal_num

if __name__ == '__main__':
    calc_roboani_legs(Robot(),Animal(),heads=10,legs=28)

Test

test_roboani.py

import unittest, roboani

class TestRobotAnimal(unittest.TestCase):

    def setUp(self):
        self.robot = roboani.Robot()
        self.animal = roboani.Animal()

    def tearDown(self):
        pass

    def test_legs(self):
        self.assertEqual(self.robot.get_legs(),2,"leg num")
        self.assertEqual(self.animal.get_legs(),4,"leg num")

    
    def test_roboani(self):
        robot, animal = roboani.calc_roboani_legs(
            self.robot,self.animal,
            heads = 10, legs = 28)

        self.assertEqual((robot,animal) ,(6,4), "robot animal calc")

テスト実行

$ python -m unittest test_roboani

結果

.------
head 10 leg 28
6 4
.
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

mocktest

RobotDataBaseConnect

# -*- coding:utf-8 -*-

import unittest
from mock import Mock, patch

class DataBaseConnect(object):
    def __init__(self):
        pass

    def find(self, param):
        print('find ' + param)

class CalculationMovement(object):
    def __init__(self, data):
        self.__dataget = data

    def execute(self):
        return self.__dataget.find('param')

calc = CalculationMovement(DataBaseConnect())
calc.execute()

# ---------------- mock test --------------------------#

class CalculationModelTestCase(unittest.TestCase):
    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_execute_1(self):
        mock_test = Mock()  
        mock_test.find.return_value = 'mock_test'
        test_obj = CalculationMovement(mock_test)
        self.assertEqual('mock_test', test_obj.execute())
        self.assertEqual(mock_test.find.call_count, 1)
        self.assertEqual(list(mock_test.find.call_args_list[0]),
                         [('param',),{}])

    def test_execute_2(self):
        DataBaseConnect.find = Mock(return_value='mock_test')
        mock_test = DataBaseConnect()
        test_obj = CalculationMovement(mock_test)
        self.assertEqual('mock_test', test_obj.execute())

    def test_execute_3(self):
        with patch('__main__.DataBaseConnect') as mock_test:
            mock_test.find.return_value = 'with_mock_test'
            test_obj = CalculationMovement(mock_test)
            self.assertEqual('with_mock_test', test_obj.execute())

unittest.main()

結果

find param
...
----------------------------------------------------------------------
Ran 3 tests in 0.002s

OK

参考:

PythonでMockを使ったユニットテスト - 工作とかプログラミングとか

python - How to unittest that a thread is spawned? - Stack Overflow

サンプルでみる Python の Mock ライブラリ Mox の使い方 | CUBE SUGAR STORAGE

EasyMockでSocketクラスのモックを作る - Yのはてな

Pythonのテストコードでmockを使ってみた | Developers.IO

Pythonのコードをきれいに書くためのTips | TRIVIAL TECHNOLOGIES 4 @ats のイクメン日記

http://momijiame.tumblr.com/post/22379282563/モックオブジェクトフレームワーク-pymox-を使って-python-のテストを書く

標準ライブラリのunittestで例外の発生を確認するテスト - podhmoの日記

unit testing - How do you test that a Python function throws an exception? - Stack Overflow